/* Subroutines used for code generation for eBPF.
   Copyright (C) 2019-2022 Free Software Foundation, Inc.

This file is part of GCC.

GCC 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.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#define IN_TARGET_CODE 1

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "regs.h"
#include "insn-config.h"
#include "insn-attr.h"
#include "recog.h"
#include "output.h"
#include "alias.h"
#include "tree.h"
#include "stringpool.h"
#include "attribs.h"
#include "varasm.h"
#include "stor-layout.h"
#include "calls.h"
#include "function.h"
#include "explow.h"
#include "memmodel.h"
#include "emit-rtl.h"
#include "reload.h"
#include "tm_p.h"
#include "target.h"
#include "target-def.h"
#include "basic-block.h"
#include "expr.h"
#include "optabs.h"
#include "bitmap.h"
#include "df.h"
#include "c-family/c-common.h"
#include "diagnostic.h"
#include "builtins.h"
#include "predict.h"
#include "langhooks.h"
#include "flags.h"

#include "cfg.h" /* needed for struct control_flow_graph used in BB macros */
#include "gimple.h"
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "tree-pass.h"
#include "tree-iterator.h"

#include "context.h"
#include "pass_manager.h"

#include "gimplify.h"
#include "gimplify-me.h"

#include "ctfc.h"
#include "btf.h"

#include "coreout.h"

/* Per-function machine data.  */
struct GTY(()) machine_function
{
  /* Number of bytes saved on the stack for local variables.  */
  int local_vars_size;

  /* Number of bytes saved on the stack for callee-saved
     registers.  */
  int callee_saved_reg_size;
};

/* Handle an attribute requiring a FUNCTION_DECL;
   arguments as in struct attribute_spec.handler.  */

static tree
bpf_handle_fndecl_attribute (tree *node, tree name,
			     tree args,
			     int flags ATTRIBUTE_UNUSED,
			     bool *no_add_attrs)
{
  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute only applies to functions",
	       name);
      *no_add_attrs = true;
    }

  if (is_attribute_p ("kernel_helper", name))
    {
      if (args)
	{
	  tree cst = TREE_VALUE (args);
	  if (TREE_CODE (cst) != INTEGER_CST)
	    {
	      warning (OPT_Wattributes, "%qE attribute requires an integer argument",
		       name);
	      *no_add_attrs = true;
	    }
	}
      else
	{
	  warning (OPT_Wattributes, "%qE requires an argument", name);
	  *no_add_attrs = true;
	}
    }

  return NULL_TREE;
}

/* Handle preserve_access_index attribute, which can be applied to structs,
   unions and classes. Actually adding the attribute to the TYPE_DECL is
   taken care of for us, so just warn for types that aren't supported.  */

