/* Producing binary form of HSA BRIG from our internal representation.
   Copyright (C) 2013-2017 Free Software Foundation, Inc.
   Contributed by Martin Jambor <mjambor@suse.cz> and
   Martin Liska <mliska@suse.cz>.

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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "target.h"
#include "memmodel.h"
#include "tm_p.h"
#include "is-a.h"
#include "vec.h"
#include "hash-table.h"
#include "hash-map.h"
#include "tree.h"
#include "tree-iterator.h"
#include "stor-layout.h"
#include "output.h"
#include "cfg.h"
#include "function.h"
#include "fold-const.h"
#include "stringpool.h"
#include "gimple-pretty-print.h"
#include "diagnostic-core.h"
#include "cgraph.h"
#include "dumpfile.h"
#include "print-tree.h"
#include "symbol-summary.h"
#include "hsa-common.h"
#include "gomp-constants.h"

/* Convert VAL to little endian form, if necessary.  */

static uint16_t
lendian16 (uint16_t val)
{
#if GCC_VERSION >= 4008
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  return val;
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  return __builtin_bswap16 (val);
#else   /* __ORDER_PDP_ENDIAN__ */
  return val;
#endif
#else
// provide a safe slower default, with shifts and masking
#ifndef WORDS_BIGENDIAN
  return val;
#else
  return (val >> 8) | (val << 8);
#endif
#endif
}

/* Convert VAL to little endian form, if necessary.  */

static uint32_t
lendian32 (uint32_t val)
{
#if GCC_VERSION >= 4006
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  return val;
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  return __builtin_bswap32 (val);
#else  /* __ORDER_PDP_ENDIAN__ */
  return (val >> 16) | (val << 16);
#endif
#else
// provide a safe slower default, with shifts and masking
#ifndef WORDS_BIGENDIAN
  return val;
#else
  val = ((val & 0xff00ff00) >> 8) | ((val & 0xff00ff) << 8);
  return (val >> 16) | (val << 16);
#endif
#endif
}

/* Convert VAL to little endian form, if necessary.  */

static uint64_t
lendian64 (uint64_t val)
{
#if GCC_VERSION >= 4006
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  return val;
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  return __builtin_bswap64 (val);
#else  /* __ORDER_PDP_ENDIAN__ */
  return (((val & 0xffffll) << 48)
	  | ((val & 0xffff0000ll) << 16)
	  | ((val & 0xffff00000000ll) >> 16)
	  | ((val & 0xffff000000000000ll) >> 48));
#endif
#else
// provide a safe slower default, with shifts and masking
#ifndef WORDS_BIGENDIAN
  return val;
#else
  val = (((val & 0xff00ff00ff00ff00ll) >> 8)
	 | ((val & 0x00ff00ff00ff00ffll) << 8));
  val = ((( val & 0xffff0000ffff0000ll) >> 16)
	 | (( val & 0x0000ffff0000ffffll) << 16));
  return (val >> 32) | (val << 32);
#endif
#endif
}

#define BRIG_ELF_SECTION_NAME ".brig"
#define BRIG_LABEL_STRING "hsa_brig"
#define BRIG_SECTION_DATA_NAME    "hsa_data"
#define BRIG_SECTION_CODE_NAME    "hsa_code"
#define BRIG_SECTION_OPERAND_NAME "hsa_operand"

#define BRIG_CHUNK_MAX_SIZE (64 * 1024)

/* Required HSA section alignment.  */

#define HSA_SECTION_ALIGNMENT 16

/* Chunks of BRIG binary data.  */

struct hsa_brig_data_chunk
{
  /* Size of the data already stored into a chunk.  */
  unsigned size;

  /* Pointer to the data.  */
  char *data;
};

/* Structure representing a BRIG section, holding and writing its data.  */

class hsa_brig_section
{
public:
  /* Section name that will be output to the BRIG.  */
  const char *section_name;
  /* Size in bytes of all data stored in the section.  */
  unsigned total_size;
  /* The size of the header of the section including padding.  */
  unsigned header_byte_count;
  /* The size of the header of the section without any padding.  */
  unsigned header_byte_delta;

  void init (const char *name);
  void release ();
  void output ();
  unsigned add (const void *data, unsigned len, void **output = NULL);
  void round_size_up (int factor);
  void *get_ptr_by_offset (unsigned int offset);

private:
  void allocate_new_chunk ();

  /* Buffers of binary data, each containing BRIG_CHUNK_MAX_SIZE bytes.  */
  vec <struct hsa_brig_data_chunk> chunks;

  /* More convenient access to the last chunk from the vector above.  */
  struct hsa_brig_data_chunk *cur_chunk;
};

static struct hsa_brig_section brig_data, brig_code, brig_operand;
static uint32_t brig_insn_count;
static bool brig_initialized = false;

/* Mapping between emitted HSA functions and their offset in code segment.  */
static hash_map<tree, BrigCodeOffset32_t> *function_offsets;

/* Hash map of emitted function declarations.  */
static hash_map <tree, BrigDirectiveExecutable *> *emitted_declarations;

/* Hash table of emitted internal function declaration offsets.  */
hash_table <hsa_internal_fn_hasher> *hsa_emitted_internal_decls;

/* List of sbr instructions.  */
static vec <hsa_insn_sbr *> *switch_instructions;

struct function_linkage_pair
{
  function_linkage_pair (tree decl, unsigned int off)
    : function_decl (decl), offset (off) {}

  /* Declaration of called function.  */
  tree function_decl;

  /* Offset in operand section.  */
  unsigned int offset;
};

/* Vector of function calls where we need to resolve function offsets.  */
static auto_vec <function_linkage_pair> function_call_linkage;

/* Add a new chunk, allocate data for it and initialize it.  */

void
hsa_brig_section::allocate_new_chunk ()
{
  struct hsa_brig_data_chunk new_chunk;

  new_chunk.data = XCNEWVEC (char, BRIG_CHUNK_MAX_SIZE);
  new_chunk.size = 0;
  cur_chunk = chunks.safe_push (new_chunk);
}

/* Initialize the brig section.  */

void
hsa_brig_section::init (const char *name)
{
  section_name = name;
  /* While the following computation is basically wrong, because the intent
     certainly wasn't to have the first character of name and padding, which
     are a part of sizeof (BrigSectionHeader), included in the first addend,
     this is what the disassembler expects.  */
  total_size = sizeof (BrigSectionHeader) + strlen (section_name);
  chunks.create (1);
  allocate_new_chunk ();
  header_byte_delta = total_size;
  round_size_up (4);
  header_byte_count = total_size;
}

/* Free all data in the section.  */

void
hsa_brig_section::release ()
{
  for (unsigned i = 0; i < chunks.length (); i++)
    free (chunks[i].data);
  chunks.release ();
  cur_chunk = NULL;
}

/* Write the section to the output file to a section with the name given at
   initialization.  Switches the output section and does not restore it.  */

void
hsa_brig_section::output ()
{
  struct BrigSectionHeader section_header;
  char padding[8];

  section_header.byteCount = lendian64 (total_size);
  section_header.headerByteCount = lendian32 (header_byte_count);
  section_header.nameLength = lendian32 (strlen (section_name));
  assemble_string ((const char *) &section_header, 16);
  assemble_string (section_name, (section_header.nameLength));
  memset (&padding, 0, sizeof (padding));
  /* This is also a consequence of the wrong header size computation described
     in a comment in hsa_brig_section::init.  */
  assemble_string (padding, 8);
  for (unsigned i = 0; i < chunks.length (); i++)
    assemble_string (chunks[i].data, chunks[i].size);
}

/* Add to the stream LEN bytes of opaque binary DATA.  Return the offset at
   which it was stored.  If OUTPUT is not NULL, store into it the pointer to
   the place where DATA was actually stored.  */

unsigned
hsa_brig_section::add (const void *data, unsigned len, void **output)
{
  unsigned offset = total_size;

  gcc_assert (len <= BRIG_CHUNK_MAX_SIZE);
  if (cur_chunk->size > (BRIG_CHUNK_MAX_SIZE - len))
    allocate_new_chunk ();

  char *dst = cur_chunk->data + cur_chunk->size;
  memcpy (dst, data, len);
  if (output)
    *output = dst;
  cur_chunk->size += len;
  total_size += len;

  return offset;
}

/* Add padding to section so that its size is divisible by FACTOR.  */

void
hsa_brig_section::round_size_up (int factor)
{
  unsigned padding, res = total_size % factor;

  if (res == 0)
    return;

  padding = factor - res;
  total_size += padding;
  if (cur_chunk->size > (BRIG_CHUNK_MAX_SIZE - padding))
    {
      padding -= BRIG_CHUNK_MAX_SIZE - cur_chunk->size;
      cur_chunk->size = BRIG_CHUNK_MAX_SIZE;
      allocate_new_chunk ();
    }

  cur_chunk->size += padding;
}

/* Return pointer to data by global OFFSET in the section.  */

void *
hsa_brig_section::get_ptr_by_offset (unsigned int offset)
{
  gcc_assert (offset < total_size);
  offset -= header_byte_delta;

  unsigned i;
  for (i = 0; offset >= chunks[i].size; i++)
    offset -= chunks[i].size;

  return chunks[i].data + offset;
}

/* BRIG string data hashing.  */

struct brig_string_slot
{
  const char *s;
  char prefix;
  int len;
  uint32_t offset;
};

/* Hash table helpers.  */

struct brig_string_slot_hasher : pointer_hash <brig_string_slot>
{
  static inline hashval_t hash (const value_type);
  static inline bool equal (const value_type, const compare_type);
  static inline void remove (value_type);
};

/* Returns a hash code for DS.  Adapted from libiberty's htab_hash_string
   to support strings that may not end in '\0'.  */

inline hashval_t
brig_string_slot_hasher::hash (const value_type ds)
{
  hashval_t r = ds->len;
  int i;

  for (i = 0; i < ds->len; i++)
     r = r * 67 + (unsigned) ds->s[i] - 113;
  r = r * 67 + (unsigned) ds->prefix - 113;
  return r;
}

/* Returns nonzero if DS1 and DS2 are equal.  */

inline bool
brig_string_slot_hasher::equal (const value_type ds1, const compare_type ds2)
{
  if (ds1->len == ds2->len)
    return ds1->prefix == ds2->prefix
      && memcmp (ds1->s, ds2->s, ds1->len) == 0;

  return 0;
}

/* Deallocate memory for DS upon its removal.  */

inline void
brig_string_slot_hasher::remove (value_type ds)
{
  free (const_cast<char *> (ds->s));
  free (ds);
}

/* Hash for strings we output in order not to duplicate them needlessly.  */

static hash_table<brig_string_slot_hasher> *brig_string_htab;

/* Emit a null terminated string STR to the data section and return its
   offset in it.  If PREFIX is non-zero, output it just before STR too.
   Sanitize the string if SANITIZE option is set to true.  */

static unsigned
brig_emit_string (const char *str, char prefix = 0, bool sanitize = true)
{
  unsigned slen = strlen (str);
  unsigned offset, len = slen + (prefix ? 1 : 0);
  uint32_t hdr_len = lendian32 (len);
  brig_string_slot s_slot;
  brig_string_slot **slot;
  char *str2;

  str2 = xstrdup (str);

  if (sanitize)
    hsa_sanitize_name (str2);
  s_slot.s = str2;
  s_slot.len = slen;
  s_slot.prefix = prefix;
  s_slot.offset = 0;

  slot = brig_string_htab->find_slot (&s_slot, INSERT);
  if (*slot == NULL)
    {
      brig_string_slot *new_slot = XCNEW (brig_string_slot);

      /* In theory we should fill in BrigData but that would mean copying
	 the string to a buffer for no reason, so we just emulate it.  */
      offset = brig_data.add (&hdr_len, sizeof (hdr_len));
      if (prefix)
	brig_data.add (&prefix, 1);

      brig_data.add (str2, slen);
      brig_data.round_size_up (4);

      /* TODO: could use the string we just copied into
	 brig_string->cur_chunk */
      new_slot->s = str2;
      new_slot->len = slen;
      new_slot->prefix = prefix;
      new_slot->offset = offset;
      *slot = new_slot;
    }
  else
    {
      offset = (*slot)->offset;
      free (str2);
    }

  return offset;
}