static tree
bpf_handle_preserve_access_index_attribute (tree *node, tree name,
					    tree args ATTRIBUTE_UNUSED,
					    int flags ATTRIBUTE_UNUSED,
					    bool *no_add_attrs)
{
  if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
    {
      warning (OPT_Wattributes,
	       "%qE attribute only applies to structure, union and class types",
	       name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Target-specific attributes.  */

static const struct attribute_spec bpf_attribute_table[] =
{
  /* Syntax: { name, min_len, max_len, decl_required, type_required,
	       function_type_required, affects_type_identity, handler,
	       exclude } */

 /* Attribute to mark function prototypes as kernel helpers.  */
 { "kernel_helper", 1, 1, true, false, false, false,
   bpf_handle_fndecl_attribute, NULL },

 /* CO-RE support: attribute to mark that all accesses to the declared
    struct/union/array should be recorded.  */
 { "preserve_access_index", 0, -1, false, true, false, true,
   bpf_handle_preserve_access_index_attribute, NULL },

 /* The last attribute spec is set to be NULL.  */
 { NULL,	0,  0, false, false, false, false, NULL, NULL }
};

#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE bpf_attribute_table

/* Data structures for the eBPF specific built-ins.  */

/* Maximum number of arguments taken by a builtin function, plus
   one.  */
#define BPF_BUILTIN_MAX_ARGS 5

enum bpf_builtins
{
  BPF_BUILTIN_UNUSED = 0,
  /* Built-ins for non-generic loads and stores.  */
  BPF_BUILTIN_LOAD_BYTE,
  BPF_BUILTIN_LOAD_HALF,
  BPF_BUILTIN_LOAD_WORD,

  /* Compile Once - Run Everywhere (CO-RE) support.  */
  BPF_BUILTIN_PRESERVE_ACCESS_INDEX,

  BPF_BUILTIN_MAX,
};

static GTY (()) tree bpf_builtins[(int) BPF_BUILTIN_MAX];


void bpf_register_coreattr_pass (void);

/* Initialize the per-function machine status.  */

static struct machine_function *
bpf_init_machine_status (void)
{
  /* Note this initializes all fields to 0, which is just OK for
     us.  */
  return ggc_cleared_alloc<machine_function> ();
}

/* Override options and do some other initialization.  */

static void
bpf_option_override (void)
{
  /* Set the initializer for the per-function status structure.  */
  init_machine_status = bpf_init_machine_status;

  /* BPF CO-RE support requires BTF debug info generation.  */
  if (TARGET_BPF_CORE && !btf_debuginfo_p ())
    error ("BPF CO-RE requires BTF debugging information, use %<-gbtf%>");

  /* To support the portability needs of BPF CO-RE approach, BTF debug
     information includes the BPF CO-RE relocations.  */
  if (TARGET_BPF_CORE)
    write_symbols |= BTF_WITH_CORE_DEBUG;

  /* Unlike much of the other BTF debug information, the information necessary
     for CO-RE relocations is added to the CTF container by the BPF backend.
     Enabling LTO adds some complications in the generation of the BPF CO-RE
     relocations because if LTO is in effect, the relocations need to be
     generated late in the LTO link phase.  This poses a new challenge for the
     compiler to now provide means to combine the early BTF and late BTF CO-RE
     debug info, similar to DWARF debug info.  BTF/CO-RE debug info is not
     amenable to such a split generation and a later merging.

     In any case, in absence of linker support for BTF sections at this time,
     it is acceptable to simply disallow LTO for BPF CO-RE compilations.  */

  if (flag_lto && TARGET_BPF_CORE)
    sorry ("BPF CO-RE does not support LTO");

  /* -gbtf implies -mcore when using the BPF backend, unless -mno-co-re
     is specified.  */
  if (btf_debuginfo_p () && !(target_flags_explicit & MASK_BPF_CORE))
    {
      target_flags |= MASK_BPF_CORE;
      write_symbols |= BTF_WITH_CORE_DEBUG;
    }

  /* Determine available features from ISA setting (-mcpu=).  */
  if (bpf_has_jmpext == -1)
    bpf_has_jmpext = (bpf_isa >= ISA_V2);

  if (bpf_has_alu32 == -1)
    bpf_has_alu32 = (bpf_isa >= ISA_V3);

  if (bpf_has_jmp32 == -1)
    bpf_has_jmp32 = (bpf_isa >= ISA_V3);

}

#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE bpf_option_override

/* Implement TARGET_ASM_INIT_SECTIONS.  */

static void
bpf_asm_init_sections (void)
{
  if (TARGET_BPF_CORE)
    btf_ext_init ();
}

#undef TARGET_ASM_INIT_SECTIONS
#define TARGET_ASM_INIT_SECTIONS bpf_asm_init_sections

/* Implement TARGET_ASM_FILE_END.  */

static void
bpf_file_end (void)
{
  if (TARGET_BPF_CORE)
    btf_ext_output ();
}

#undef TARGET_ASM_FILE_END
#define TARGET_ASM_FILE_END bpf_file_end

/* Define target-specific CPP macros.  This function in used in the
   definition of TARGET_CPU_CPP_BUILTINS in bpf.h */

#define builtin_define(TXT) cpp_define (pfile, TXT)

void
bpf_target_macros (cpp_reader *pfile)
{
  builtin_define ("__BPF__");

  if (TARGET_BIG_ENDIAN)
    builtin_define ("__BPF_BIG_ENDIAN__");
  else
    builtin_define ("__BPF_LITTLE_ENDIAN__");

  /* Define BPF_KERNEL_VERSION_CODE */
  {
    const char *version_code;
    char *kernel_version_code;

    switch (bpf_kernel)
      {
      case LINUX_V4_0: version_code = "0x40000"; break;
      case LINUX_V4_1: version_code = "0x40100"; break;
      case LINUX_V4_2: version_code = "0x40200"; break;
      case LINUX_V4_3: version_code = "0x40300"; break;
      case LINUX_V4_4: version_code = "0x40400"; break;
      case LINUX_V4_5: version_code = "0x40500"; break;
      case LINUX_V4_6: version_code = "0x40600"; break;
      case LINUX_V4_7: version_code = "0x40700"; break;
      case LINUX_V4_8: version_code = "0x40800"; break;
      case LINUX_V4_9: version_code = "0x40900"; break;
      case LINUX_V4_10: version_code = "0x40a00"; break;
      case LINUX_V4_11: version_code = "0x40b00"; break;
      case LINUX_V4_12: version_code = "0x40c00"; break;
      case LINUX_V4_13: version_code = "0x40d00"; break;
      case LINUX_V4_14: version_code = "0x40e00"; break;
      case LINUX_V4_15: version_code = "0x40f00"; break;
      case LINUX_V4_16: version_code = "0x41000"; break;
      case LINUX_V4_17: version_code = "0x42000"; break;
      case LINUX_V4_18: version_code = "0x43000"; break;
      case LINUX_V4_19: version_code = "0x44000"; break;
      case LINUX_V4_20: version_code = "0x45000"; break;
      case LINUX_V5_0: version_code = "0x50000"; break;
      case LINUX_V5_1: version_code = "0x50100"; break;
      case LINUX_V5_2: version_code = "0x50200"; break;
      default:
	gcc_unreachable ();
      }

    kernel_version_code = ACONCAT (("__BPF_KERNEL_VERSION_CODE__=",
				    version_code, NULL));
    builtin_define (kernel_version_code);
  }
}

/* Return an RTX representing the place where a function returns or
   receives a value of data type RET_TYPE, a tree node representing a
   data type.  */

static rtx
bpf_function_value (const_tree ret_type,
		    const_tree fntype_or_decl,
		    bool outgoing ATTRIBUTE_UNUSED)
{
  enum machine_mode mode;
  int unsignedp;

  mode = TYPE_MODE (ret_type);
  if (INTEGRAL_TYPE_P (ret_type))
    mode = promote_function_mode (ret_type, mode, &unsignedp,
				  fntype_or_decl, 1);

  return gen_rtx_REG (mode, BPF_R0);
}

#undef TARGET_FUNCTION_VALUE
#define TARGET_FUNCTION_VALUE bpf_function_value

/* Return true if REGNO is the number of a hard register in which the
   values of called function may come back.  */

static bool
bpf_function_value_regno_p (const unsigned int regno)
{
  return (regno == BPF_R0);
}

#undef TARGET_FUNCTION_VALUE_REGNO_P
#define TARGET_FUNCTION_VALUE_REGNO_P bpf_function_value_regno_p

/* Compute the size of the function's stack frame, including the local
   area and the register-save area.  */

static void
bpf_compute_frame_layout (void)
{
  int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
  int padding_locals, regno;

  /* Set the space used in the stack by local variables.  This is
     rounded up to respect the minimum stack alignment.  */
  cfun->machine->local_vars_size = get_frame_size ();

  padding_locals = cfun->machine->local_vars_size % stack_alignment;
  if (padding_locals)
    padding_locals = stack_alignment - padding_locals;

  cfun->machine->local_vars_size += padding_locals;

  if (TARGET_XBPF)
    {
      /* Set the space used in the stack by callee-saved used
	 registers in the current function.  There is no need to round
	 up, since the registers are all 8 bytes wide.  */
      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
	if ((df_regs_ever_live_p (regno)
	     && !call_used_or_fixed_reg_p (regno))
	    || (cfun->calls_alloca
		&& regno == STACK_POINTER_REGNUM))
	  cfun->machine->callee_saved_reg_size += 8;
    }

  /* Check that the total size of the frame doesn't exceed the limit
     imposed by eBPF.  */
  if ((cfun->machine->local_vars_size
       + cfun->machine->callee_saved_reg_size) > bpf_frame_limit)
    {
      static int stack_limit_exceeded = 0;

      if (!stack_limit_exceeded)
	error ("eBPF stack limit exceeded");
      stack_limit_exceeded = 1;
    }
}

#undef TARGET_COMPUTE_FRAME_LAYOUT
#define TARGET_COMPUTE_FRAME_LAYOUT bpf_compute_frame_layout

/* Expand to the instructions in a function prologue.  This function
   is called when expanding the 'prologue' pattern in bpf.md.  */

void
bpf_expand_prologue (void)
{
  rtx insn;
  HOST_WIDE_INT size;

  size = (cfun->machine->local_vars_size
	  + cfun->machine->callee_saved_reg_size);

  /* The BPF "hardware" provides a fresh new set of registers for each
     called function, some of which are initialized to the values of
     the arguments passed in the first five registers.  In doing so,
     it saves the values of the registers of the caller, and restored
     them upon returning.  Therefore, there is no need to save the
     callee-saved registers here.  What is worse, the kernel
     implementation refuses to run programs in which registers are
     referred before being initialized.  */
  if (TARGET_XBPF)
    {
      int regno;
      int fp_offset = -cfun->machine->local_vars_size;

      /* Save callee-saved hard registes.  The register-save-area
	 starts right after the local variables.  */
      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
	{
	  if ((df_regs_ever_live_p (regno)
	       && !call_used_or_fixed_reg_p (regno))
	      || (cfun->calls_alloca
		  && regno == STACK_POINTER_REGNUM))
	    {
	      rtx mem;

	      if (!IN_RANGE (fp_offset, -1 - 0x7fff, 0x7fff))
		/* This has been already reported as an error in
		   bpf_compute_frame_layout. */
		break;
	      else
		{
		  mem = gen_frame_mem (DImode,
				       plus_constant (DImode,
						      hard_frame_pointer_rtx,
						      fp_offset - 8));
		  insn = emit_move_insn (mem, gen_rtx_REG (DImode, regno));
		  fp_offset -= 8;
		}
	    }
	}
    }

  /* Set the stack pointer, if the function allocates space
     dynamically.  Note that the value of %sp should be directly
     derived from %fp, for the kernel verifier to track it as a stack
     accessor.  */
  if (cfun->calls_alloca)
    {
      insn = emit_move_insn (stack_pointer_rtx,
			     hard_frame_pointer_rtx);

      if (size > 0)
	{
	  insn = emit_insn (gen_rtx_SET (stack_pointer_rtx,
					 gen_rtx_PLUS (Pmode,
						       stack_pointer_rtx,
						       GEN_INT (-size))));
	}
    }
}

/* Expand to the instructions in a function epilogue.  This function
   is called when expanding the 'epilogue' pattern in bpf.md.  */

void
bpf_expand_epilogue (void)
{
  /* See note in bpf_expand_prologue for an explanation on why we are
     not restoring callee-saved registers in BPF.  */
  if (TARGET_XBPF)
    {
      rtx insn;
      int regno;
      int fp_offset = -cfun->machine->local_vars_size;

      /* Restore callee-saved hard registes from the stack.  */
      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
	{
	  if ((df_regs_ever_live_p (regno)
	       && !call_used_or_fixed_reg_p (regno))
	      || (cfun->calls_alloca
		  && regno == STACK_POINTER_REGNUM))
	    {
	      rtx mem;

	      if (!IN_RANGE (fp_offset, -1 - 0x7fff, 0x7fff))
		/* This has been already reported as an error in
		   bpf_compute_frame_layout. */
		break;
	      else
		{
		  mem = gen_frame_mem (DImode,
				       plus_constant (DImode,
						      hard_frame_pointer_rtx,
						      fp_offset - 8));
		  insn = emit_move_insn (gen_rtx_REG (DImode, regno), mem);
		  fp_offset -= 8;
		}
	    }
	}
    }

  emit_jump_insn (gen_exit ());
}

/* Expand to the instructions for a conditional branch. This function
   is called when expanding the 'cbranch<mode>4' pattern in bpf.md.  */

void
bpf_expand_cbranch (machine_mode mode, rtx *operands)
{
  /* If all jump instructions are available, nothing special to do here.  */
  if (bpf_has_jmpext)
    return;

  enum rtx_code code = GET_CODE (operands[0]);

  /* Without the conditional branch instructions jslt, jsle, jlt, jle, we need
     to convert conditional branches that would use them to an available
     operation instead by reversing the comparison.  */
  if ((code == LT || code == LE || code == LTU || code == LEU))
    {
      /* Reverse the condition.  */
      PUT_CODE (operands[0], reverse_condition (code));

      /* Swap the operands, and ensure that the first is a register.  */
      if (!register_operand (operands[2], mode))
	operands[2] = force_reg (mode, operands[2]);

      rtx tmp = operands[1];
      operands[1] = operands[2];
      operands[2] = tmp;
    }
}

/* Return the initial difference between the specified pair of
   registers.  The registers that can figure in FROM, and TO, are
   specified by ELIMINABLE_REGS in bpf.h.

   This function is used in the definition of
   INITIAL_ELIMINATION_OFFSET in bpf.h  */

HOST_WIDE_INT
bpf_initial_elimination_offset (int from, int to)
{
  HOST_WIDE_INT ret;

  if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
    ret = (cfun->machine->local_vars_size
	   + cfun->machine->callee_saved_reg_size);
  else if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
    ret = 0;
  else
    gcc_unreachable ();

  return ret;
}

/* Return the number of consecutive hard registers, starting at
   register number REGNO, required to hold a value of mode MODE.  */

static unsigned int
bpf_hard_regno_nregs (unsigned int regno ATTRIBUTE_UNUSED,
		      enum machine_mode mode)
{
  return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
}

#undef TARGET_HARD_REGNO_NREGS
#define TARGET_HARD_REGNO_NREGS bpf_hard_regno_nregs

/* Return true if it is permissible to store a value of mode MODE in
   hard register number REGNO, or in several registers starting with
   that one.  */

static bool
bpf_hard_regno_mode_ok (unsigned int regno ATTRIBUTE_UNUSED,
			enum machine_mode mode)
{
  switch (mode)
    {
    case E_SImode:
    case E_DImode:
    case E_HImode:
    case E_QImode:
    case E_TImode:
    case E_SFmode:
    case E_DFmode:
      return true;
    default:
      return false;
    }
}

#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK bpf_hard_regno_mode_ok

/* Return true if a function must have and use a frame pointer.  */

static bool
bpf_frame_pointer_required (void)
{
  /* We do not have a stack pointer, so we absolutely depend on the
     frame-pointer in order to access the stack... and fishes walk and
     pigs fly glglgl */
  return true;
}

#undef TARGET_FRAME_POINTER_REQUIRED
#define TARGET_FRAME_POINTER_REQUIRED bpf_frame_pointer_required

/* Return `true' if the given RTX X is a valid base for an indirect
   memory access.  STRICT has the same meaning than in
   bpf_legitimate_address_p.  */

static inline bool
bpf_address_base_p (rtx x, bool strict)
{
  return (GET_CODE (x) == REG
	  && (REGNO (x) < 11
	      || (!strict && REGNO (x) >= FIRST_PSEUDO_REGISTER)));
}

/* Return true if X (a RTX) is a legitimate memory address on the
   target machine for a memory operand of mode MODE.  */

static bool
bpf_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
			  rtx x,
			  bool strict)
{
  switch (GET_CODE (x))
    {
    case REG:
      return bpf_address_base_p (x, strict);

    case PLUS:
      {
	/* Accept (PLUS ADDR_BASE CONST_INT), provided CONST_INT fits
	   in a signed 16-bit.

	   Note that LABEL_REF and SYMBOL_REF are not allowed in
	   REG+IMM addresses, because it is almost certain they will
	   overload the offset field.  */

	rtx x0 = XEXP (x, 0);
	rtx x1 = XEXP (x, 1);

	if (bpf_address_base_p (x0, strict) && GET_CODE (x1) == CONST_INT)
	  return IN_RANGE (INTVAL (x1), -1 - 0x7fff, 0x7fff);

	break;
      }
    default:
      break;
    }

  return false;
}

#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P bpf_legitimate_address_p

/* Describe the relative costs of RTL expressions.  Return true when
   all subexpressions of X have been processed, and false when
   `rtx_cost' should recurse.  */

static bool
bpf_rtx_costs (rtx x ATTRIBUTE_UNUSED,
	       enum machine_mode mode ATTRIBUTE_UNUSED,
	       int outer_code ATTRIBUTE_UNUSED,
	       int opno ATTRIBUTE_UNUSED,
               int *total ATTRIBUTE_UNUSED,
	       bool speed ATTRIBUTE_UNUSED)
{
  /* To be written.  */
  return false;
}

#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS bpf_rtx_costs

/* Return true if an argument at the position indicated by CUM should
   be passed by reference.  If the hook returns true, a copy of that
   argument is made in memory and a pointer to the argument is passed
   instead of the argument itself.  */

static bool
bpf_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
		       const function_arg_info &arg)
{
  unsigned num_bytes = arg.type_size_in_bytes ();

  /* Pass aggregates and values bigger than 5 words by reference.
     Everything else is passed by copy.  */
  return (arg.aggregate_type_p () || (num_bytes > 8*5));
}

#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE bpf_pass_by_reference

/* Return a RTX indicating whether a function argument is passed in a
   register and if so, which register.  */

static rtx
bpf_function_arg (cumulative_args_t ca, const function_arg_info &arg)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (ca);

  if (*cum < 5)
    return gen_rtx_REG (arg.mode, *cum + 1);
  else
    /* An error will be emitted for this in
       bpf_function_arg_advance.  */
    return NULL_RTX;
}