/* Linked list of queued operands.  */

static struct operand_queue
{
  /* First from the chain of queued operands.  */
  hsa_op_base *first_op, *last_op;

  /* The offset at which the next operand will be enqueued.  */
  unsigned projected_size;

} op_queue;

/* Unless already initialized, initialize infrastructure to produce BRIG.  */

static void
brig_init (void)
{
  brig_insn_count = 0;

  if (brig_initialized)
    return;

  brig_string_htab = new hash_table<brig_string_slot_hasher> (37);
  brig_data.init (BRIG_SECTION_DATA_NAME);
  brig_code.init (BRIG_SECTION_CODE_NAME);
  brig_operand.init (BRIG_SECTION_OPERAND_NAME);
  brig_initialized = true;

  struct BrigDirectiveModule moddir;
  memset (&moddir, 0, sizeof (moddir));
  moddir.base.byteCount = lendian16 (sizeof (moddir));

  char *modname;
  if (main_input_filename && *main_input_filename != '\0')
    {
      const char *part = strrchr (main_input_filename, '/');
      if (!part)
	part = main_input_filename;
      else
	part++;
      modname = concat ("&__hsa_module_", part, NULL);
      char *extension = strchr (modname, '.');
      if (extension)
	*extension = '\0';

      /* As in LTO mode, we have to emit a different module names.  */
      if (flag_ltrans)
	{
	  part = strrchr (asm_file_name, '/');
	  if (!part)
	    part = asm_file_name;
	  else
	    part++;
	  char *modname2;
	  modname2 = xasprintf ("%s_%s", modname, part);
	  free (modname);
	  modname = modname2;
	}

      hsa_sanitize_name (modname);
      moddir.name = brig_emit_string (modname);
      free (modname);
    }
  else
    moddir.name = brig_emit_string ("__hsa_module_unnamed", '&');
  moddir.base.kind = lendian16 (BRIG_KIND_DIRECTIVE_MODULE);
  moddir.hsailMajor = lendian32 (BRIG_VERSION_HSAIL_MAJOR);
  moddir.hsailMinor = lendian32 (BRIG_VERSION_HSAIL_MINOR);
  moddir.profile = hsa_full_profile_p () ? BRIG_PROFILE_FULL: BRIG_PROFILE_BASE;
  if (hsa_machine_large_p ())
    moddir.machineModel = BRIG_MACHINE_LARGE;
  else
    moddir.machineModel = BRIG_MACHINE_SMALL;
  moddir.defaultFloatRound = BRIG_ROUND_FLOAT_DEFAULT;
  brig_code.add (&moddir, sizeof (moddir));
}

/* Free all BRIG data.  */

static void
brig_release_data (void)
{
  delete brig_string_htab;
  brig_data.release ();
  brig_code.release ();
  brig_operand.release ();

  brig_initialized = 0;
}

/* Enqueue operation OP.  Return the offset at which it will be stored.  */

static unsigned int
enqueue_op (hsa_op_base *op)
{
  unsigned ret;

  if (op->m_brig_op_offset)
    return op->m_brig_op_offset;

  ret = op_queue.projected_size;
  op->m_brig_op_offset = op_queue.projected_size;

  if (!op_queue.first_op)
    op_queue.first_op = op;
  else
    op_queue.last_op->m_next = op;
  op_queue.last_op = op;

  if (is_a <hsa_op_immed *> (op))
    op_queue.projected_size += sizeof (struct BrigOperandConstantBytes);
  else if (is_a <hsa_op_reg *> (op))
    op_queue.projected_size += sizeof (struct BrigOperandRegister);
  else if (is_a <hsa_op_address *> (op))
    op_queue.projected_size += sizeof (struct BrigOperandAddress);
  else if (is_a <hsa_op_code_ref *> (op))
    op_queue.projected_size += sizeof (struct BrigOperandCodeRef);
  else if (is_a <hsa_op_code_list *> (op))
    op_queue.projected_size += sizeof (struct BrigOperandCodeList);
  else if (is_a <hsa_op_operand_list *> (op))
    op_queue.projected_size += sizeof (struct BrigOperandOperandList);
  else
    gcc_unreachable ();
  return ret;
}

static void emit_immediate_operand (hsa_op_immed *imm);

/* Emit directive describing a symbol if it has not been emitted already.
   Return the offset of the directive.  */

static unsigned
emit_directive_variable (struct hsa_symbol *symbol)
{
  struct BrigDirectiveVariable dirvar;
  unsigned name_offset;
  static unsigned res_name_offset;

  if (symbol->m_directive_offset)
    return symbol->m_directive_offset;

  memset (&dirvar, 0, sizeof (dirvar));
  dirvar.base.byteCount = lendian16 (sizeof (dirvar));
  dirvar.base.kind = lendian16 (BRIG_KIND_DIRECTIVE_VARIABLE);
  dirvar.allocation = symbol->m_allocation;

  char prefix = symbol->m_global_scope_p ? '&' : '%';

  if (symbol->m_decl && TREE_CODE (symbol->m_decl) == RESULT_DECL)
    {
      if (res_name_offset == 0)
	res_name_offset = brig_emit_string (symbol->m_name, '%');
      name_offset = res_name_offset;
    }
  else if (symbol->m_name)
    name_offset = brig_emit_string (symbol->m_name, prefix);
  else
    {
      char buf[64];
      snprintf (buf, 64, "__%s_%i", hsa_seg_name (symbol->m_segment),
		symbol->m_name_number);
      name_offset = brig_emit_string (buf, prefix);
    }

  dirvar.name = lendian32 (name_offset);

  if (symbol->m_decl && TREE_CODE (symbol->m_decl) == CONST_DECL)
    {
      hsa_op_immed *tmp = new hsa_op_immed (DECL_INITIAL (symbol->m_decl));
      dirvar.init = lendian32 (enqueue_op (tmp));
    }
  else
    dirvar.init = 0;
  dirvar.type = lendian16 (symbol->m_type);
  dirvar.segment = symbol->m_segment;
  dirvar.align = symbol->m_align;
  dirvar.linkage = symbol->m_linkage;
  dirvar.dim.lo = symbol->m_dim;
  dirvar.dim.hi = symbol->m_dim >> 32;

  /* Global variables are just declared and linked via HSA runtime.  */
  if (symbol->m_linkage != BRIG_ALLOCATION_PROGRAM)
    dirvar.modifier |= BRIG_VARIABLE_DEFINITION;
  dirvar.reserved = 0;

  if (symbol->m_cst_value)
    {
      dirvar.modifier |= BRIG_VARIABLE_CONST;
      dirvar.init = lendian32 (enqueue_op (symbol->m_cst_value));
    }

  symbol->m_directive_offset = brig_code.add (&dirvar, sizeof (dirvar));
  return symbol->m_directive_offset;
}

/* Emit directives describing either a function declaration or definition F and
   return the produced BrigDirectiveExecutable structure.  The function does
   not take into account any instructions when calculating nextModuleEntry
   field of the produced BrigDirectiveExecutable structure so when emitting
   actual definitions, this field needs to be updated after all of the function
   is actually added to the code section.  */

static BrigDirectiveExecutable *
emit_function_directives (hsa_function_representation *f, bool is_declaration)
{
  struct BrigDirectiveExecutable fndir;
  unsigned name_offset, inarg_off, scoped_off, next_toplev_off;
  int count = 0;
  void *ptr_to_fndir;
  hsa_symbol *sym;

  if (!f->m_declaration_p)
    for (int i = 0; f->m_global_symbols.iterate (i, &sym); i++)
      {
	gcc_assert (!sym->m_emitted_to_brig);
	sym->m_emitted_to_brig = true;
	emit_directive_variable (sym);
	brig_insn_count++;
      }

  name_offset = brig_emit_string (f->m_name, '&');
  inarg_off = brig_code.total_size + sizeof (fndir)
    + (f->m_output_arg ? sizeof (struct BrigDirectiveVariable) : 0);
  scoped_off = inarg_off
    + f->m_input_args.length () * sizeof (struct BrigDirectiveVariable);

  if (!f->m_declaration_p)
    {
      count += f->m_spill_symbols.length ();
      count += f->m_private_variables.length ();
    }

  next_toplev_off = scoped_off + count * sizeof (struct BrigDirectiveVariable);

  memset (&fndir, 0, sizeof (fndir));
  fndir.base.byteCount = lendian16 (sizeof (fndir));
  fndir.base.kind = lendian16 (f->m_kern_p ? BRIG_KIND_DIRECTIVE_KERNEL
			       : BRIG_KIND_DIRECTIVE_FUNCTION);
  fndir.name = lendian32 (name_offset);
  fndir.inArgCount = lendian16 (f->m_input_args.length ());
  fndir.outArgCount = lendian16 (f->m_output_arg ? 1 : 0);
  fndir.firstInArg = lendian32 (inarg_off);
  fndir.firstCodeBlockEntry = lendian32 (scoped_off);
  fndir.nextModuleEntry = lendian32 (next_toplev_off);
  fndir.linkage = f->get_linkage ();
  if (!f->m_declaration_p)
    fndir.modifier |= BRIG_EXECUTABLE_DEFINITION;
  memset (&fndir.reserved, 0, sizeof (fndir.reserved));

  /* Once we put a definition of function_offsets, we should not overwrite
     it with a declaration of the function.  */
  if (f->m_internal_fn == NULL)
    {
      if (!function_offsets->get (f->m_decl) || !is_declaration)
	function_offsets->put (f->m_decl, brig_code.total_size);
    }
  else
    {
      /* Internal function.  */
      hsa_internal_fn **slot
	= hsa_emitted_internal_decls->find_slot (f->m_internal_fn, INSERT);
      hsa_internal_fn *int_fn = new hsa_internal_fn (f->m_internal_fn);
      int_fn->m_offset = brig_code.total_size;
      *slot = int_fn;
    }

  brig_code.add (&fndir, sizeof (fndir), &ptr_to_fndir);

  if (f->m_output_arg)
    emit_directive_variable (f->m_output_arg);
  for (unsigned i = 0; i < f->m_input_args.length (); i++)
    emit_directive_variable (f->m_input_args[i]);

  if (!f->m_declaration_p)
    {
      for (int i = 0; f->m_spill_symbols.iterate (i, &sym); i++)
	{
	  emit_directive_variable (sym);
	  brig_insn_count++;
	}
      for (unsigned i = 0; i < f->m_private_variables.length (); i++)
	{
	  emit_directive_variable (f->m_private_variables[i]);
	  brig_insn_count++;
	}
    }

  return (BrigDirectiveExecutable *) ptr_to_fndir;
}

/* Emit a label directive for the given HBB.  We assume it is about to start on
   the current offset in the code section.  */

static void
emit_bb_label_directive (hsa_bb *hbb)
{
  struct BrigDirectiveLabel lbldir;

  lbldir.base.byteCount = lendian16 (sizeof (lbldir));
  lbldir.base.kind = lendian16 (BRIG_KIND_DIRECTIVE_LABEL);
  char buf[32];
  snprintf (buf, 32, "BB_%u_%i", DECL_UID (current_function_decl),
	    hbb->m_index);
  lbldir.name = lendian32 (brig_emit_string (buf, '@'));

  hbb->m_label_ref.m_directive_offset = brig_code.add (&lbldir,
						       sizeof (lbldir));
  brig_insn_count++;
}