#undef TARGET_FUNCTION_ARG
#define TARGET_FUNCTION_ARG bpf_function_arg

/* Update the summarizer variable pointed by CA to advance past an
   argument in the argument list.  */

static void
bpf_function_arg_advance (cumulative_args_t ca,
			  const function_arg_info &arg)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
  unsigned num_bytes = arg.type_size_in_bytes ();
  unsigned num_words = CEIL (num_bytes, UNITS_PER_WORD);

  if (*cum <= 5 && *cum + num_words > 5)
    error ("too many function arguments for eBPF");

  *cum += num_words;
}

#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE bpf_function_arg_advance

/* Output the assembly code for a constructor.  Since eBPF doesn't
   support indirect calls, constructors are not supported.  */

static void
bpf_output_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
  tree decl = SYMBOL_REF_DECL (symbol);

  if (decl)
    sorry_at (DECL_SOURCE_LOCATION (decl),
	      "no constructors");
  else
    sorry ("no constructors");
}

#undef TARGET_ASM_CONSTRUCTOR
#define TARGET_ASM_CONSTRUCTOR bpf_output_constructor

/* Output the assembly code for a destructor.  Since eBPF doesn't
   support indirect calls, destructors are not supported.  */

static void
bpf_output_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
  tree decl = SYMBOL_REF_DECL (symbol);

  if (decl)
    sorry_at (DECL_SOURCE_LOCATION (decl),
	      "no destructors");
  else
    sorry ("no destructors");
}