/* Map a normal HSAIL type to the type of the equivalent BRIG operand
   holding such, for constants and registers.  */

static BrigType16_t
regtype_for_type (BrigType16_t t)
{
  switch (t)
    {
    case BRIG_TYPE_B1:
      return BRIG_TYPE_B1;

    case BRIG_TYPE_U8:
    case BRIG_TYPE_U16:
    case BRIG_TYPE_U32:
    case BRIG_TYPE_S8:
    case BRIG_TYPE_S16:
    case BRIG_TYPE_S32:
    case BRIG_TYPE_B8:
    case BRIG_TYPE_B16:
    case BRIG_TYPE_B32:
    case BRIG_TYPE_F16:
    case BRIG_TYPE_F32:
    case BRIG_TYPE_U8X4:
    case BRIG_TYPE_U16X2:
    case BRIG_TYPE_S8X4:
    case BRIG_TYPE_S16X2:
    case BRIG_TYPE_F16X2:
      return BRIG_TYPE_B32;

    case BRIG_TYPE_U64:
    case BRIG_TYPE_S64:
    case BRIG_TYPE_F64:
    case BRIG_TYPE_B64:
    case BRIG_TYPE_U8X8:
    case BRIG_TYPE_U16X4:
    case BRIG_TYPE_U32X2:
    case BRIG_TYPE_S8X8:
    case BRIG_TYPE_S16X4:
    case BRIG_TYPE_S32X2:
    case BRIG_TYPE_F16X4:
    case BRIG_TYPE_F32X2:
      return BRIG_TYPE_B64;

    case BRIG_TYPE_B128:
    case BRIG_TYPE_U8X16:
    case BRIG_TYPE_U16X8:
    case BRIG_TYPE_U32X4:
    case BRIG_TYPE_U64X2:
    case BRIG_TYPE_S8X16:
    case BRIG_TYPE_S16X8:
    case BRIG_TYPE_S32X4:
    case BRIG_TYPE_S64X2:
    case BRIG_TYPE_F16X8:
    case BRIG_TYPE_F32X4:
    case BRIG_TYPE_F64X2:
      return BRIG_TYPE_B128;

    default:
      gcc_unreachable ();
    }
}

/* Return the length of the BRIG type TYPE that is going to be streamed out as
   an immediate constant (so it must not be B1).  */

unsigned
hsa_get_imm_brig_type_len (BrigType16_t type)
{
  BrigType16_t base_type = type & BRIG_TYPE_BASE_MASK;
  BrigType16_t pack_type = type & BRIG_TYPE_PACK_MASK;

  switch (pack_type)
    {
    case BRIG_TYPE_PACK_NONE:
      break;
    case BRIG_TYPE_PACK_32:
      return 4;
    case BRIG_TYPE_PACK_64:
      return 8;
    case BRIG_TYPE_PACK_128:
      return 16;
    default:
      gcc_unreachable ();
    }

  switch (base_type)
    {
    case BRIG_TYPE_U8:
    case BRIG_TYPE_S8:
    case BRIG_TYPE_B8:
      return 1;
    case BRIG_TYPE_U16:
    case BRIG_TYPE_S16:
    case BRIG_TYPE_F16:
    case BRIG_TYPE_B16:
      return 2;
    case BRIG_TYPE_U32:
    case BRIG_TYPE_S32:
    case BRIG_TYPE_F32:
    case BRIG_TYPE_B32:
      return 4;
    case BRIG_TYPE_U64:
    case BRIG_TYPE_S64:
    case BRIG_TYPE_F64:
    case BRIG_TYPE_B64:
      return 8;
    case BRIG_TYPE_B128:
      return 16;
    default:
      gcc_unreachable ();
    }
}

/* Emit one scalar VALUE to the buffer DATA intended for BRIG emission.
   If NEED_LEN is not equal to zero, shrink or extend the value
   to NEED_LEN bytes.  Return how many bytes were written.  */

static int
emit_immediate_scalar_to_buffer (tree value, char *data, unsigned need_len)
{
  union hsa_bytes bytes;

  memset (&bytes, 0, sizeof (bytes));
  tree type = TREE_TYPE (value);
  gcc_checking_assert (TREE_CODE (type) != VECTOR_TYPE);

  unsigned data_len = tree_to_uhwi (TYPE_SIZE (type)) / BITS_PER_UNIT;
  if (INTEGRAL_TYPE_P (type)
      || (POINTER_TYPE_P (type) && TREE_CODE (value) == INTEGER_CST))
    switch (data_len)
      {
      case 1:
	bytes.b8 = (uint8_t) TREE_INT_CST_LOW (value);
	break;
      case 2:
	bytes.b16 = (uint16_t) TREE_INT_CST_LOW (value);
	break;
      case 4:
	bytes.b32 = (uint32_t) TREE_INT_CST_LOW (value);
	break;
      case 8:
	bytes.b64 = (uint64_t) TREE_INT_CST_LOW (value);
	break;
      default:
	gcc_unreachable ();
      }
  else if (SCALAR_FLOAT_TYPE_P (type))
    {
      if (data_len == 2)
	{
	  sorry ("Support for HSA does not implement immediate 16 bit FPU "
		 "operands");
	  return 2;
	}
      unsigned int_len = GET_MODE_SIZE (TYPE_MODE (type));
      /* There are always 32 bits in each long, no matter the size of
	 the hosts long.  */
      long tmp[6];

      real_to_target (tmp, TREE_REAL_CST_PTR (value), TYPE_MODE (type));

      if (int_len == 4)
	bytes.b32 = (uint32_t) tmp[0];
      else
	{
	  bytes.b64 = (uint64_t)(uint32_t) tmp[1];
	  bytes.b64 <<= 32;
	  bytes.b64 |= (uint32_t) tmp[0];
	}
    }
  else
    gcc_unreachable ();

  int len;
  if (need_len == 0)
    len = data_len;
  else
    len = need_len;

  memcpy (data, &bytes, len);
  return len;
}

char *
hsa_op_immed::emit_to_buffer (unsigned *brig_repr_size)
{
  char *brig_repr;
  *brig_repr_size = hsa_get_imm_brig_type_len (m_type);

  if (m_tree_value != NULL_TREE)
    {
      /* Update brig_repr_size for special tree values.  */
      if (TREE_CODE (m_tree_value) == STRING_CST)
	*brig_repr_size = TREE_STRING_LENGTH (m_tree_value);
      else if (TREE_CODE (m_tree_value) == CONSTRUCTOR)
	*brig_repr_size
	  = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (m_tree_value)));

      unsigned total_len = *brig_repr_size;

      /* As we can have a constructor with fewer elements, fill the memory
	 with zeros.  */
      brig_repr = XCNEWVEC (char, total_len);
      char *p = brig_repr;

      if (TREE_CODE (m_tree_value) == VECTOR_CST)
	{
	  int i, num = VECTOR_CST_NELTS (m_tree_value);
	  for (i = 0; i < num; i++)
	    {
	      tree v = VECTOR_CST_ELT (m_tree_value, i);
	      unsigned actual = emit_immediate_scalar_to_buffer (v, p, 0);
	      total_len -= actual;
	      p += actual;
	    }
	  /* Vectors should have the exact size.  */
	  gcc_assert (total_len == 0);
	}
      else if (TREE_CODE (m_tree_value) == STRING_CST)
	memcpy (brig_repr, TREE_STRING_POINTER (m_tree_value),
		TREE_STRING_LENGTH (m_tree_value));
      else if (TREE_CODE (m_tree_value) == COMPLEX_CST)
	{
	  gcc_assert (total_len % 2 == 0);
	  unsigned actual;
	  actual
	    = emit_immediate_scalar_to_buffer (TREE_REALPART (m_tree_value), p,
					       total_len / 2);

	  gcc_assert (actual == total_len / 2);
	  p += actual;

	  actual
	    = emit_immediate_scalar_to_buffer (TREE_IMAGPART (m_tree_value), p,
					       total_len / 2);
	  gcc_assert (actual == total_len / 2);
	}
      else if (TREE_CODE (m_tree_value) == CONSTRUCTOR)
	{
	  unsigned len = CONSTRUCTOR_NELTS (m_tree_value);
	  for (unsigned i = 0; i < len; i++)
	    {
	      tree v = CONSTRUCTOR_ELT (m_tree_value, i)->value;
	      unsigned actual = emit_immediate_scalar_to_buffer (v, p, 0);
	      total_len -= actual;
	      p += actual;
	    }
	}
      else
	emit_immediate_scalar_to_buffer (m_tree_value, p, total_len);
    }
  else
    {
      hsa_bytes bytes;

      switch (*brig_repr_size)
	{
	case 1:
	  bytes.b8 = (uint8_t) m_int_value;
	  break;
	case 2:
	  bytes.b16 = (uint16_t) m_int_value;
	  break;
	case 4:
	  bytes.b32 = (uint32_t) m_int_value;
	  break;
	case 8:
	  bytes.b64 = (uint64_t) m_int_value;
	  break;
	default:
	  gcc_unreachable ();
	}

      brig_repr = XNEWVEC (char, *brig_repr_size);
      memcpy (brig_repr, &bytes, *brig_repr_size);
    }

  return brig_repr;
}

/* Emit an immediate BRIG operand IMM.  The BRIG type of the immediate might
   have been massaged to comply with various HSA/BRIG type requirements, so the
   only important aspect of that is the length (because HSAIL might expect
   smaller constants or become bit-data).  The data should be represented
   according to what is in the tree representation.  */

static void
emit_immediate_operand (hsa_op_immed *imm)
{
  unsigned brig_repr_size;
  char *brig_repr = imm->emit_to_buffer (&brig_repr_size);
  struct BrigOperandConstantBytes out;

  memset (&out, 0, sizeof (out));
  out.base.byteCount = lendian16 (sizeof (out));
  out.base.kind = lendian16 (BRIG_KIND_OPERAND_CONSTANT_BYTES);
  uint32_t byteCount = lendian32 (brig_repr_size);
  out.type = lendian16 (imm->m_type);
  out.bytes = lendian32 (brig_data.add (&byteCount, sizeof (byteCount)));
  brig_operand.add (&out, sizeof (out));
  brig_data.add (brig_repr, brig_repr_size);
  brig_data.round_size_up (4);

  free (brig_repr);
}

/* Emit a register BRIG operand REG.  */

static void
emit_register_operand (hsa_op_reg *reg)
{
  struct BrigOperandRegister out;

  out.base.byteCount = lendian16 (sizeof (out));
  out.base.kind = lendian16 (BRIG_KIND_OPERAND_REGISTER);
  out.regNum = lendian32 (reg->m_hard_num);

  switch (regtype_for_type (reg->m_type))
    {
    case BRIG_TYPE_B32:
      out.regKind = BRIG_REGISTER_KIND_SINGLE;
      break;
    case BRIG_TYPE_B64:
      out.regKind = BRIG_REGISTER_KIND_DOUBLE;
      break;
    case BRIG_TYPE_B128:
      out.regKind = BRIG_REGISTER_KIND_QUAD;
      break;
    case BRIG_TYPE_B1:
      out.regKind = BRIG_REGISTER_KIND_CONTROL;
      break;
    default:
      gcc_unreachable ();
    }

  brig_operand.add (&out, sizeof (out));
}

/* Emit an address BRIG operand ADDR.  */

static void
emit_address_operand (hsa_op_address *addr)
{
  struct BrigOperandAddress out;

  out.base.byteCount = lendian16 (sizeof (out));
  out.base.kind = lendian16 (BRIG_KIND_OPERAND_ADDRESS);
  out.symbol = addr->m_symbol
    ? lendian32 (emit_directive_variable (addr->m_symbol)) : 0;
  out.reg = addr->m_reg ? lendian32 (enqueue_op (addr->m_reg)) : 0;

  if (sizeof (addr->m_imm_offset) == 8)
    {
      out.offset.lo = lendian32 (addr->m_imm_offset);
      out.offset.hi = lendian32 (addr->m_imm_offset >> 32);
    }
  else
    {
      gcc_assert (sizeof (addr->m_imm_offset) == 4);
      out.offset.lo = lendian32 (addr->m_imm_offset);
      out.offset.hi = 0;
    }

  brig_operand.add (&out, sizeof (out));
}

/* Emit a code reference operand REF.  */

static void
emit_code_ref_operand (hsa_op_code_ref *ref)
{
  struct BrigOperandCodeRef out;

  out.base.byteCount = lendian16 (sizeof (out));
  out.base.kind = lendian16 (BRIG_KIND_OPERAND_CODE_REF);
  out.ref = lendian32 (ref->m_directive_offset);
  brig_operand.add (&out, sizeof (out));
}

/* Emit a code list operand CODE_LIST.  */

static void
emit_code_list_operand (hsa_op_code_list *code_list)
{
  struct BrigOperandCodeList out;
  unsigned args = code_list->m_offsets.length ();

  for (unsigned i = 0; i < args; i++)
    gcc_assert (code_list->m_offsets[i]);

  out.base.byteCount = lendian16 (sizeof (out));
  out.base.kind = lendian16 (BRIG_KIND_OPERAND_CODE_LIST);

  uint32_t byteCount = lendian32 (4 * args);

  out.elements = lendian32 (brig_data.add (&byteCount, sizeof (byteCount)));
  brig_data.add (code_list->m_offsets.address (), args * sizeof (uint32_t));
  brig_data.round_size_up (4);
  brig_operand.add (&out, sizeof (out));
}

/* Emit an operand list operand OPERAND_LIST.  */

static void
emit_operand_list_operand (hsa_op_operand_list *operand_list)
{
  struct BrigOperandOperandList out;
  unsigned args = operand_list->m_offsets.length ();

  for (unsigned i = 0; i < args; i++)
    gcc_assert (operand_list->m_offsets[i]);

  out.base.byteCount = lendian16 (sizeof (out));
  out.base.kind = lendian16 (BRIG_KIND_OPERAND_OPERAND_LIST);

  uint32_t byteCount = lendian32 (4 * args);

  out.elements = lendian32 (brig_data.add (&byteCount, sizeof (byteCount)));
  brig_data.add (operand_list->m_offsets.address (), args * sizeof (uint32_t));
  brig_data.round_size_up (4);
  brig_operand.add (&out, sizeof (out));
}

/* Emit all operands queued for writing.  */

static void
emit_queued_operands (void)
{
  for (hsa_op_base *op = op_queue.first_op; op; op = op->m_next)
    {
      gcc_assert (op->m_brig_op_offset == brig_operand.total_size);
      if (hsa_op_immed *imm = dyn_cast <hsa_op_immed *> (op))
	emit_immediate_operand (imm);
      else if (hsa_op_reg *reg = dyn_cast <hsa_op_reg *> (op))
	emit_register_operand (reg);
      else if (hsa_op_address *addr = dyn_cast <hsa_op_address *> (op))
	emit_address_operand (addr);
      else if (hsa_op_code_ref *ref = dyn_cast <hsa_op_code_ref *> (op))
	emit_code_ref_operand (ref);
      else if (hsa_op_code_list *code_list = dyn_cast <hsa_op_code_list *> (op))
	emit_code_list_operand (code_list);
      else if (hsa_op_operand_list *l = dyn_cast <hsa_op_operand_list *> (op))
	emit_operand_list_operand (l);
      else
	gcc_unreachable ();
    }
}

/* Emit directives describing the function that is used for
   a function declaration.  */

static BrigDirectiveExecutable *
emit_function_declaration (tree decl)
{
  hsa_function_representation *f = hsa_generate_function_declaration (decl);

  BrigDirectiveExecutable *e = emit_function_directives (f, true);
  emit_queued_operands ();

  delete f;

  return e;
}

/* Emit directives describing the function that is used for
   an internal function declaration.  */

static BrigDirectiveExecutable *
emit_internal_fn_decl (hsa_internal_fn *fn)
{
  hsa_function_representation *f = hsa_generate_internal_fn_decl (fn);

  BrigDirectiveExecutable *e = emit_function_directives (f, true);
  emit_queued_operands ();

  delete f;

  return e;
}

/* Enqueue all operands of INSN and return offset to BRIG data section
   to list of operand offsets.  */

static unsigned
emit_insn_operands (hsa_insn_basic *insn)
{
  auto_vec<BrigOperandOffset32_t, HSA_BRIG_INT_STORAGE_OPERANDS>
    operand_offsets;

  unsigned l = insn->operand_count ();

  /* We have N operands so use 4 * N for the byte_count.  */
  uint32_t byte_count = lendian32 (4 * l);
  unsigned offset = brig_data.add (&byte_count, sizeof (byte_count));
  if (l > 0)
    {
      operand_offsets.safe_grow (l);
      for (unsigned i = 0; i < l; i++)
	operand_offsets[i] = lendian32 (enqueue_op (insn->get_op (i)));

      brig_data.add (operand_offsets.address (),
		     l * sizeof (BrigOperandOffset32_t));
    }
  brig_data.round_size_up (4);
  return offset;
}

/* Enqueue operand OP0, OP1, OP2 (if different from NULL) and return offset
   to BRIG data section to list of operand offsets.  */

static unsigned
emit_operands (hsa_op_base *op0, hsa_op_base *op1 = NULL,
	       hsa_op_base *op2 = NULL)
{
  auto_vec<BrigOperandOffset32_t, HSA_BRIG_INT_STORAGE_OPERANDS>
    operand_offsets;

  gcc_checking_assert (op0 != NULL);
  operand_offsets.safe_push (enqueue_op (op0));

  if (op1 != NULL)
    {
      operand_offsets.safe_push (enqueue_op (op1));
      if (op2 != NULL)
	operand_offsets.safe_push (enqueue_op (op2));
    }

  unsigned l = operand_offsets.length ();

  /* We have N operands so use 4 * N for the byte_count.  */
  uint32_t byte_count = lendian32 (4 * l);

  unsigned offset = brig_data.add (&byte_count, sizeof (byte_count));
  brig_data.add (operand_offsets.address (),
		 l * sizeof (BrigOperandOffset32_t));

  brig_data.round_size_up (4);

  return offset;
}

/* Emit an HSA memory instruction and all necessary directives, schedule
   necessary operands for writing.  */

static void
emit_memory_insn (hsa_insn_mem *mem)
{
  struct BrigInstMem repr;
  gcc_checking_assert (mem->operand_count () == 2);

  hsa_op_address *addr = as_a <hsa_op_address *> (mem->get_op (1));

  /* This is necessary because of the erroneous typedef of
     BrigMemoryModifier8_t which introduces padding which may then contain
     random stuff (which we do not want so that we can test things don't
     change).  */
  memset (&repr, 0, sizeof (repr));
  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_MEM);
  repr.base.opcode = lendian16 (mem->m_opcode);
  repr.base.type = lendian16 (mem->m_type);
  repr.base.operands = lendian32 (emit_insn_operands (mem));

  if (addr->m_symbol)
    repr.segment = addr->m_symbol->m_segment;
  else
    repr.segment = BRIG_SEGMENT_FLAT;
  repr.modifier = 0;
  repr.equivClass = mem->m_equiv_class;
  repr.align = mem->m_align;
  if (mem->m_opcode == BRIG_OPCODE_LD)
    repr.width = BRIG_WIDTH_1;
  else
    repr.width = BRIG_WIDTH_NONE;
  memset (&repr.reserved, 0, sizeof (repr.reserved));
  brig_code.add (&repr, sizeof (repr));
  brig_insn_count++;
}

/* Emit an HSA signal memory instruction and all necessary directives, schedule
   necessary operands for writing.  */

static void
emit_signal_insn (hsa_insn_signal *mem)
{
  struct BrigInstSignal repr;

  memset (&repr, 0, sizeof (repr));
  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_SIGNAL);
  repr.base.opcode = lendian16 (mem->m_opcode);
  repr.base.type = lendian16 (mem->m_type);
  repr.base.operands = lendian32 (emit_insn_operands (mem));

  repr.memoryOrder = mem->m_memory_order;
  repr.signalOperation = mem->m_signalop;
  repr.signalType = hsa_machine_large_p () ? BRIG_TYPE_SIG64 : BRIG_TYPE_SIG32;

  brig_code.add (&repr, sizeof (repr));
  brig_insn_count++;
}

/* Emit an HSA atomic memory instruction and all necessary directives, schedule
   necessary operands for writing.  */

static void
emit_atomic_insn (hsa_insn_atomic *mem)
{
  struct BrigInstAtomic repr;

  /* Either operand[0] or operand[1] must be an address operand.  */
  hsa_op_address *addr = NULL;
  if (is_a <hsa_op_address *> (mem->get_op (0)))
    addr = as_a <hsa_op_address *> (mem->get_op (0));
  else
    addr = as_a <hsa_op_address *> (mem->get_op (1));

  memset (&repr, 0, sizeof (repr));
  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_ATOMIC);
  repr.base.opcode = lendian16 (mem->m_opcode);
  repr.base.type = lendian16 (mem->m_type);
  repr.base.operands = lendian32 (emit_insn_operands (mem));

  if (addr->m_symbol)
    repr.segment = addr->m_symbol->m_segment;
  else
    repr.segment = BRIG_SEGMENT_FLAT;
  repr.memoryOrder = mem->m_memoryorder;
  repr.memoryScope = mem->m_memoryscope;
  repr.atomicOperation = mem->m_atomicop;

  brig_code.add (&repr, sizeof (repr));
  brig_insn_count++;
}

/* Emit an HSA LDA instruction and all necessary directives, schedule
   necessary operands for writing.  */

static void
emit_addr_insn (hsa_insn_basic *insn)
{
  struct BrigInstAddr repr;

  hsa_op_address *addr = as_a <hsa_op_address *> (insn->get_op (1));

  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_ADDR);
  repr.base.opcode = lendian16 (insn->m_opcode);
  repr.base.type = lendian16 (insn->m_type);
  repr.base.operands = lendian32 (emit_insn_operands (insn));

  if (addr->m_symbol)
    repr.segment = addr->m_symbol->m_segment;
  else
    repr.segment = BRIG_SEGMENT_FLAT;
  memset (&repr.reserved, 0, sizeof (repr.reserved));

  brig_code.add (&repr, sizeof (repr));
  brig_insn_count++;
}

/* Emit an HSA segment conversion instruction and all necessary directives,
   schedule necessary operands for writing.  */

static void
emit_segment_insn (hsa_insn_seg *seg)
{
  struct BrigInstSegCvt repr;

  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_SEG_CVT);
  repr.base.opcode = lendian16 (seg->m_opcode);
  repr.base.type = lendian16 (seg->m_type);
  repr.base.operands = lendian32 (emit_insn_operands (seg));
  repr.sourceType = lendian16 (as_a <hsa_op_reg *> (seg->get_op (1))->m_type);
  repr.segment = seg->m_segment;
  repr.modifier = 0;

  brig_code.add (&repr, sizeof (repr));

  brig_insn_count++;
}

/* Emit an HSA alloca instruction and all necessary directives,
   schedule necessary operands for writing.  */

static void
emit_alloca_insn (hsa_insn_alloca *alloca)
{
  struct BrigInstMem repr;
  gcc_checking_assert (alloca->operand_count () == 2);

  memset (&repr, 0, sizeof (repr));
  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_MEM);
  repr.base.opcode = lendian16 (alloca->m_opcode);
  repr.base.type = lendian16 (alloca->m_type);
  repr.base.operands = lendian32 (emit_insn_operands (alloca));
  repr.segment = BRIG_SEGMENT_PRIVATE;
  repr.modifier = 0;
  repr.equivClass = 0;
  repr.align = alloca->m_align;
  repr.width = BRIG_WIDTH_NONE;
  memset (&repr.reserved, 0, sizeof (repr.reserved));
  brig_code.add (&repr, sizeof (repr));
  brig_insn_count++;
}