#undef TARGET_ASM_DESTRUCTOR
#define TARGET_ASM_DESTRUCTOR bpf_output_destructor

/* Return the appropriate instruction to CALL to a function.  TARGET
   is an RTX denoting the address of the called function.

   The main purposes of this function are:
   - To reject indirect CALL instructions, which are not supported by
     eBPF.
   - To recognize calls to kernel helper functions and emit the
     corresponding CALL N instruction.

   This function is called from the expansion of the 'call' pattern in
   bpf.md.  */

const char *
bpf_output_call (rtx target)
{
  rtx xops[1];

  switch (GET_CODE (target))
    {
    case CONST_INT:
      output_asm_insn ("call\t%0", &target);
      break;
    case SYMBOL_REF:
      {
	tree decl = SYMBOL_REF_DECL (target);
	tree attr;

	if (decl
	    && (attr = lookup_attribute ("kernel_helper",
					 DECL_ATTRIBUTES (decl))))
	  {
	    tree attr_args = TREE_VALUE (attr);

	    xops[0] = GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (attr_args)));
	    output_asm_insn ("call\t%0", xops);
	  }
	else
	  output_asm_insn ("call\t%0", &target);

	break;
      }
    default:
      if (TARGET_XBPF)
	output_asm_insn ("call\t%0", &target);
      else
	{
	  error ("indirect call in function, which are not supported by eBPF");
	  output_asm_insn ("call 0", NULL);
	}
      break;
    }

  return "";
}