/* Emit an HSA comparison instruction and all necessary directives,
   schedule necessary operands for writing.  */

static void
emit_cmp_insn (hsa_insn_cmp *cmp)
{
  struct BrigInstCmp repr;

  memset (&repr, 0, sizeof (repr));
  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_CMP);
  repr.base.opcode = lendian16 (cmp->m_opcode);
  repr.base.type = lendian16 (cmp->m_type);
  repr.base.operands = lendian32 (emit_insn_operands (cmp));

  if (is_a <hsa_op_reg *> (cmp->get_op (1)))
    repr.sourceType
      = lendian16 (as_a <hsa_op_reg *> (cmp->get_op (1))->m_type);
  else
    repr.sourceType
      = lendian16 (as_a <hsa_op_immed *> (cmp->get_op (1))->m_type);
  repr.modifier = 0;
  repr.compare = cmp->m_compare;
  repr.pack = 0;

  brig_code.add (&repr, sizeof (repr));
  brig_insn_count++;
}

/* Emit an HSA generic branching/sycnronization instruction.  */

static void
emit_generic_branch_insn (hsa_insn_br *br)
{
  struct BrigInstBr repr;
  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_BR);
  repr.base.opcode = lendian16 (br->m_opcode);
  repr.width = br->m_width;
  repr.base.type = lendian16 (br->m_type);
  repr.base.operands = lendian32 (emit_insn_operands (br));
  memset (&repr.reserved, 0, sizeof (repr.reserved));

  brig_code.add (&repr, sizeof (repr));
  brig_insn_count++;
}

/* Emit an HSA conditional branching instruction and all necessary directives,
   schedule necessary operands for writing.  */

static void
emit_cond_branch_insn (hsa_insn_cbr *br)
{
  struct BrigInstBr repr;

  basic_block target = NULL;
  edge_iterator ei;
  edge e;

  /* At the moment we only handle direct conditional jumps.  */
  gcc_assert (br->m_opcode == BRIG_OPCODE_CBR);
  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_BR);
  repr.base.opcode = lendian16 (br->m_opcode);
  repr.width = br->m_width;
  /* For Conditional jumps the type is always B1.  */
  repr.base.type = lendian16 (BRIG_TYPE_B1);

  FOR_EACH_EDGE (e, ei, br->m_bb->succs)
    if (e->flags & EDGE_TRUE_VALUE)
      {
	target = e->dest;
	break;
      }
  gcc_assert (target);

  repr.base.operands
    = lendian32 (emit_operands (br->get_op (0),
				&hsa_bb_for_bb (target)->m_label_ref));
  memset (&repr.reserved, 0, sizeof (repr.reserved));

  brig_code.add (&repr, sizeof (repr));
  brig_insn_count++;
}

/* Emit an HSA unconditional jump branching instruction that points to
   a label REFERENCE.  */

static void
emit_unconditional_jump (hsa_op_code_ref *reference)
{
  struct BrigInstBr repr;

  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_BR);
  repr.base.opcode = lendian16 (BRIG_OPCODE_BR);
  repr.base.type = lendian16 (BRIG_TYPE_NONE);
  /* Direct branches to labels must be width(all).  */
  repr.width = BRIG_WIDTH_ALL;

  repr.base.operands = lendian32 (emit_operands (reference));
  memset (&repr.reserved, 0, sizeof (repr.reserved));
  brig_code.add (&repr, sizeof (repr));
  brig_insn_count++;
}

/* Emit an HSA switch jump instruction that uses a jump table to
   jump to a destination label.  */

static void
emit_switch_insn (hsa_insn_sbr *sbr)
{
  struct BrigInstBr repr;

  gcc_assert (sbr->m_opcode == BRIG_OPCODE_SBR);
  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_BR);
  repr.base.opcode = lendian16 (sbr->m_opcode);
  repr.width = BRIG_WIDTH_1;
  /* For Conditional jumps the type is always B1.  */
  hsa_op_reg *index = as_a <hsa_op_reg *> (sbr->get_op (0));
  repr.base.type = lendian16 (index->m_type);
  repr.base.operands
    = lendian32 (emit_operands (sbr->get_op (0), sbr->m_label_code_list));
  memset (&repr.reserved, 0, sizeof (repr.reserved));

  brig_code.add (&repr, sizeof (repr));
  brig_insn_count++;
}

/* Emit a HSA convert instruction and all necessary directives, schedule
   necessary operands for writing.  */

static void
emit_cvt_insn (hsa_insn_cvt *insn)
{
  struct BrigInstCvt repr;
  BrigType16_t srctype;

  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_CVT);
  repr.base.opcode = lendian16 (insn->m_opcode);
  repr.base.type = lendian16 (insn->m_type);
  repr.base.operands = lendian32 (emit_insn_operands (insn));

  if (is_a <hsa_op_reg *> (insn->get_op (1)))
    srctype = as_a <hsa_op_reg *> (insn->get_op (1))->m_type;
  else
    srctype = as_a <hsa_op_immed *> (insn->get_op (1))->m_type;
  repr.sourceType = lendian16 (srctype);
  repr.modifier = 0;
  /* float to smaller float requires a rounding setting (we default
     to 'near'.  */
  if (hsa_type_float_p (insn->m_type)
      && (!hsa_type_float_p (srctype)
	  || ((insn->m_type & BRIG_TYPE_BASE_MASK)
	      < (srctype & BRIG_TYPE_BASE_MASK))))
    repr.round = BRIG_ROUND_FLOAT_NEAR_EVEN;
  else if (hsa_type_integer_p (insn->m_type) &&
	   hsa_type_float_p (srctype))
    repr.round = BRIG_ROUND_INTEGER_ZERO;
  else
    repr.round = BRIG_ROUND_NONE;
  brig_code.add (&repr, sizeof (repr));
  brig_insn_count++;
}

/* Emit call instruction INSN, where this instruction must be closed
   within a call block instruction.  */

static void
emit_call_insn (hsa_insn_call *call)
{
  struct BrigInstBr repr;

  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_BR);
  repr.base.opcode = lendian16 (BRIG_OPCODE_CALL);
  repr.base.type = lendian16 (BRIG_TYPE_NONE);

  repr.base.operands
    = lendian32 (emit_operands (call->m_result_code_list, &call->m_func,
				call->m_args_code_list));

  /* Internal functions have not set m_called_function.  */
  if (call->m_called_function)
    {
      function_linkage_pair pair (call->m_called_function,
				  call->m_func.m_brig_op_offset);
      function_call_linkage.safe_push (pair);
    }
  else
    {
      hsa_internal_fn *slot
	= hsa_emitted_internal_decls->find (call->m_called_internal_fn);
      gcc_assert (slot);
      gcc_assert (slot->m_offset > 0);
      call->m_func.m_directive_offset = slot->m_offset;
    }

  repr.width = BRIG_WIDTH_ALL;
  memset (&repr.reserved, 0, sizeof (repr.reserved));

  brig_code.add (&repr, sizeof (repr));
  brig_insn_count++;
}

/* Emit argument block directive.  */

static void
emit_arg_block_insn (hsa_insn_arg_block *insn)
{
  switch (insn->m_kind)
    {
    case BRIG_KIND_DIRECTIVE_ARG_BLOCK_START:
      {
	struct BrigDirectiveArgBlock repr;
	repr.base.byteCount = lendian16 (sizeof (repr));
	repr.base.kind = lendian16 (insn->m_kind);
	brig_code.add (&repr, sizeof (repr));

	for (unsigned i = 0; i < insn->m_call_insn->m_input_args.length (); i++)
	  {
	    insn->m_call_insn->m_args_code_list->m_offsets[i]
	      = lendian32 (emit_directive_variable
			   (insn->m_call_insn->m_input_args[i]));
	    brig_insn_count++;
	  }

	if (insn->m_call_insn->m_output_arg)
	  {
	    insn->m_call_insn->m_result_code_list->m_offsets[0]
	      = lendian32 (emit_directive_variable
			   (insn->m_call_insn->m_output_arg));
	    brig_insn_count++;
	  }

	break;
      }
    case BRIG_KIND_DIRECTIVE_ARG_BLOCK_END:
      {
	struct BrigDirectiveArgBlock repr;
	repr.base.byteCount = lendian16 (sizeof (repr));
	repr.base.kind = lendian16 (insn->m_kind);
	brig_code.add (&repr, sizeof (repr));
	break;
      }
    default:
      gcc_unreachable ();
    }

  brig_insn_count++;
}

/* Emit comment directive.  */

static void
emit_comment_insn (hsa_insn_comment *insn)
{
  struct BrigDirectiveComment repr;
  memset (&repr, 0, sizeof (repr));

  repr.base.byteCount = lendian16 (sizeof (repr));
  repr.base.kind = lendian16 (insn->m_opcode);
  repr.name = brig_emit_string (insn->m_comment, '\0', false);
  brig_code.add (&repr, sizeof (repr));
}

/* Emit queue instruction INSN.  */

static void
emit_queue_insn (hsa_insn_queue *insn)
{
  BrigInstQueue repr;
  memset (&repr, 0, sizeof (repr));

  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_QUEUE);
  repr.base.opcode = lendian16 (insn->m_opcode);
  repr.base.type = lendian16 (insn->m_type);
  repr.segment = insn->m_segment;
  repr.memoryOrder = insn->m_memory_order;
  repr.base.operands = lendian32 (emit_insn_operands (insn));
  brig_data.round_size_up (4);
  brig_code.add (&repr, sizeof (repr));

  brig_insn_count++;
}

/* Emit source type instruction INSN.  */

static void
emit_srctype_insn (hsa_insn_srctype *insn)
{
  /* We assume that BrigInstMod has a BrigInstBasic prefix.  */
  struct BrigInstSourceType repr;
  unsigned operand_count = insn->operand_count ();
  gcc_checking_assert (operand_count >= 2);

  memset (&repr, 0, sizeof (repr));
  repr.sourceType = lendian16 (insn->m_source_type);
  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_SOURCE_TYPE);
  repr.base.opcode = lendian16 (insn->m_opcode);
  repr.base.type = lendian16 (insn->m_type);

  repr.base.operands = lendian32 (emit_insn_operands (insn));
  brig_code.add (&repr, sizeof (struct BrigInstSourceType));
  brig_insn_count++;
}

/* Emit packed instruction INSN.  */

static void
emit_packed_insn (hsa_insn_packed *insn)
{
  /* We assume that BrigInstMod has a BrigInstBasic prefix.  */
  struct BrigInstSourceType repr;
  unsigned operand_count = insn->operand_count ();
  gcc_checking_assert (operand_count >= 2);

  memset (&repr, 0, sizeof (repr));
  repr.sourceType = lendian16 (insn->m_source_type);
  repr.base.base.byteCount = lendian16 (sizeof (repr));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_SOURCE_TYPE);
  repr.base.opcode = lendian16 (insn->m_opcode);
  repr.base.type = lendian16 (insn->m_type);

  if (insn->m_opcode == BRIG_OPCODE_COMBINE)
    {
      /* Create operand list for packed type.  */
      for (unsigned i = 1; i < operand_count; i++)
	{
	  gcc_checking_assert (insn->get_op (i));
	  insn->m_operand_list->m_offsets[i - 1]
	    = lendian32 (enqueue_op (insn->get_op (i)));
	}

      repr.base.operands = lendian32 (emit_operands (insn->get_op (0),
						     insn->m_operand_list));
    }
  else if (insn->m_opcode == BRIG_OPCODE_EXPAND)
    {
      /* Create operand list for packed type.  */
      for (unsigned i = 0; i < operand_count - 1; i++)
	{
	  gcc_checking_assert (insn->get_op (i));
	  insn->m_operand_list->m_offsets[i]
	    = lendian32 (enqueue_op (insn->get_op (i)));
	}

      unsigned ops = emit_operands (insn->m_operand_list,
				    insn->get_op (insn->operand_count () - 1));
      repr.base.operands = lendian32 (ops);
    }


  brig_code.add (&repr, sizeof (struct BrigInstSourceType));
  brig_insn_count++;
}

/* Emit a basic HSA instruction and all necessary directives, schedule
   necessary operands for writing.  */

static void
emit_basic_insn (hsa_insn_basic *insn)
{
  /* We assume that BrigInstMod has a BrigInstBasic prefix.  */
  struct BrigInstMod repr;
  BrigType16_t type;

  memset (&repr, 0, sizeof (repr));
  repr.base.base.byteCount = lendian16 (sizeof (BrigInstBasic));
  repr.base.base.kind = lendian16 (BRIG_KIND_INST_BASIC);
  repr.base.opcode = lendian16 (insn->m_opcode);
  switch (insn->m_opcode)
    {
      /* And the bit-logical operations need bit types and whine about
	 arithmetic types :-/  */
      case BRIG_OPCODE_AND:
      case BRIG_OPCODE_OR:
      case BRIG_OPCODE_XOR:
      case BRIG_OPCODE_NOT:
	type = regtype_for_type (insn->m_type);
	break;
      default:
	type = insn->m_type;
	break;
    }
  repr.base.type = lendian16 (type);
  repr.base.operands = lendian32 (emit_insn_operands (insn));

  if (hsa_type_packed_p (type))
    {
      if (hsa_type_float_p (type)
	  && !hsa_opcode_floating_bit_insn_p (insn->m_opcode))
	repr.round = BRIG_ROUND_FLOAT_NEAR_EVEN;
      else
	repr.round = 0;
      /* We assume that destination and sources agree in packing layout.  */
      if (insn->num_used_ops () >= 2)
	repr.pack = BRIG_PACK_PP;
      else
	repr.pack = BRIG_PACK_P;
      repr.reserved = 0;
      repr.base.base.byteCount = lendian16 (sizeof (BrigInstMod));
      repr.base.base.kind = lendian16 (BRIG_KIND_INST_MOD);
      brig_code.add (&repr, sizeof (struct BrigInstMod));
    }
  else
    brig_code.add (&repr, sizeof (struct BrigInstBasic));
  brig_insn_count++;
}

/* Emit an HSA instruction and all necessary directives, schedule necessary
   operands for writing.  */

static void
emit_insn (hsa_insn_basic *insn)
{
  gcc_assert (!is_a <hsa_insn_phi *> (insn));

  insn->m_brig_offset = brig_code.total_size;

  if (hsa_insn_signal *signal = dyn_cast <hsa_insn_signal *> (insn))
    emit_signal_insn (signal);
  else if (hsa_insn_atomic *atom = dyn_cast <hsa_insn_atomic *> (insn))
    emit_atomic_insn (atom);
  else if (hsa_insn_mem *mem = dyn_cast <hsa_insn_mem *> (insn))
    emit_memory_insn (mem);
  else if (insn->m_opcode == BRIG_OPCODE_LDA)
    emit_addr_insn (insn);
  else if (hsa_insn_seg *seg = dyn_cast <hsa_insn_seg *> (insn))
    emit_segment_insn (seg);
  else if (hsa_insn_cmp *cmp = dyn_cast <hsa_insn_cmp *> (insn))
    emit_cmp_insn (cmp);
  else if (hsa_insn_cbr *br = dyn_cast <hsa_insn_cbr *> (insn))
    emit_cond_branch_insn (br);
  else if (hsa_insn_sbr *sbr = dyn_cast <hsa_insn_sbr *> (insn))
    {
      if (switch_instructions == NULL)
	switch_instructions = new vec <hsa_insn_sbr *> ();

      switch_instructions->safe_push (sbr);
      emit_switch_insn (sbr);
    }
  else if (hsa_insn_br *br = dyn_cast <hsa_insn_br *> (insn))
    emit_generic_branch_insn (br);
  else if (hsa_insn_arg_block *block = dyn_cast <hsa_insn_arg_block *> (insn))
    emit_arg_block_insn (block);
  else if (hsa_insn_call *call = dyn_cast <hsa_insn_call *> (insn))
    emit_call_insn (call);
  else if (hsa_insn_comment *comment = dyn_cast <hsa_insn_comment *> (insn))
    emit_comment_insn (comment);
  else if (hsa_insn_queue *queue = dyn_cast <hsa_insn_queue *> (insn))
    emit_queue_insn (queue);
  else if (hsa_insn_srctype *srctype = dyn_cast <hsa_insn_srctype *> (insn))
    emit_srctype_insn (srctype);
  else if (hsa_insn_packed *packed = dyn_cast <hsa_insn_packed *> (insn))
    emit_packed_insn (packed);
  else if (hsa_insn_cvt *cvt = dyn_cast <hsa_insn_cvt *> (insn))
    emit_cvt_insn (cvt);
  else if (hsa_insn_alloca *alloca = dyn_cast <hsa_insn_alloca *> (insn))
    emit_alloca_insn (alloca);
  else
    emit_basic_insn (insn);
}

/* We have just finished emitting BB and are about to emit NEXT_BB if non-NULL,
   or we are about to finish emitting code, if it is NULL.  If the fall through
   edge from BB does not lead to NEXT_BB, emit an unconditional jump.  */

static void
perhaps_emit_branch (basic_block bb, basic_block next_bb)
{
  basic_block t_bb = NULL, ff = NULL;

  edge_iterator ei;
  edge e;

  /* If the last instruction of BB is a switch, ignore emission of all
     edges.  */
  if (hsa_bb_for_bb (bb)->m_last_insn
      && is_a <hsa_insn_sbr *> (hsa_bb_for_bb (bb)->m_last_insn))
    return;

  FOR_EACH_EDGE (e, ei, bb->succs)
    if (e->flags & EDGE_TRUE_VALUE)
      {
	gcc_assert (!t_bb);
	t_bb = e->dest;
      }
    else
      {
	gcc_assert (!ff);
	ff = e->dest;
      }

  if (!ff || ff == next_bb || ff == EXIT_BLOCK_PTR_FOR_FN (cfun))
    return;

  emit_unconditional_jump (&hsa_bb_for_bb (ff)->m_label_ref);
}

/* Emit the a function with name NAME to the various brig sections.  */

void
hsa_brig_emit_function (void)
{
  basic_block bb, prev_bb;
  hsa_insn_basic *insn;
  BrigDirectiveExecutable *ptr_to_fndir;

  brig_init ();

  brig_insn_count = 0;
  memset (&op_queue, 0, sizeof (op_queue));
  op_queue.projected_size = brig_operand.total_size;

  if (!function_offsets)
    function_offsets = new hash_map<tree, BrigCodeOffset32_t> ();

  if (!emitted_declarations)
    emitted_declarations = new hash_map <tree, BrigDirectiveExecutable *> ();

  for (unsigned i = 0; i < hsa_cfun->m_called_functions.length (); i++)
    {
      tree called = hsa_cfun->m_called_functions[i];

      /* If the function has no definition, emit a declaration.  */
      if (!emitted_declarations->get (called))
	{
	  BrigDirectiveExecutable *e = emit_function_declaration (called);
	  emitted_declarations->put (called, e);
	}
    }

  for (unsigned i = 0; i < hsa_cfun->m_called_internal_fns.length (); i++)
    {
      hsa_internal_fn *called = hsa_cfun->m_called_internal_fns[i];
      emit_internal_fn_decl (called);
    }

  ptr_to_fndir = emit_function_directives (hsa_cfun, false);
  for (insn = hsa_bb_for_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun))->m_first_insn;
       insn;
       insn = insn->m_next)
    emit_insn (insn);
  prev_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
  FOR_EACH_BB_FN (bb, cfun)
    {
      perhaps_emit_branch (prev_bb, bb);
      emit_bb_label_directive (hsa_bb_for_bb (bb));
      for (insn = hsa_bb_for_bb (bb)->m_first_insn; insn; insn = insn->m_next)
	emit_insn (insn);
      prev_bb = bb;
    }
  perhaps_emit_branch (prev_bb, NULL);
  ptr_to_fndir->nextModuleEntry = lendian32 (brig_code.total_size);

  /* Fill up label references for all sbr instructions.  */
  if (switch_instructions)
    {
      for (unsigned i = 0; i < switch_instructions->length (); i++)
	{
	  hsa_insn_sbr *sbr = (*switch_instructions)[i];
	  for (unsigned j = 0; j < sbr->m_jump_table.length (); j++)
	    {
	      hsa_bb *hbb = hsa_bb_for_bb (sbr->m_jump_table[j]);
	      sbr->m_label_code_list->m_offsets[j]
		= hbb->m_label_ref.m_directive_offset;
	    }
	}

      switch_instructions->release ();
      delete switch_instructions;
      switch_instructions = NULL;
    }

  if (dump_file)
    {
      fprintf (dump_file, "------- After BRIG emission: -------\n");
      dump_hsa_cfun (dump_file);
    }

  emit_queued_operands ();
}

/* Emit all OMP symbols related to OMP.  */

void
hsa_brig_emit_omp_symbols (void)
{
  brig_init ();
  emit_directive_variable (hsa_num_threads);
}

/* Create and return __hsa_global_variables symbol that contains
   all informations consumed by libgomp to link global variables
   with their string names used by an HSA kernel.  */

static tree
hsa_output_global_variables ()
{
  unsigned l = hsa_global_variable_symbols->elements ();

  tree variable_info_type = make_node (RECORD_TYPE);
  tree id_f1 = build_decl (BUILTINS_LOCATION, FIELD_DECL,
			   get_identifier ("name"), ptr_type_node);
  DECL_CHAIN (id_f1) = NULL_TREE;
  tree id_f2 = build_decl (BUILTINS_LOCATION, FIELD_DECL,
			   get_identifier ("omp_data_size"),
			   ptr_type_node);
  DECL_CHAIN (id_f2) = id_f1;
  finish_builtin_struct (variable_info_type, "__hsa_variable_info", id_f2,
			 NULL_TREE);

  tree int_num_of_global_vars;
  int_num_of_global_vars = build_int_cst (uint32_type_node, l);
  tree global_vars_num_index_type = build_index_type (int_num_of_global_vars);
  tree global_vars_array_type = build_array_type (variable_info_type,
						  global_vars_num_index_type);
  TYPE_ARTIFICIAL (global_vars_array_type) = 1;

  vec<constructor_elt, va_gc> *global_vars_vec = NULL;

  for (hash_table <hsa_noop_symbol_hasher>::iterator it
       = hsa_global_variable_symbols->begin ();
       it != hsa_global_variable_symbols->end (); ++it)
    {
      unsigned len = strlen ((*it)->m_name);
      char *copy = XNEWVEC (char, len + 2);
      copy[0] = '&';
      memcpy (copy + 1, (*it)->m_name, len);
      copy[len + 1] = '\0';
      len++;
      hsa_sanitize_name (copy);

      tree var_name = build_string (len, copy);
      TREE_TYPE (var_name)
	= build_array_type (char_type_node, build_index_type (size_int (len)));
      free (copy);

      vec<constructor_elt, va_gc> *variable_info_vec = NULL;
      CONSTRUCTOR_APPEND_ELT (variable_info_vec, NULL_TREE,
			      build1 (ADDR_EXPR,
				      build_pointer_type (TREE_TYPE (var_name)),
				      var_name));
      CONSTRUCTOR_APPEND_ELT (variable_info_vec, NULL_TREE,
			      build_fold_addr_expr ((*it)->m_decl));

      tree variable_info_ctor = build_constructor (variable_info_type,
						   variable_info_vec);

      CONSTRUCTOR_APPEND_ELT (global_vars_vec, NULL_TREE,
			      variable_info_ctor);
    }

  tree global_vars_ctor = build_constructor (global_vars_array_type,
					     global_vars_vec);

  char tmp_name[64];
  ASM_GENERATE_INTERNAL_LABEL (tmp_name, "__hsa_global_variables", 1);
  tree global_vars_table = build_decl (UNKNOWN_LOCATION, VAR_DECL,
					   get_identifier (tmp_name),
					   global_vars_array_type);
  TREE_STATIC (global_vars_table) = 1;
  TREE_READONLY (global_vars_table) = 1;
  TREE_PUBLIC (global_vars_table) = 0;
  DECL_ARTIFICIAL (global_vars_table) = 1;
  DECL_IGNORED_P (global_vars_table) = 1;
  DECL_EXTERNAL (global_vars_table) = 0;
  TREE_CONSTANT (global_vars_table) = 1;
  DECL_INITIAL (global_vars_table) = global_vars_ctor;
  varpool_node::finalize_decl (global_vars_table);

  return global_vars_table;
}