/* Print an instruction operand.  This function is called in the macro
   PRINT_OPERAND defined in bpf.h */

void
bpf_print_operand (FILE *file, rtx op, int code ATTRIBUTE_UNUSED)
{
  switch (GET_CODE (op))
    {
    case REG:
      fprintf (file, "%s", reg_names[REGNO (op)]);
      break;
    case MEM:
      output_address (GET_MODE (op), XEXP (op, 0));
      break;
    case CONST_DOUBLE:
      if (CONST_DOUBLE_HIGH (op))
	fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
		 CONST_DOUBLE_HIGH (op), CONST_DOUBLE_LOW (op));
      else if (CONST_DOUBLE_LOW (op) < 0)
	fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (op));
      else
	fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (op));
      break;
    default:
      output_addr_const (file, op);
    }
}

/* Print an operand which is an address.  This function should handle
   any legit address, as accepted by bpf_legitimate_address_p, and
   also addresses that are valid in CALL instructions.

   This function is called in the PRINT_OPERAND_ADDRESS macro defined
   in bpf.h */

void
bpf_print_operand_address (FILE *file, rtx addr)
{
  switch (GET_CODE (addr))
    {
    case REG:
      fprintf (file, "[%s+0]", reg_names[REGNO (addr)]);
      break;
    case PLUS:
      {
	rtx op0 = XEXP (addr, 0);
	rtx op1 = XEXP (addr, 1);

	if (GET_CODE (op0) == REG && GET_CODE (op1) == CONST_INT)
	  {
	    fprintf (file, "[%s+", reg_names[REGNO (op0)]);
	    output_addr_const (file, op1);
	    fputs ("]", file);
	  }
	else
	  fatal_insn ("invalid address in operand", addr);
	break;
      }
    case MEM:
      /* Fallthrough.  */
    case LABEL_REF:
      /* Fallthrough.  */
      fatal_insn ("unsupported operand", addr);
      break;
    default:
      output_addr_const (file, addr);
      break;
    }
}

/* Add a BPF builtin function with NAME, CODE and TYPE.  Return
   the function decl or NULL_TREE if the builtin was not added.  */

static tree
def_builtin (const char *name, enum bpf_builtins code, tree type)
{
  tree t
    = add_builtin_function (name, type, code, BUILT_IN_MD, NULL, NULL_TREE);

  bpf_builtins[code] = t;
  return t;
}

/* Define machine-specific built-in functions.  */

static void
bpf_init_builtins (void)
{
  tree ullt = long_long_unsigned_type_node;

  /* Built-ins for BPF_LD_ABS and BPF_LD_IND instructions.  */

  def_builtin ("__builtin_bpf_load_byte", BPF_BUILTIN_LOAD_BYTE,
	       build_function_type_list (ullt, ullt, 0));
  def_builtin ("__builtin_bpf_load_half", BPF_BUILTIN_LOAD_HALF,
	       build_function_type_list (ullt, ullt, 0));
  def_builtin ("__builtin_bpf_load_word", BPF_BUILTIN_LOAD_WORD,
	       build_function_type_list (ullt, ullt, 0));
  def_builtin ("__builtin_preserve_access_index",
	       BPF_BUILTIN_PRESERVE_ACCESS_INDEX,
	       build_function_type_list (ptr_type_node, ptr_type_node, 0));
}

#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS bpf_init_builtins

static tree bpf_core_compute (tree, vec<unsigned int> *);
static int bpf_core_get_index (const tree);
static bool is_attr_preserve_access (tree);

/* Expand a call to a BPF-specific built-in function that was set up
   with bpf_init_builtins.  */