/* Create __hsa_host_functions and __hsa_kernels that contain
   all informations consumed by libgomp to register all kernels
   in the BRIG binary.  */

static void
hsa_output_kernels (tree *host_func_table, tree *kernels)
{
  unsigned map_count = hsa_get_number_decl_kernel_mappings ();

  tree int_num_of_kernels;
  int_num_of_kernels = build_int_cst (uint32_type_node, map_count);
  tree kernel_num_index_type = build_index_type (int_num_of_kernels);
  tree host_functions_array_type = build_array_type (ptr_type_node,
						     kernel_num_index_type);
  TYPE_ARTIFICIAL (host_functions_array_type) = 1;

  vec<constructor_elt, va_gc> *host_functions_vec = NULL;
  for (unsigned i = 0; i < map_count; ++i)
    {
      tree decl = hsa_get_decl_kernel_mapping_decl (i);
      tree host_fn = build_fold_addr_expr (hsa_get_host_function (decl));
      CONSTRUCTOR_APPEND_ELT (host_functions_vec, NULL_TREE, host_fn);
    }
  tree host_functions_ctor = build_constructor (host_functions_array_type,
						host_functions_vec);
  char tmp_name[64];
  ASM_GENERATE_INTERNAL_LABEL (tmp_name, "__hsa_host_functions", 1);
  tree hsa_host_func_table = build_decl (UNKNOWN_LOCATION, VAR_DECL,
					 get_identifier (tmp_name),
					 host_functions_array_type);
  TREE_STATIC (hsa_host_func_table) = 1;
  TREE_READONLY (hsa_host_func_table) = 1;
  TREE_PUBLIC (hsa_host_func_table) = 0;
  DECL_ARTIFICIAL (hsa_host_func_table) = 1;
  DECL_IGNORED_P (hsa_host_func_table) = 1;
  DECL_EXTERNAL (hsa_host_func_table) = 0;
  TREE_CONSTANT (hsa_host_func_table) = 1;
  DECL_INITIAL (hsa_host_func_table) = host_functions_ctor;
  varpool_node::finalize_decl (hsa_host_func_table);
  *host_func_table = hsa_host_func_table;

  /* Following code emits list of kernel_info structures.  */

  tree kernel_info_type = make_node (RECORD_TYPE);
  tree id_f1 = build_decl (BUILTINS_LOCATION, FIELD_DECL,
			   get_identifier ("name"), ptr_type_node);
  DECL_CHAIN (id_f1) = NULL_TREE;
  tree id_f2 = build_decl (BUILTINS_LOCATION, FIELD_DECL,
			   get_identifier ("omp_data_size"),
			   unsigned_type_node);
  DECL_CHAIN (id_f2) = id_f1;
  tree id_f3 = build_decl (BUILTINS_LOCATION, FIELD_DECL,
			   get_identifier ("gridified_kernel_p"),
			   boolean_type_node);
  DECL_CHAIN (id_f3) = id_f2;
  tree id_f4 = build_decl (BUILTINS_LOCATION, FIELD_DECL,
			   get_identifier ("kernel_dependencies_count"),
			   unsigned_type_node);
  DECL_CHAIN (id_f4) = id_f3;
  tree id_f5 = build_decl (BUILTINS_LOCATION, FIELD_DECL,
			   get_identifier ("kernel_dependencies"),
			   build_pointer_type (build_pointer_type
					       (char_type_node)));
  DECL_CHAIN (id_f5) = id_f4;
  finish_builtin_struct (kernel_info_type, "__hsa_kernel_info", id_f5,
			 NULL_TREE);

  int_num_of_kernels = build_int_cstu (uint32_type_node, map_count);
  tree kernel_info_vector_type
    = build_array_type (kernel_info_type,
			build_index_type (int_num_of_kernels));
  TYPE_ARTIFICIAL (kernel_info_vector_type) = 1;

  vec<constructor_elt, va_gc> *kernel_info_vector_vec = NULL;
  tree kernel_dependencies_vector_type = NULL;

  for (unsigned i = 0; i < map_count; ++i)
    {
      tree kernel = hsa_get_decl_kernel_mapping_decl (i);
      char *name = hsa_get_decl_kernel_mapping_name (i);
      unsigned len = strlen (name);
      char *copy = XNEWVEC (char, len + 2);
      copy[0] = '&';
      memcpy (copy + 1, name, len);
      copy[len + 1] = '\0';
      len++;

      tree kern_name = build_string (len, copy);
      TREE_TYPE (kern_name)
	= build_array_type (char_type_node, build_index_type (size_int (len)));
      free (copy);

      unsigned omp_size = hsa_get_decl_kernel_mapping_omp_size (i);
      tree omp_data_size = build_int_cstu (unsigned_type_node, omp_size);
      bool gridified_kernel_p = hsa_get_decl_kernel_mapping_gridified (i);
      tree gridified_kernel_p_tree = build_int_cstu (boolean_type_node,
						     gridified_kernel_p);
      unsigned count = 0;
      vec<constructor_elt, va_gc> *kernel_dependencies_vec = NULL;
      if (hsa_decl_kernel_dependencies)
	{
	  vec<const char *> **slot;
	  slot = hsa_decl_kernel_dependencies->get (kernel);
	  if (slot)
	    {
	      vec <const char *> *dependencies = *slot;
	      count = dependencies->length ();

	      kernel_dependencies_vector_type
		= build_array_type (build_pointer_type (char_type_node),
				    build_index_type (size_int (count)));
	      TYPE_ARTIFICIAL (kernel_dependencies_vector_type) = 1;

	      for (unsigned j = 0; j < count; j++)
		{
		  const char *d = (*dependencies)[j];
		  len = strlen (d);
		  tree dependency_name = build_string (len, d);
		  TREE_TYPE (dependency_name)
		    = build_array_type (char_type_node,
					build_index_type (size_int (len)));

		  CONSTRUCTOR_APPEND_ELT
		    (kernel_dependencies_vec, NULL_TREE,
		     build1 (ADDR_EXPR,
			     build_pointer_type (TREE_TYPE (dependency_name)),
			     dependency_name));
		}
	    }
	}

      tree dependencies_count = build_int_cstu (unsigned_type_node, count);

      vec<constructor_elt, va_gc> *kernel_info_vec = NULL;
      CONSTRUCTOR_APPEND_ELT (kernel_info_vec, NULL_TREE,
			      build1 (ADDR_EXPR,
				      build_pointer_type (TREE_TYPE
							  (kern_name)),
				      kern_name));
      CONSTRUCTOR_APPEND_ELT (kernel_info_vec, NULL_TREE, omp_data_size);
      CONSTRUCTOR_APPEND_ELT (kernel_info_vec, NULL_TREE,
			      gridified_kernel_p_tree);
      CONSTRUCTOR_APPEND_ELT (kernel_info_vec, NULL_TREE, dependencies_count);

      if (count > 0)
	{
	  ASM_GENERATE_INTERNAL_LABEL (tmp_name, "__hsa_dependencies_list", i);
	  gcc_checking_assert (kernel_dependencies_vector_type);
	  tree dependencies_list = build_decl (UNKNOWN_LOCATION, VAR_DECL,
					       get_identifier (tmp_name),
					       kernel_dependencies_vector_type);

	  TREE_STATIC (dependencies_list) = 1;
	  TREE_READONLY (dependencies_list) = 1;
	  TREE_PUBLIC (dependencies_list) = 0;
	  DECL_ARTIFICIAL (dependencies_list) = 1;
	  DECL_IGNORED_P (dependencies_list) = 1;
	  DECL_EXTERNAL (dependencies_list) = 0;
	  TREE_CONSTANT (dependencies_list) = 1;
	  DECL_INITIAL (dependencies_list)
	    = build_constructor (kernel_dependencies_vector_type,
				 kernel_dependencies_vec);
	  varpool_node::finalize_decl (dependencies_list);

	  CONSTRUCTOR_APPEND_ELT (kernel_info_vec, NULL_TREE,
				  build1 (ADDR_EXPR,
					  build_pointer_type
					    (TREE_TYPE (dependencies_list)),
					  dependencies_list));
	}
      else
	CONSTRUCTOR_APPEND_ELT (kernel_info_vec, NULL_TREE, null_pointer_node);

      tree kernel_info_ctor = build_constructor (kernel_info_type,
						 kernel_info_vec);

      CONSTRUCTOR_APPEND_ELT (kernel_info_vector_vec, NULL_TREE,
			      kernel_info_ctor);
    }

  ASM_GENERATE_INTERNAL_LABEL (tmp_name, "__hsa_kernels", 1);
  tree hsa_kernels = build_decl (UNKNOWN_LOCATION, VAR_DECL,
				 get_identifier (tmp_name),
				 kernel_info_vector_type);

  TREE_STATIC (hsa_kernels) = 1;
  TREE_READONLY (hsa_kernels) = 1;
  TREE_PUBLIC (hsa_kernels) = 0;
  DECL_ARTIFICIAL (hsa_kernels) = 1;
  DECL_IGNORED_P (hsa_kernels) = 1;
  DECL_EXTERNAL (hsa_kernels) = 0;
  TREE_CONSTANT (hsa_kernels) = 1;
  DECL_INITIAL (hsa_kernels) = build_constructor (kernel_info_vector_type,
						  kernel_info_vector_vec);
  varpool_node::finalize_decl (hsa_kernels);
  *kernels = hsa_kernels;
}

/* Create a static constructor that will register out brig stuff with
   libgomp.  */

static void
hsa_output_libgomp_mapping (tree brig_decl)
{
  unsigned kernel_count = hsa_get_number_decl_kernel_mappings ();
  unsigned global_variable_count = hsa_global_variable_symbols->elements ();

  tree kernels;
  tree host_func_table;

  hsa_output_kernels (&host_func_table, &kernels);
  tree global_vars = hsa_output_global_variables ();

  tree hsa_image_desc_type = make_node (RECORD_TYPE);
  tree id_f1 = build_decl (BUILTINS_LOCATION, FIELD_DECL,
			   get_identifier ("brig_module"), ptr_type_node);
  DECL_CHAIN (id_f1) = NULL_TREE;
  tree id_f2 = build_decl (BUILTINS_LOCATION, FIELD_DECL,
			   get_identifier ("kernel_count"),
			   unsigned_type_node);

  DECL_CHAIN (id_f2) = id_f1;
  tree id_f3 = build_decl (BUILTINS_LOCATION, FIELD_DECL,
			   get_identifier ("hsa_kernel_infos"),
			   ptr_type_node);
  DECL_CHAIN (id_f3) = id_f2;
  tree id_f4 = build_decl (BUILTINS_LOCATION, FIELD_DECL,
			   get_identifier ("global_variable_count"),
			   unsigned_type_node);
  DECL_CHAIN (id_f4) = id_f3;
  tree id_f5 = build_decl (BUILTINS_LOCATION, FIELD_DECL,
			   get_identifier ("hsa_global_variable_infos"),
			   ptr_type_node);
  DECL_CHAIN (id_f5) = id_f4;
  finish_builtin_struct (hsa_image_desc_type, "__hsa_image_desc", id_f5,
			 NULL_TREE);
  TYPE_ARTIFICIAL (hsa_image_desc_type) = 1;

  vec<constructor_elt, va_gc> *img_desc_vec = NULL;
  CONSTRUCTOR_APPEND_ELT (img_desc_vec, NULL_TREE,
			  build_fold_addr_expr (brig_decl));
  CONSTRUCTOR_APPEND_ELT (img_desc_vec, NULL_TREE,
			  build_int_cstu (unsigned_type_node, kernel_count));
  CONSTRUCTOR_APPEND_ELT (img_desc_vec, NULL_TREE,
			  build1 (ADDR_EXPR,
				  build_pointer_type (TREE_TYPE (kernels)),
				  kernels));
  CONSTRUCTOR_APPEND_ELT (img_desc_vec, NULL_TREE,
			  build_int_cstu (unsigned_type_node,
					  global_variable_count));
  CONSTRUCTOR_APPEND_ELT (img_desc_vec, NULL_TREE,
			  build1 (ADDR_EXPR,
				  build_pointer_type (TREE_TYPE (global_vars)),
				  global_vars));

  tree img_desc_ctor = build_constructor (hsa_image_desc_type, img_desc_vec);

  char tmp_name[64];
  ASM_GENERATE_INTERNAL_LABEL (tmp_name, "__hsa_img_descriptor", 1);
  tree hsa_img_descriptor = build_decl (UNKNOWN_LOCATION, VAR_DECL,
					get_identifier (tmp_name),
					hsa_image_desc_type);
  TREE_STATIC (hsa_img_descriptor) = 1;
  TREE_READONLY (hsa_img_descriptor) = 1;
  TREE_PUBLIC (hsa_img_descriptor) = 0;
  DECL_ARTIFICIAL (hsa_img_descriptor) = 1;
  DECL_IGNORED_P (hsa_img_descriptor) = 1;
  DECL_EXTERNAL (hsa_img_descriptor) = 0;
  TREE_CONSTANT (hsa_img_descriptor) = 1;
  DECL_INITIAL (hsa_img_descriptor) = img_desc_ctor;
  varpool_node::finalize_decl (hsa_img_descriptor);

  /* Construct the "host_table" libgomp expects.  */
  tree index_type = build_index_type (build_int_cst (integer_type_node, 4));
  tree libgomp_host_table_type = build_array_type (ptr_type_node, index_type);
  TYPE_ARTIFICIAL (libgomp_host_table_type) = 1;
  vec<constructor_elt, va_gc> *libgomp_host_table_vec = NULL;
  tree host_func_table_addr = build_fold_addr_expr (host_func_table);
  CONSTRUCTOR_APPEND_ELT (libgomp_host_table_vec, NULL_TREE,
			  host_func_table_addr);
  offset_int func_table_size
    = wi::to_offset (TYPE_SIZE_UNIT (ptr_type_node)) * kernel_count;
  CONSTRUCTOR_APPEND_ELT (libgomp_host_table_vec, NULL_TREE,
			  fold_build2 (POINTER_PLUS_EXPR,
				       TREE_TYPE (host_func_table_addr),
				       host_func_table_addr,
				       build_int_cst (size_type_node,
						      func_table_size.to_uhwi
						      ())));
  CONSTRUCTOR_APPEND_ELT (libgomp_host_table_vec, NULL_TREE, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (libgomp_host_table_vec, NULL_TREE, null_pointer_node);
  tree libgomp_host_table_ctor = build_constructor (libgomp_host_table_type,
						    libgomp_host_table_vec);
  ASM_GENERATE_INTERNAL_LABEL (tmp_name, "__hsa_libgomp_host_table", 1);
  tree hsa_libgomp_host_table = build_decl (UNKNOWN_LOCATION, VAR_DECL,
					    get_identifier (tmp_name),
					    libgomp_host_table_type);

  TREE_STATIC (hsa_libgomp_host_table) = 1;
  TREE_READONLY (hsa_libgomp_host_table) = 1;
  TREE_PUBLIC (hsa_libgomp_host_table) = 0;
  DECL_ARTIFICIAL (hsa_libgomp_host_table) = 1;
  DECL_IGNORED_P (hsa_libgomp_host_table) = 1;
  DECL_EXTERNAL (hsa_libgomp_host_table) = 0;
  TREE_CONSTANT (hsa_libgomp_host_table) = 1;
  DECL_INITIAL (hsa_libgomp_host_table) = libgomp_host_table_ctor;
  varpool_node::finalize_decl (hsa_libgomp_host_table);

  /* Generate an initializer with a call to the registration routine.  */

  tree offload_register
    = builtin_decl_explicit (BUILT_IN_GOMP_OFFLOAD_REGISTER);
  gcc_checking_assert (offload_register);

  tree *hsa_ctor_stmts = hsa_get_ctor_statements ();
  append_to_statement_list
    (build_call_expr (offload_register, 4,
		      build_int_cstu (unsigned_type_node,
				      GOMP_VERSION_PACK (GOMP_VERSION,
							 GOMP_VERSION_HSA)),
		      build_fold_addr_expr (hsa_libgomp_host_table),
		      build_int_cst (integer_type_node, GOMP_DEVICE_HSA),
		      build_fold_addr_expr (hsa_img_descriptor)),
     hsa_ctor_stmts);

  cgraph_build_static_cdtor ('I', *hsa_ctor_stmts, DEFAULT_INIT_PRIORITY);

  tree offload_unregister
    = builtin_decl_explicit (BUILT_IN_GOMP_OFFLOAD_UNREGISTER);
  gcc_checking_assert (offload_unregister);

  tree *hsa_dtor_stmts = hsa_get_dtor_statements ();
  append_to_statement_list
    (build_call_expr (offload_unregister, 4,
		      build_int_cstu (unsigned_type_node,
				      GOMP_VERSION_PACK (GOMP_VERSION,
							 GOMP_VERSION_HSA)),
		      build_fold_addr_expr (hsa_libgomp_host_table),
		      build_int_cst (integer_type_node, GOMP_DEVICE_HSA),
		      build_fold_addr_expr (hsa_img_descriptor)),
     hsa_dtor_stmts);
  cgraph_build_static_cdtor ('D', *hsa_dtor_stmts, DEFAULT_INIT_PRIORITY);
}

/* Emit the brig module we have compiled to a section in the final assembly and
   also create a compile unit static constructor that will register the brig
   module with libgomp.  */

void
hsa_output_brig (void)
{
  section *saved_section;

  if (!brig_initialized)
    return;

  for (unsigned i = 0; i < function_call_linkage.length (); i++)
    {
      function_linkage_pair p = function_call_linkage[i];

      BrigCodeOffset32_t *func_offset = function_offsets->get (p.function_decl);
      gcc_assert (*func_offset);
      BrigOperandCodeRef *code_ref
	= (BrigOperandCodeRef *) (brig_operand.get_ptr_by_offset (p.offset));
      gcc_assert (code_ref->base.kind == BRIG_KIND_OPERAND_CODE_REF);
      code_ref->ref = lendian32 (*func_offset);
    }

  /* Iterate all function declarations and if we meet a function that should
     have module linkage and we are unable to emit HSAIL for the function,
     then change the linkage to program linkage.  Doing so, we will emit
     a valid BRIG image.  */
  if (hsa_failed_functions != NULL && emitted_declarations != NULL)
    for (hash_map <tree, BrigDirectiveExecutable *>::iterator it
	 = emitted_declarations->begin ();
	 it != emitted_declarations->end ();
	 ++it)
      {
	if (hsa_failed_functions->contains ((*it).first))
	  (*it).second->linkage = BRIG_LINKAGE_PROGRAM;
      }

  saved_section = in_section;

  switch_to_section (get_section (BRIG_ELF_SECTION_NAME, SECTION_NOTYPE, NULL));
  char tmp_name[64];
  ASM_GENERATE_INTERNAL_LABEL (tmp_name, BRIG_LABEL_STRING, 1);
  ASM_OUTPUT_LABEL (asm_out_file, tmp_name);
  tree brig_id = get_identifier (tmp_name);
  tree brig_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, brig_id,
			       char_type_node);
  SET_DECL_ASSEMBLER_NAME (brig_decl, brig_id);
  TREE_ADDRESSABLE (brig_decl) = 1;
  TREE_READONLY (brig_decl) = 1;
  DECL_ARTIFICIAL (brig_decl) = 1;
  DECL_IGNORED_P (brig_decl) = 1;
  TREE_STATIC (brig_decl) = 1;
  TREE_PUBLIC (brig_decl) = 0;
  TREE_USED (brig_decl) = 1;
  DECL_INITIAL (brig_decl) = brig_decl;
  TREE_ASM_WRITTEN (brig_decl) = 1;

  BrigModuleHeader module_header;
  memcpy (&module_header.identification, "HSA BRIG",
	  sizeof (module_header.identification));
  module_header.brigMajor = lendian32 (BRIG_VERSION_BRIG_MAJOR);
  module_header.brigMinor = lendian32 (BRIG_VERSION_BRIG_MINOR);
  uint64_t section_index[3];

  int data_padding, code_padding, operand_padding;
  data_padding = HSA_SECTION_ALIGNMENT
    - brig_data.total_size % HSA_SECTION_ALIGNMENT;
  code_padding = HSA_SECTION_ALIGNMENT
    - brig_code.total_size % HSA_SECTION_ALIGNMENT;
  operand_padding = HSA_SECTION_ALIGNMENT
    - brig_operand.total_size % HSA_SECTION_ALIGNMENT;

  uint64_t module_size = sizeof (module_header)
    + sizeof (section_index)
    + brig_data.total_size
    + data_padding
    + brig_code.total_size
    + code_padding
    + brig_operand.total_size
    + operand_padding;
  gcc_assert ((module_size % 16) == 0);
  module_header.byteCount = lendian64 (module_size);
  memset (&module_header.hash, 0, sizeof (module_header.hash));
  module_header.reserved = 0;
  module_header.sectionCount = lendian32 (3);
  module_header.sectionIndex = lendian64 (sizeof (module_header));
  assemble_string ((const char *) &module_header, sizeof (module_header));
  uint64_t off = sizeof (module_header) + sizeof (section_index);
  section_index[0] = lendian64 (off);
  off += brig_data.total_size + data_padding;
  section_index[1] = lendian64 (off);
  off += brig_code.total_size + code_padding;
  section_index[2] = lendian64 (off);
  assemble_string ((const char *) &section_index, sizeof (section_index));

  char padding[HSA_SECTION_ALIGNMENT];
  memset (padding, 0, sizeof (padding));

  brig_data.output ();
  assemble_string (padding, data_padding);
  brig_code.output ();
  assemble_string (padding, code_padding);
  brig_operand.output ();
  assemble_string (padding, operand_padding);

  if (saved_section)
    switch_to_section (saved_section);

  hsa_output_libgomp_mapping (brig_decl);

  hsa_free_decl_kernel_mapping ();
  brig_release_data ();
  hsa_deinit_compilation_unit_data ();

  delete emitted_declarations;
  emitted_declarations = NULL;
  delete function_offsets;
  function_offsets = NULL;
}