static rtx
bpf_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
		    rtx subtarget ATTRIBUTE_UNUSED,
		    machine_mode mode ATTRIBUTE_UNUSED,
		    int ignore ATTRIBUTE_UNUSED)
{
  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
  int code = DECL_MD_FUNCTION_CODE (fndecl);

  if (code == BPF_BUILTIN_LOAD_BYTE
      || code == BPF_BUILTIN_LOAD_HALF
      || code == BPF_BUILTIN_LOAD_WORD)
    {
      /* Expand an indirect load from the sk_buff in the context.
	 There is just one argument to the builtin, which is the
	 offset.

	 We try first to expand a ldabs* instruction.  In case this
	 fails, we try a ldind* instruction.  */

      enum insn_code abs_icode
	= (code == BPF_BUILTIN_LOAD_BYTE ? CODE_FOR_ldabsb
	   : code == BPF_BUILTIN_LOAD_HALF ? CODE_FOR_ldabsh
	   : CODE_FOR_ldabsw);

      enum insn_code ind_icode
	= (code == BPF_BUILTIN_LOAD_BYTE ? CODE_FOR_ldindb
	   : code == BPF_BUILTIN_LOAD_HALF ? CODE_FOR_ldindh
	   : CODE_FOR_ldindw);

      tree offset_arg = CALL_EXPR_ARG (exp, 0);
      struct expand_operand ops[2];

      create_input_operand (&ops[0], expand_normal (offset_arg),
			    TYPE_MODE (TREE_TYPE (offset_arg)));
      create_input_operand (&ops[1], const0_rtx, SImode);

      if (!maybe_expand_insn (abs_icode, 2, ops)
	  && !maybe_expand_insn (ind_icode, 2, ops))
	{
	  error ("invalid argument to built-in function");
	  return gen_rtx_REG (ops[0].mode, BPF_R0);
	}

      /* The result of the load is in R0.  */
      return gen_rtx_REG (ops[0].mode, BPF_R0);
    }
  else if (code == -1)
    {
      /* A resolved overloaded builtin, e.g. __bpf_preserve_access_index_si */
      tree arg = CALL_EXPR_ARG (exp, 0);

      if (arg == NULL_TREE)
	return NULL_RTX;

      auto_vec<unsigned int, 16> accessors;
      tree container;

      if (TREE_CODE (arg) == SSA_NAME)
	{
	  gimple *def_stmt = SSA_NAME_DEF_STMT (arg);

	  if (is_gimple_assign (def_stmt))
	    arg = gimple_assign_rhs1 (def_stmt);
	  else
	    return expand_normal (arg);
	}

      /* Avoid double-recording information if the argument is an access to
	 a struct/union marked __attribute__((preserve_access_index)). This
	 Will be handled by the attribute handling pass.  */
      if (is_attr_preserve_access (arg))
	return expand_normal (arg);

      container = bpf_core_compute (arg, &accessors);

      /* Any valid use of the builtin must have at least one access. Otherwise,
	 there is nothing to record and nothing to do. This is primarily a
	 guard against optimizations leading to unexpected expressions in the
	 argument of the builtin. For example, if the builtin is used to read
	 a field of a structure which can be statically determined to hold a
	 constant value, the argument to the builtin will be optimized to that
	 constant. This is OK, and means the builtin call is superfluous.
	 e.g.
	   struct S foo;
	   foo.a = 5;
	   int x = __preserve_access_index (foo.a);
	   ... do stuff with x
	 'foo.a' in the builtin argument will be optimized to '5' with -01+.
	 This sequence does not warrant recording a CO-RE relocation.  */

      if (accessors.length () < 1)
	return expand_normal (arg);

      accessors.reverse ();

      container = TREE_TYPE (container);

      rtx_code_label *label = gen_label_rtx ();
      LABEL_PRESERVE_P (label) = 1;
      emit_label (label);

      /* Determine what output section this relocation will apply to.
	 If this function is associated with a section, use that. Otherwise,
	 fall back on '.text'.  */
      const char * section_name;
      if (current_function_decl && DECL_SECTION_NAME (current_function_decl))
	section_name = DECL_SECTION_NAME (current_function_decl);
      else
	section_name = ".text";

      /* Add the CO-RE relocation information to the BTF container.  */
      bpf_core_reloc_add (container, section_name, &accessors, label);

      return expand_normal (arg);
    }
  gcc_unreachable ();
}

#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN bpf_expand_builtin

/* Initialize target-specific function library calls.  This is mainly
   used to call library-provided soft-fp operations, since eBPF
   doesn't support floating-point in "hardware".  */

static void
bpf_init_libfuncs (void)
{
  set_conv_libfunc (sext_optab, DFmode, SFmode,
		    "__bpf_extendsfdf2");
  set_conv_libfunc (trunc_optab, SFmode, DFmode,
		    "__bpf_truncdfsf2");
  set_conv_libfunc (sfix_optab, SImode, DFmode,
		    "__bpf_fix_truncdfsi");
  set_conv_libfunc (sfloat_optab, DFmode, SImode,
		    "__bpf_floatsidf");
  set_conv_libfunc (ufloat_optab, DFmode, SImode,
		    "__bpf_floatunsidf");
}

#undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS bpf_init_libfuncs

/* Define the mechanism that will be used for describing frame unwind
   information to the debugger.  In eBPF it is not possible to unwind
   frames.  */

static enum unwind_info_type
bpf_debug_unwind_info ()
{
  return UI_NONE;
}

#undef TARGET_DEBUG_UNWIND_INFO
#define TARGET_DEBUG_UNWIND_INFO bpf_debug_unwind_info

/* Output assembly directives to assemble data of various sized and
   alignments.  */

#undef TARGET_ASM_BYTE_OP
#define TARGET_ASM_BYTE_OP "\t.byte\t"
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
#undef TARGET_ASM_ALIGNED_SI_OP
#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
#undef TARGET_ASM_ALIGNED_DI_OP
#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"


/* BPF Compile Once - Run Everywhere (CO-RE) support routines.

   BPF CO-RE is supported in two forms:
   - A target builtin, __builtin_preserve_access_index

     This builtin accepts a single argument. Any access to an aggregate data
     structure (struct, union or array) within the argument will be recorded by
     the CO-RE machinery, resulting in a relocation record being placed in the
     .BTF.ext section of the output.

     It is implemented in bpf_resolve_overloaded_builtin () and
     bpf_expand_builtin (), using the supporting routines below.

   - An attribute, __attribute__((preserve_access_index))

     This attribute can be applied to struct and union types. Any access to a
     type with this attribute will be recorded by the CO-RE machinery.

     The pass pass_bpf_core_attr, below, implements support for
     this attribute.  */

/* Traverse the subtree under NODE, which is expected to be some form of
   aggregate access the CO-RE machinery cares about (like a read of a member of
   a struct or union), collecting access indices for the components and storing
   them in the vector referenced by ACCESSORS.

   Return the ultimate (top-level) container of the aggregate access. In general,
   this will be a VAR_DECL or some kind of REF.

   Note that the accessors are computed *in reverse order* of how the BPF
   CO-RE machinery defines them. The vector needs to be reversed (or simply
   output in reverse order) for the .BTF.ext relocation information.  */

static tree
bpf_core_compute (tree node, vec<unsigned int> *accessors)
{

  if (TREE_CODE (node) == ADDR_EXPR)
    node = TREE_OPERAND (node, 0);

  else if (TREE_CODE (node) == INDIRECT_REF
	   || TREE_CODE (node) == POINTER_PLUS_EXPR)
    {
      accessors->safe_push (0);
      return TREE_OPERAND (node, 0);
    }

  while (1)
    {
      switch (TREE_CODE (node))
	{
	case COMPONENT_REF:
	  accessors->safe_push (bpf_core_get_index (TREE_OPERAND (node, 1)));
	  break;

	case ARRAY_REF:
	case ARRAY_RANGE_REF:
	  accessors->safe_push (bpf_core_get_index (node));
	  break;

	case MEM_REF:
	  accessors->safe_push (bpf_core_get_index (node));
	  if (TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR)
	    node = TREE_OPERAND (TREE_OPERAND (node, 0), 0);
	  goto done;

	default:
	  goto done;
	}
      node = TREE_OPERAND (node, 0);
    }
 done:
  return node;

}

/* Compute the index of the NODE in its immediate container.
   NODE should be a FIELD_DECL (i.e. of struct or union), or an ARRAY_REF. */
static int
bpf_core_get_index (const tree node)
{
  enum tree_code code = TREE_CODE (node);

  if (code == FIELD_DECL)
    {
      /* Lookup the index from the BTF information.  Some struct/union members
	 may not be emitted in BTF; only the BTF container has enough
	 information to compute the correct index.  */
      int idx = bpf_core_get_sou_member_index (ctf_get_tu_ctfc (), node);
      if (idx >= 0)
	return idx;
    }

  else if (code == ARRAY_REF || code == ARRAY_RANGE_REF || code == MEM_REF)
    {
      /* For array accesses, the index is operand 1.  */
      tree index = TREE_OPERAND (node, 1);

      /* If the indexing operand is a constant, extracting is trivial.  */
      if (TREE_CODE (index) == INTEGER_CST && tree_fits_shwi_p (index))
	return tree_to_shwi (index);
    }

  return -1;
}

/* Synthesize a new builtin function declaration with signature TYPE.
   Used by bpf_resolve_overloaded_builtin to resolve calls to
   __builtin_preserve_access_index.  */

static tree
bpf_core_newdecl (tree type)
{
  tree rettype = build_function_type_list (type, type, NULL);
  char name[80];
  int len = snprintf (name, sizeof (name), "%s", "__builtin_pai_");

  static unsigned long cnt = 0;
  len = snprintf (name + len, sizeof (name) - len, "%lu", cnt++);

  return add_builtin_function_ext_scope (name, rettype, -1, BUILT_IN_MD, NULL,
					 NULL_TREE);
}

/* Return whether EXPR could access some aggregate data structure that
   BPF CO-RE support needs to know about.  */

static int
bpf_core_is_maybe_aggregate_access (tree expr)
{
  enum tree_code code = TREE_CODE (expr);
  if (code == COMPONENT_REF || code == ARRAY_REF)
    return 1;

  if (code == ADDR_EXPR)
      return bpf_core_is_maybe_aggregate_access (TREE_OPERAND (expr, 0));

  return 0;
}

/* Callback function used with walk_tree from bpf_resolve_overloaded_builtin.  */

static tree
bpf_core_walk (tree *tp, int *walk_subtrees, void *data)
{
  location_t loc = *((location_t *) data);

  /* If this is a type, don't do anything. */
  if (TYPE_P (*tp))
    {
      *walk_subtrees = 0;
      return NULL_TREE;
    }

  if (bpf_core_is_maybe_aggregate_access (*tp))
    {
      tree newdecl = bpf_core_newdecl (TREE_TYPE (*tp));
      tree newcall = build_call_expr_loc (loc, newdecl, 1, *tp);
      *tp = newcall;
      *walk_subtrees = 0;
    }

  return NULL_TREE;
}


/* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN (see gccint manual section
   Target Macros::Misc.).
   We use this for the __builtin_preserve_access_index builtin for CO-RE
   support.

   FNDECL is the declaration of the builtin, and ARGLIST is the list of
   arguments passed to it, and is really a vec<tree,_> *.

   In this case, the 'operation' implemented by the builtin is a no-op;
   the builtin is just a marker. So, the result is simply the argument.  */

static tree
bpf_resolve_overloaded_builtin (location_t loc, tree fndecl, void *arglist)
{
  if (DECL_MD_FUNCTION_CODE (fndecl) != BPF_BUILTIN_PRESERVE_ACCESS_INDEX)
    return NULL_TREE;

  /* We only expect one argument, but it may be an arbitrarily-complicated
     statement-expression. */
  vec<tree, va_gc> *params = static_cast<vec<tree, va_gc> *> (arglist);
  unsigned n_params = params ? params->length() : 0;

  if (n_params != 1)
    {
      error_at (loc, "expected exactly 1 argument");
      return NULL_TREE;
    }

  tree param = (*params)[0];

  /* If not generating BPF_CORE information, the builtin does nothing.  */
  if (!TARGET_BPF_CORE)
    return param;

  /* Do remove_c_maybe_const_expr for the arg.
     TODO: WHY do we have to do this here? Why doesn't c-typeck take care
     of it before or after this hook? */
  if (TREE_CODE (param) == C_MAYBE_CONST_EXPR)
    param = C_MAYBE_CONST_EXPR_EXPR (param);

  /* Construct a new function declaration with the correct type, and return
     a call to it.

     Calls with statement-expressions, for example:
     _(({ foo->a = 1; foo->u[2].b = 2; }))
     require special handling.

     We rearrange this into a new block scope in which each statement
     becomes a unique builtin call:
     {
       _ ({ foo->a = 1;});
       _ ({ foo->u[2].b = 2;});
     }

     This ensures that all the relevant information remains within the
     expression trees the builtin finally gets.  */

  walk_tree (&param, bpf_core_walk, (void *) &loc, NULL);

  return param;
}

#undef TARGET_RESOLVE_OVERLOADED_BUILTIN
#define TARGET_RESOLVE_OVERLOADED_BUILTIN bpf_resolve_overloaded_builtin


/* Handling for __attribute__((preserve_access_index)) for BPF CO-RE support.

   This attribute marks a structure/union/array type as "preseve", so that
   every access to that type should be recorded and replayed by the BPF loader;
   this is just the same functionality as __builtin_preserve_access_index,
   but in the form of an attribute for an entire aggregate type.

   Note also that nested structs behave as though they all have the attribute.
   For example:
     struct X { int a; };
     struct Y { struct X bar} __attribute__((preserve_access_index));
     struct Y foo;
     foo.bar.a;
   will record access all the way to 'a', even though struct X does not have
   the preserve_access_index attribute.

   This is to follow LLVM behavior.

   This pass finds all accesses to objects of types marked with the attribute,
   and wraps them in the same "low-level" builtins used by the builtin version.
   All logic afterwards is therefore identical to the builtin version of
   preserve_access_index.  */

/* True iff tree T accesses any member of a struct/union/class which is marked
   with the PRESERVE_ACCESS_INDEX attribute.  */

static bool
is_attr_preserve_access (tree t)
{
  if (t == NULL_TREE)
    return false;

  poly_int64 bitsize, bitpos;
  tree var_off;
  machine_mode mode;
  int sign, reverse, vol;

  tree base = get_inner_reference (t, &bitsize, &bitpos, &var_off, &mode,
				   &sign, &reverse, &vol);

  if (TREE_CODE (base) == MEM_REF)
    {
      return lookup_attribute ("preserve_access_index",
			       TYPE_ATTRIBUTES (TREE_TYPE (base)));
    }

  if (TREE_CODE (t) == COMPONENT_REF)
    {
      /* preserve_access_index propegates into nested structures,
	 so check whether this is a component of another component
	 which in turn is part of such a struct.  */

      const tree op = TREE_OPERAND (t, 0);

      if (TREE_CODE (op) == COMPONENT_REF)
	return is_attr_preserve_access (op);

      const tree container = DECL_CONTEXT (TREE_OPERAND (t, 1));

      return lookup_attribute ("preserve_access_index",
			       TYPE_ATTRIBUTES (container));
    }

  else if (TREE_CODE (t) == ADDR_EXPR)
    return is_attr_preserve_access (TREE_OPERAND (t, 0));

  return false;
}

/* The body of pass_bpf_core_attr. Scan RTL for accesses to structs/unions
   marked with __attribute__((preserve_access_index)) and generate a CO-RE
   relocation for any such access.  */

static void
handle_attr_preserve (function *fn)
{
  basic_block bb;
  rtx_insn *insn;
  rtx_code_label *label;
  FOR_EACH_BB_FN (bb, fn)
    {
      FOR_BB_INSNS (bb, insn)
	{
	  if (!NONJUMP_INSN_P (insn))
	    continue;
	  rtx pat = PATTERN (insn);
	  if (GET_CODE (pat) != SET)
	    continue;

	  start_sequence();

	  for (int i = 0; i < 2; i++)
	    {
	      rtx mem = XEXP (pat, i);
	      if (MEM_P (mem))
		{
		  tree expr = MEM_EXPR (mem);
		  if (!expr)
		    continue;

		  if (TREE_CODE (expr) == MEM_REF
		      && TREE_CODE (TREE_OPERAND (expr, 0)) == SSA_NAME)
		    {
		      gimple *def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (expr, 0));
		      if (def_stmt && is_gimple_assign (def_stmt))
			expr = gimple_assign_rhs1 (def_stmt);
		    }

		  if (is_attr_preserve_access (expr))
		    {
		      auto_vec<unsigned int, 16> accessors;
		      tree container = bpf_core_compute (expr, &accessors);
		      if (accessors.length () < 1)
			continue;
		      accessors.reverse ();

		      container = TREE_TYPE (container);
		      const char * section_name;
		      if (DECL_SECTION_NAME (fn->decl))
			section_name = DECL_SECTION_NAME (fn->decl);
		      else
			section_name = ".text";

		      label = gen_label_rtx ();
		      LABEL_PRESERVE_P (label) = 1;
		      emit_label (label);

		      /* Add the CO-RE relocation information to the BTF container.  */
		      bpf_core_reloc_add (container, section_name, &accessors, label);
		    }
		}
	    }
	  rtx_insn *seq = get_insns ();
	  end_sequence ();
	  emit_insn_before (seq, insn);
	}
    }
}


/* This pass finds accesses to structures marked with the BPF target attribute
   __attribute__((preserve_access_index)). For every such access, a CO-RE
   relocation record is generated, to be output in the .BTF.ext section.  */

namespace {

const pass_data pass_data_bpf_core_attr =
{
  RTL_PASS, /* type */
  "bpf_core_attr", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_bpf_core_attr : public rtl_opt_pass
{
public:
  pass_bpf_core_attr (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_bpf_core_attr, ctxt)
  {}

  virtual bool gate (function *) { return TARGET_BPF_CORE; }
  virtual unsigned int execute (function *);
};

unsigned int
pass_bpf_core_attr::execute (function *fn)
{
  handle_attr_preserve (fn);
  return 0;
}

} /* Anonymous namespace.  */

rtl_opt_pass *
make_pass_bpf_core_attr (gcc::context *ctxt)
{
  return new pass_bpf_core_attr (ctxt);
}

/* Finally, build the GCC target.  */

struct gcc_target targetm = TARGET_INITIALIZER;

#include "gt-bpf.h"
