diff mbox

[hsa] Upgrade to HSAIL 1.0p

Message ID 20140925234906.GE20259@virgil.suse
State New
Headers show

Commit Message

Martin Jambor Sept. 25, 2014, 11:49 p.m. UTC
Hi,

this big patch is work of Ganesh Gopalasubramanian with a small number
of my modifications.  It upgrades the hsa branch of gcc to HSAIL
version 1.0p (so far we've been producing 0.95).

Bootstrapped to confirm there were no warnings, tested on a collection
of OMP testcases, committed to the HSA branch.

Thanks,

Martin


2014-09-26  Ganesh Gopalasubramanian  <Ganesh.Gopalasubramanian@amd.com>
 	    Martin Jambor  <mjambor@suse.cz>

	* hsa-brig-format.h: Update to HSA 1.0p.
	* hsa-brig.c: Remove strtab, directives	and debug sections.
	(hsa_brig_section): New fields section_name and header_byte_count.
	(hsa_brig_section::init): New parameter name, store it, calculate
	header size from it.
	(hsa_brig_section::output): Removed parameter section_name. Output
	section in the new format.
	(brig_emit_string): Emit strings to the data section.
	(c_reg_names, s_reg_names, d_reg_names, q_reg_names): Removed.
	(c_regs, s_regs, d_regs, q_regs): Likewise.
	(brig_init): Handle bytecount and kind info as part of base.  Change
	enumeration names.  Emit BrigDirectiveVersion in code section.
	(brig_release_data): Remove brig_string, brig_debug and
	brig_directive. Add brig_data.
	(get_alignment): New function.
	(emit_symbol_directive): Renamed to emit_directive_variable.  Handle
	bytecount and kind info as part of base.  Change enumeration
	names. Emit strings in data section.  Emit BrigDirectiveVariable in
	code section.
	(emit_function_directives): Likewise.  Increment brig_insn_count.
	(emit_bb_label_directive): Likewise.
	(enqueue_op): Remove reg name handling.  Change BrigOperandRef to
	BrigOperandCodeRef.  Handle immediate operand size using
	BrigOperandData.
	(emit_immediate_operand): Change enumeration names.  Emit immediate
	operand in data section.
	(emit_register_name): Removed.
	(emit_register_operand): Remove register name handling.  Handle
	register number and register kind.
	(emit_address_operand): Handle bytecount and kind info as part of
	base.  Change enumeration names.
	(emit_label_operand): Likewise.
	(emit_memory_insn): Handle bytecount and kind info as part of base.
	Change enumeration names.  Add insn alignment.
	(emit_atomic_insn): Likewise.  Add memoryorder and memoryscope.
	(emit_addr_insn): Likewise.
	(emit_segment_insn): Likewise.
	(emit_cmp_insn): Likewise.
	(emit_branch_insn): Likewise.
	(emit_cvt_insn): Likewise.
	(emit_basic_insn): Likewise.
	(perhaps_emit_branch): Likewise.
	(hsa_brig_emit_function): Use HSA 1.0p ield names.
	(hsa_output_brig): Remove brig_directive, brig_string and brig_debug
	sections. Add brig_data section.
	* hsa-dump.c (hsa_type_name): Update to HSAIL 1.0p.
	(hsa_opcode_name): Likewise.
	(hsa_memsem_name): Likewise.
	(hsa_memscope_name): New function.
	(hsa_atomicop_name): Update to HSAIL 1.0p.
	(dump_hsa_insn): Likewise.
	* hsa-gen.c (hsa_init_data_for_cfun): Change BRIG_OPERAND_LABEL_REF to
	BRIG_KIND_OPERAND_CODE_REF.
	(hsa_alloc_immed_op): Change BRIG_OPERAND_IMMED to
	BRIG_KIND_OPERAND_DATA.
	(hsa_alloc_reg_op): Change BRIG_OPERAND_REG to BRIG_KIND_OPERAND_REG.
	(hsa_alloc_addr_op): Change BRIG_OPERAND_ADDRESS to
	BRIG_KIND_OPERAND_ADDRESS.
	(gen_hsa_insns_for_call): Add memoryscope to meminsn. Change
	semantic to memoryorder.
	(hsa_init_new_bb): Change BRIG_OPERAND_LABEL_REF to
	BRIG_KIND_OPERAND_CODE_REF.
	* README.hsa: Add a brief comment about further incompatibilities with
        the given instructions.
---
 gcc/README.hsa        |    6 +-
 gcc/hsa-brig-format.h | 1175 ++++++++++++++++++++++---------------------------
 gcc/hsa-brig.c        |  698 +++++++++++++++--------------
 gcc/hsa-dump.c        |  272 +++++++-----
 gcc/hsa-gen.c         |   18 +-
 gcc/hsa.h             |   28 +-
 6 files changed, 1081 insertions(+), 1116 deletions(-)
diff mbox

Patch

diff --git a/gcc/README.hsa b/gcc/README.hsa
index baad817..513dbcc 100644
--- a/gcc/README.hsa
+++ b/gcc/README.hsa
@@ -6,8 +6,10 @@  recent one.
 
 In particular, in this revision it is impossible to directly use the
 simulator any more, only the OKRA interface is supported (but you can
-still use the simulator through it).  The rest still works, provided
-your OKRA and LIBHSAIL tools support and work with HSAIL 0.95.
+still use the simulator through it).  Even the rest of the
+instructions are not quite up to date.  You need to use LIBHSAIL
+supporting HSAIL 1.0p and only extract different sections from the
+object files.
 
 ===========================================================================
 
diff --git a/gcc/hsa-brig-format.h b/gcc/hsa-brig-format.h
index 7715772..179ea4c 100644
--- a/gcc/hsa-brig-format.h
+++ b/gcc/hsa-brig-format.h
@@ -1,9 +1,6 @@ 
 /* HSAIL and BRIG related macros and definitions.
    Copyright (C) 2013 Free Software Foundation, Inc.
 
-   FIXME: This is basically all copied from the HSA Programmers Reference Guide,
-   so it's HSA foundation code, can we publish it under GPL?
-
    This file is part of GCC.
 
    GCC is free software; you can redistribute it and/or modify
@@ -26,75 +23,34 @@ 
 #include "config.h"
 #include "system.h"
 
-typedef uint32_t BrigDirectiveOffset32_t;
+typedef uint32_t BrigDataOffset32_t;
 typedef uint32_t BrigCodeOffset32_t;
 typedef uint32_t BrigOperandOffset32_t;
-typedef uint32_t BrigStringOffset32_t;
-
-typedef uint16_t BrigDirectiveKinds16_t;
-enum BrigDirectiveKinds {
-  BRIG_DIRECTIVE_ARG_SCOPE_END = 0,
-  BRIG_DIRECTIVE_ARG_SCOPE_START = 1,
-  BRIG_DIRECTIVE_BLOCK_END = 2,
-  BRIG_DIRECTIVE_BLOCK_NUMERIC = 3,
-  BRIG_DIRECTIVE_BLOCK_START = 4,
-  BRIG_DIRECTIVE_BLOCK_STRING = 5,
-  BRIG_DIRECTIVE_COMMENT = 6,
-  BRIG_DIRECTIVE_CONTROL = 7,
-  BRIG_DIRECTIVE_EXTENSION = 8,
-  BRIG_DIRECTIVE_FBARRIER = 9,
-  BRIG_DIRECTIVE_FILE = 10,
-  BRIG_DIRECTIVE_FUNCTION = 11,
-  BRIG_DIRECTIVE_IMAGE = 12,
-  BRIG_DIRECTIVE_IMAGE_INIT = 13,
-  BRIG_DIRECTIVE_KERNEL = 14,
-  BRIG_DIRECTIVE_LABEL = 15,
-  BRIG_DIRECTIVE_LABEL_INIT = 16,
-  BRIG_DIRECTIVE_LABEL_TARGETS = 17,
-  BRIG_DIRECTIVE_LOC = 18,
-  BRIG_DIRECTIVE_PRAGMA = 19,
-  BRIG_DIRECTIVE_SAMPLER = 20,
-  BRIG_DIRECTIVE_SAMPLER_INIT = 21,
-  BRIG_DIRECTIVE_SCOPE = 22,
-  BRIG_DIRECTIVE_SIGNATURE = 23,
-  BRIG_DIRECTIVE_VARIABLE = 24,
-  BRIG_DIRECTIVE_VARIABLE_INIT = 25,
-  BRIG_DIRECTIVE_VERSION = 26
-};
-
-typedef uint16_t BrigInstKinds16_t;
-enum BrigInstKinds {
-  BRIG_INST_NONE = 0,
-  BRIG_INST_BASIC = 1,
-  BRIG_INST_ATOMIC = 2,
-  BRIG_INST_ATOMIC_IMAGE = 3,
-  BRIG_INST_BAR = 4,
-  BRIG_INST_BR = 5,
-  BRIG_INST_CMP = 6,
-  BRIG_INST_CVT = 7,
-  BRIG_INST_FBAR = 8,
-  BRIG_INST_IMAGE = 9,
-  BRIG_INST_MEM = 10,
-  BRIG_INST_ADDR = 11,
-  BRIG_INST_MOD = 12,
-  BRIG_INST_SEG = 13,
-  BRIG_INST_SOURCE_TYPE = 14
-};
-
-typedef uint16_t BrigOperandKinds16_t;
-enum BrigOperandKinds {
-  BRIG_OPERAND_IMMED = 0,
-  BRIG_OPERAND_WAVESIZE = 1,
-  BRIG_OPERAND_REG = 2,
-  BRIG_OPERAND_REG_VECTOR = 3,
-  BRIG_OPERAND_ADDRESS = 4,
-  BRIG_OPERAND_LABEL_REF = 5,
-  BRIG_OPERAND_ARGUMENT_REF = 6,
-  BRIG_OPERAND_ARGUMENT_LIST = 7,
-  BRIG_OPERAND_FUNCTION_REF = 8,
-  BRIG_OPERAND_FUNCTION_LIST = 9,
-  BRIG_OPERAND_SIGNATURE_REF = 10,
-  BRIG_OPERAND_FBARRIER_REF = 11
+
+typedef BrigDataOffset32_t BrigDataOffsetString32_t;
+typedef BrigDataOffset32_t BrigDataOffsetCodeList32_t;
+typedef BrigDataOffset32_t BrigDataOffsetOperandList32_t;
+
+typedef uint8_t BrigAlignment8_t;
+enum BrigAlignment {
+  BRIG_ALIGNMENT_NONE = 0,
+  BRIG_ALIGNMENT_1 = 1,
+  BRIG_ALIGNMENT_2 = 2,
+  BRIG_ALIGNMENT_4 = 3,
+  BRIG_ALIGNMENT_8 = 4,
+  BRIG_ALIGNMENT_16 = 5,
+  BRIG_ALIGNMENT_32 = 6,
+  BRIG_ALIGNMENT_64 = 7,
+  BRIG_ALIGNMENT_128 = 8,
+  BRIG_ALIGNMENT_256 = 9
+};
+
+typedef uint8_t BrigAllocation8_t;
+enum BrigAllocation {
+  BRIG_ALLOCATION_NONE = 0,
+  BRIG_ALLOCATION_PROGRAM = 1,
+  BRIG_ALLOCATION_AGENT = 2,
+  BRIG_ALLOCATION_AUTOMATIC = 3
 };
 
 typedef uint16_t BrigAluModifier16_t;
@@ -105,17 +61,81 @@  enum BrigAluModifierMask {
 
 typedef uint8_t BrigAtomicOperation8_t;
 enum BrigAtomicOperation {
-  BRIG_ATOMIC_AND = 0,
-  BRIG_ATOMIC_OR = 1,
-  BRIG_ATOMIC_XOR = 2,
-  BRIG_ATOMIC_CAS = 3,
-  BRIG_ATOMIC_EXCH = 4,
-  BRIG_ATOMIC_ADD = 5,
-  BRIG_ATOMIC_INC = 6,
-  BRIG_ATOMIC_DEC = 7,
-  BRIG_ATOMIC_MIN = 8,
-  BRIG_ATOMIC_MAX = 9,
-  BRIG_ATOMIC_SUB = 10
+  BRIG_ATOMIC_ADD = 0,
+  BRIG_ATOMIC_AND = 1,
+  BRIG_ATOMIC_CAS = 2,
+  BRIG_ATOMIC_EXCH = 3,
+  BRIG_ATOMIC_LD = 4,
+  BRIG_ATOMIC_MAX = 5,
+  BRIG_ATOMIC_MIN = 6,
+  BRIG_ATOMIC_OR = 7,
+  BRIG_ATOMIC_ST = 8,
+  BRIG_ATOMIC_SUB = 9,
+  BRIG_ATOMIC_WRAPDEC = 10,
+  BRIG_ATOMIC_WRAPINC = 11,
+  BRIG_ATOMIC_XOR = 12,
+  BRIG_ATOMIC_WAIT_EQ = 13,
+  BRIG_ATOMIC_WAIT_NE = 14,
+  BRIG_ATOMIC_WAIT_LT = 15,
+  BRIG_ATOMIC_WAIT_GTE = 16,
+  BRIG_ATOMIC_WAITTIMEOUT_EQ = 17,
+  BRIG_ATOMIC_WAITTIMEOUT_NE = 18,
+  BRIG_ATOMIC_WAITTIMEOUT_LT = 19,
+  BRIG_ATOMIC_WAITTIMEOUT_GTE = 20
+};
+
+typedef uint16_t BrigKinds16_t;
+enum BrigKind {
+  BRIG_KIND_NONE = 0x0000,
+  BRIG_KIND_DIRECTIVE_BEGIN = 0x1000,
+  BRIG_KIND_DIRECTIVE_ARG_BLOCK_END = 0x1000,
+  BRIG_KIND_DIRECTIVE_ARG_BLOCK_START = 0x1001,
+  BRIG_KIND_DIRECTIVE_COMMENT = 0x1002,
+  BRIG_KIND_DIRECTIVE_CONTROL = 0x1003,
+  BRIG_KIND_DIRECTIVE_EXTENSION = 0x1004,
+  BRIG_KIND_DIRECTIVE_FBARRIER = 0x1005,
+  BRIG_KIND_DIRECTIVE_FUNCTION = 0x1006,
+  BRIG_KIND_DIRECTIVE_INDIRECT_FUNCTION = 0x1007,
+  BRIG_KIND_DIRECTIVE_KERNEL = 0x1008,
+  BRIG_KIND_DIRECTIVE_LABEL = 0x1009,
+  BRIG_KIND_DIRECTIVE_LOC = 0x100a,
+  BRIG_KIND_DIRECTIVE_PRAGMA = 0x100b,
+  BRIG_KIND_DIRECTIVE_SIGNATURE = 0x100c,
+  BRIG_KIND_DIRECTIVE_VARIABLE = 0x100d,
+  BRIG_KIND_DIRECTIVE_VERSION = 0x100e,
+  BRIG_KIND_DIRECTIVE_END = 0x100f,
+  BRIG_KIND_INST_BEGIN = 0x2000,
+  BRIG_KIND_INST_ADDR = 0x2000,
+  BRIG_KIND_INST_ATOMIC = 0x2001,
+  BRIG_KIND_INST_BASIC = 0x2002,
+  BRIG_KIND_INST_BR = 0x2003,
+  BRIG_KIND_INST_CMP = 0x2004,
+  BRIG_KIND_INST_CVT = 0x2005,
+  BRIG_KIND_INST_IMAGE = 0x2006,
+  BRIG_KIND_INST_LANE = 0x2007,
+  BRIG_KIND_INST_MEM = 0x2008,
+  BRIG_KIND_INST_MEM_FENCE = 0x2009,
+  BRIG_KIND_INST_MOD = 0x200a,
+  BRIG_KIND_INST_QUERY_IMAGE = 0x200b,
+  BRIG_KIND_INST_QUERY_SAMPLER = 0x200c,
+  BRIG_KIND_INST_QUEUE = 0x200d,
+  BRIG_KIND_INST_SEG = 0x200e,
+  BRIG_KIND_INST_SEG_CVT = 0x200f,
+  BRIG_KIND_INST_SIGNAL = 0x2010,
+  BRIG_KIND_INST_SOURCE_TYPE = 0x2011,
+  BRIG_KIND_INST_END = 0x2012,
+  BRIG_KIND_OPERAND_BEGIN = 0x3000,
+  BRIG_KIND_OPERAND_ADDRESS = 0x3000,
+  BRIG_KIND_OPERAND_DATA = 0x3001,
+  BRIG_KIND_OPERAND_CODE_LIST = 0x3002,
+  BRIG_KIND_OPERAND_CODE_REF = 0x3003,
+  BRIG_KIND_OPERAND_IMAGE_PROPERTIES = 0x3004,
+  BRIG_KIND_OPERAND_OPERAND_LIST = 0x3005,
+  BRIG_KIND_OPERAND_REG = 0x3006,
+  BRIG_KIND_OPERAND_SAMPLER_PROPERTIES = 0x3007,
+  BRIG_KIND_OPERAND_STRING = 0x3008,
+  BRIG_KIND_OPERAND_WAVESIZE = 0x3009,
+  BRIG_KIND_OPERAND_END = 0x300a
 };
 
 typedef uint8_t BrigCompareOperation8_t;
@@ -167,28 +187,51 @@  enum BrigControlDirective {
 
 typedef uint8_t BrigExecutableModifier8_t;
 enum BrigExecuteableModifierMask {
-  BRIG_EXECUTABLE_LINKAGE = 3,
-  BRIG_EXECUTABLE_DECLARATION = 4
-};
-
-typedef uint8_t BrigImageFormat8_t;
-enum BrigImageFormat {
-  BRIG_FORMAT_SNORM_INT8 = 0,
-  BRIG_FORMAT_SNORM_INT16 = 1,
-  BRIG_FORMAT_UNORM_INT8 = 2,
-  BRIG_FORMAT_UNORM_INT16 = 3,
-  BRIG_FORMAT_UNORM_SHORT_565 = 4,
-  BRIG_FORMAT_UNORM_SHORT_555 = 5,
-  BRIG_FORMAT_UNORM_SHORT_101010 = 6,
-  BRIG_FORMAT_SIGNED_INT8 = 7,
-  BRIG_FORMAT_SIGNED_INT16 = 8,
-  BRIG_FORMAT_SIGNED_INT32 = 9,
-  BRIG_FORMAT_UNSIGNED_INT8 = 10,
-  BRIG_FORMAT_UNSIGNED_INT16 = 11,
-  BRIG_FORMAT_UNSIGNED_INT32 = 12,
-  BRIG_FORMAT_HALF_FLOAT = 13,
-  BRIG_FORMAT_FLOAT = 14,
-  BRIG_FORMAT_UNORM_INT24 = 15
+  BRIG_EXECUTABLE_DEFINITION = 1
+};
+
+typedef uint8_t BrigImageChannelOrder8_t;
+enum BrigImageChannelOrder {
+  BRIG_CHANNEL_ORDER_A = 0,
+  BRIG_CHANNEL_ORDER_R = 1,
+  BRIG_CHANNEL_ORDER_RX = 2,
+  BRIG_CHANNEL_ORDER_RG = 3,
+  BRIG_CHANNEL_ORDER_RGX = 4,
+  BRIG_CHANNEL_ORDER_RA = 5,
+  BRIG_CHANNEL_ORDER_RGB = 6,
+  BRIG_CHANNEL_ORDER_RGBX = 7,
+  BRIG_CHANNEL_ORDER_RGBA = 8,
+  BRIG_CHANNEL_ORDER_BGRA = 9,
+  BRIG_CHANNEL_ORDER_ARGB = 10,
+  BRIG_CHANNEL_ORDER_ABGR = 11,
+  BRIG_CHANNEL_ORDER_SRGB = 12,
+  BRIG_CHANNEL_ORDER_SRGBX = 13,
+  BRIG_CHANNEL_ORDER_SRGBA = 14,
+  BRIG_CHANNEL_ORDER_SBGRA = 15,
+  BRIG_CHANNEL_ORDER_INTENSITY = 16,
+  BRIG_CHANNEL_ORDER_LUMINANCE = 17,
+  BRIG_CHANNEL_ORDER_DEPTH = 18,
+  BRIG_CHANNEL_ORDER_DEPTH_STENCIL = 19
+};
+
+typedef uint8_t BrigImageChannelType8_t;
+enum BrigImageChannelType {
+  BRIG_CHANNEL_TYPE_SNORM_INT8 = 0,
+  BRIG_CHANNEL_TYPE_SNORM_INT16 = 1,
+  BRIG_CHANNEL_TYPE_UNORM_INT8 = 2,
+  BRIG_CHANNEL_TYPE_UNORM_INT16 = 3,
+  BRIG_CHANNEL_TYPE_UNORM_INT24 = 4,
+  BRIG_CHANNEL_TYPE_UNORM_SHORT_555 = 5,
+  BRIG_CHANNEL_TYPE_UNORM_SHORT_565 = 6,
+  BRIG_CHANNEL_TYPE_UNORM_SHORT_101010 = 7,
+  BRIG_CHANNEL_TYPE_SIGNED_INT8 = 8,
+  BRIG_CHANNEL_TYPE_SIGNED_INT16 = 9,
+  BRIG_CHANNEL_TYPE_SIGNED_INT32 = 10,
+  BRIG_CHANNEL_TYPE_UNSIGNED_INT8 = 11,
+  BRIG_CHANNEL_TYPE_UNSIGNED_INT16 = 12,
+  BRIG_CHANNEL_TYPE_UNSIGNED_INT32 = 13,
+  BRIG_CHANNEL_TYPE_HALF_FLOAT = 14,
+  BRIG_CHANNEL_TYPE_FLOAT = 15
 };
 
 typedef uint8_t BrigImageGeometry8_t;
@@ -197,36 +240,29 @@  enum BrigImageGeometry {
   BRIG_GEOMETRY_2D = 1,
   BRIG_GEOMETRY_3D = 2,
   BRIG_GEOMETRY_1DA = 3,
-  BRIG_GEOMETRY_1DB = 4,
-  BRIG_GEOMETRY_2DA = 5
-};
-
-typedef uint8_t BrigImageOrder8_t;
-enum BrigImageOrder {
-  BRIG_ORDER_R = 0,
-  BRIG_ORDER_A = 1,
-  BRIG_ORDER_RX = 2,
-  BRIG_ORDER_RG = 3,
-  BRIG_ORDER_RGX = 4,
-  BRIG_ORDER_RA = 5,
-  BRIG_ORDER_RGB = 6,
-  BRIG_ORDER_RGBA = 7,
-  BRIG_ORDER_RGBX = 8,
-  BRIG_ORDER_BGRA = 9,
-  BRIG_ORDER_ARGB = 10,
-  BRIG_ORDER_INTENSITY = 11,
-  BRIG_ORDER_LUMINANCE = 12,
-  BRIG_ORDER_SRGB = 13,
-  BRIG_ORDER_SRGBX = 14,
-  BRIG_ORDER_SRGBA = 15,
-  BRIG_ORDER_SBGRA = 16
+  BRIG_GEOMETRY_2DA = 4,
+  BRIG_GEOMETRY_1DB = 5,
+  BRIG_GEOMETRY_2DDEPTH = 6,
+  BRIG_GEOMETRY_2DADEPTH = 7
+};
+
+typedef uint8_t BrigImageQuery8_t;
+enum BrigImageQuery {
+  BRIG_IMAGE_QUERY_WIDTH = 0,
+  BRIG_IMAGE_QUERY_HEIGHT = 1,
+  BRIG_IMAGE_QUERY_DEPTH = 2,
+  BRIG_IMAGE_QUERY_ARRAY = 3,
+  BRIG_IMAGE_QUERY_CHANNELORDER = 4,
+  BRIG_IMAGE_QUERY_CHANNELTYPE = 5
 };
 
 typedef uint8_t BrigLinkage8_t;
 enum BrigLinkage {
   BRIG_LINKAGE_NONE = 0,
-  BRIG_LINKAGE_STATIC = 1,
-  BRIG_LINKAGE_EXTERN = 2
+  BRIG_LINKAGE_PROGRAM = 1,
+  BRIG_LINKAGE_MODULE = 2,
+  BRIG_LINKAGE_FUNCTION = 3,
+  BRIG_LINKAGE_ARG = 4
 };
 
 typedef uint8_t BrigMachineModel8_t;
@@ -235,34 +271,28 @@  enum BrigMachineModel {
   BRIG_MACHINE_LARGE = 1
 };
 
-typedef uint8_t BrigMemoryFence8_t;
-enum BrigMemoryFence {
-  BRIG_FENCE_NONE = 0,
-  BRIG_FENCE_GROUP = 1,
-  BRIG_FENCE_GLOBAL = 2,
-  BRIG_FENCE_BOTH = 3,
-  BRIG_FENCE_PARTIAL = 4,
-  BRIG_FENCE_PARTIAL_BOTH = 5
+typedef uint8_t BrigMemoryModifier8_t;
+enum BrigMemoryModifierMask {
+  BRIG_MEMORY_CONST = 1
 };
 
-/* This is most certainly a bug in the specificaton but the verifier uses this
-   flawed typedef too and so we need to as well.  */
-typedef uint16_t BrigMemoryModifier8_t;
-enum BrigMemoryModifierMask {
-  BRIG_MEMORY_SEMANTIC = 15,
-  BRIG_MEMORY_ALIGNED = 16
+typedef uint8_t BrigMemoryOrder8_t;
+enum BrigMemoryOrder {
+  BRIG_MEMORY_ORDER_NONE = 0,
+  BRIG_MEMORY_ORDER_RELAXED = 1,
+  BRIG_MEMORY_ORDER_SC_ACQUIRE = 2,
+  BRIG_MEMORY_ORDER_SC_RELEASE = 3,
+  BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE = 4
 };
 
-typedef uint8_t BrigMemorySemantic8_t;
-enum BrigMemorySemantic {
-  BRIG_SEMANTIC_NONE = 0,
-  BRIG_SEMANTIC_REGULAR = 1,
-  BRIG_SEMANTIC_ACQUIRE = 2,
-  BRIG_SEMANTIC_RELEASE = 3,
-  BRIG_SEMANTIC_ACQUIRE_RELEASE = 4,
-  BRIG_SEMANTIC_PARTIAL_ACQUIRE = 5,
-  BRIG_SEMANTIC_PARTIAL_RELEASE = 6,
-  BRIG_SEMANTIC_PARTIAL_ACQUIRE_RELEASE = 7
+typedef uint8_t BrigMemoryScope8_t;
+enum BrigMemoryScope {
+  BRIG_MEMORY_SCOPE_NONE = 0,
+  BRIG_MEMORY_SCOPE_WORKITEM = 1,
+  BRIG_MEMORY_SCOPE_WAVEFRONT = 2,
+  BRIG_MEMORY_SCOPE_WORKGROUP = 3,
+  BRIG_MEMORY_SCOPE_COMPONENT = 4,
+  BRIG_MEMORY_SCOPE_SYSTEM = 5
 };
 
 typedef uint16_t BrigOpcode16_t;
@@ -310,97 +340,104 @@  enum BrigOpcode {
   BRIG_OPCODE_COMBINE = 40,
   BRIG_OPCODE_EXPAND = 41,
   BRIG_OPCODE_LDA = 42,
-  BRIG_OPCODE_LDC = 43,
-  BRIG_OPCODE_MOV = 44,
-  BRIG_OPCODE_SHUFFLE = 45,
-  BRIG_OPCODE_UNPACKHI = 46,
-  BRIG_OPCODE_UNPACKLO = 47,
-  BRIG_OPCODE_PACK = 48,
-  BRIG_OPCODE_UNPACK = 49,
-  BRIG_OPCODE_CMOV = 50,
-  BRIG_OPCODE_CLASS = 51,
-  BRIG_OPCODE_NCOS = 52,
-  BRIG_OPCODE_NEXP2 = 53,
-  BRIG_OPCODE_NFMA = 54,
-  BRIG_OPCODE_NLOG2 = 55,
-  BRIG_OPCODE_NRCP = 56,
-  BRIG_OPCODE_NRSQRT = 57,
-  BRIG_OPCODE_NSIN = 58,
-  BRIG_OPCODE_NSQRT = 59,
-  BRIG_OPCODE_BITALIGN = 60,
-  BRIG_OPCODE_BYTEALIGN = 61,
-  BRIG_OPCODE_PACKCVT = 62,
-  BRIG_OPCODE_UNPACKCVT = 63,
-  BRIG_OPCODE_LERP = 64,
-  BRIG_OPCODE_SAD = 65,
-  BRIG_OPCODE_SADHI = 66,
-  BRIG_OPCODE_SEGMENTP = 67,
-  BRIG_OPCODE_FTOS = 68,
-  BRIG_OPCODE_STOF = 69,
-  BRIG_OPCODE_CMP = 70,
-  BRIG_OPCODE_CVT = 71,
-  BRIG_OPCODE_LD = 72,
-  BRIG_OPCODE_ST = 73,
-  BRIG_OPCODE_ATOMIC = 74,
-  BRIG_OPCODE_ATOMICNORET = 75,
-  BRIG_OPCODE_RDIMAGE = 76,
-  BRIG_OPCODE_LDIMAGE = 77,
-  BRIG_OPCODE_STIMAGE = 78,
-  BRIG_OPCODE_ATOMICIMAGE = 79,
-  BRIG_OPCODE_ATOMICIMAGENORET = 80,
-  BRIG_OPCODE_QUERYIMAGEARRAY = 81,
-  BRIG_OPCODE_QUERYIMAGEDEPTH = 82,
-  BRIG_OPCODE_QUERYIMAGEFORMAT = 83,
-  BRIG_OPCODE_QUERYIMAGEHEIGHT = 84,
-  BRIG_OPCODE_QUERYIMAGEORDER = 85,
-  BRIG_OPCODE_QUERYIMAGEWIDTH = 86,
-  BRIG_OPCODE_QUERYSAMPLERCOORD = 87,
-  BRIG_OPCODE_QUERYSAMPLERFILTER = 88,
-  BRIG_OPCODE_CBR = 89,
-  BRIG_OPCODE_BRN = 90,
-  BRIG_OPCODE_BARRIER = 91,
-  BRIG_OPCODE_ARRIVEFBAR = 92,
-  BRIG_OPCODE_INITFBAR = 93,
-  BRIG_OPCODE_JOINFBAR = 94,
-  BRIG_OPCODE_LEAVEFBAR = 95,
-  BRIG_OPCODE_RELEASEFBAR = 96,
-  BRIG_OPCODE_WAITFBAR = 97,
-  BRIG_OPCODE_LDF = 98,
-  BRIG_OPCODE_SYNC = 99,
-  BRIG_OPCODE_COUNTLANE = 100,
-  BRIG_OPCODE_COUNTUPLANE = 101,
-  BRIG_OPCODE_MASKLANE = 102,
-  BRIG_OPCODE_SENDLANE = 103,
-  BRIG_OPCODE_RECEIVELANE = 104,
-  BRIG_OPCODE_CALL = 105,
-  BRIG_OPCODE_RET = 106,
-  BRIG_OPCODE_SYSCALL = 107,
-  BRIG_OPCODE_ALLOCA = 108,
-  BRIG_OPCODE_CLEARDETECTEXCEPT = 109,
-  BRIG_OPCODE_CLOCK = 110,
-  BRIG_OPCODE_CUID = 111,
-  BRIG_OPCODE_CURRENTWORKGROUPSIZE = 112,
-  BRIG_OPCODE_DEBUGTRAP = 113,
-  BRIG_OPCODE_DIM = 114,
-  BRIG_OPCODE_DISPATCHID = 115,
-  BRIG_OPCODE_DISPATCHPTR = 116,
-  BRIG_OPCODE_GETDETECTEXCEPT = 117,
-  BRIG_OPCODE_GRIDGROUPS = 118,
-  BRIG_OPCODE_GRIDSIZE = 119,
-  BRIG_OPCODE_LANEID = 120,
-  BRIG_OPCODE_MAXCUID = 121,
-  BRIG_OPCODE_MAXWAVEID = 122,
-  BRIG_OPCODE_NULLPTR = 123,
-  BRIG_OPCODE_QID = 124,
-  BRIG_OPCODE_QPTR = 125,
-  BRIG_OPCODE_SETDETECTEXCEPT = 126,
-  BRIG_OPCODE_WAVEID = 127,
-  BRIG_OPCODE_WORKGROUPID = 128,
-  BRIG_OPCODE_WORKGROUPSIZE = 129,
-  BRIG_OPCODE_WORKITEMABSID = 130,
-  BRIG_OPCODE_WORKITEMFLATABSID = 131,
-  BRIG_OPCODE_WORKITEMFLATID = 132,
-  BRIG_OPCODE_WORKITEMID = 133
+  BRIG_OPCODE_MOV = 43,
+  BRIG_OPCODE_SHUFFLE = 44,
+  BRIG_OPCODE_UNPACKHI = 45,
+  BRIG_OPCODE_UNPACKLO = 46,
+  BRIG_OPCODE_PACK = 47,
+  BRIG_OPCODE_UNPACK = 48,
+  BRIG_OPCODE_CMOV = 49,
+  BRIG_OPCODE_CLASS = 50,
+  BRIG_OPCODE_NCOS = 51,
+  BRIG_OPCODE_NEXP2 = 52,
+  BRIG_OPCODE_NFMA = 53,
+  BRIG_OPCODE_NLOG2 = 54,
+  BRIG_OPCODE_NRCP = 55,
+  BRIG_OPCODE_NRSQRT = 56,
+  BRIG_OPCODE_NSIN = 57,
+  BRIG_OPCODE_NSQRT = 58,
+  BRIG_OPCODE_BITALIGN = 59,
+  BRIG_OPCODE_BYTEALIGN = 60,
+  BRIG_OPCODE_PACKCVT = 61,
+  BRIG_OPCODE_UNPACKCVT = 62,
+  BRIG_OPCODE_LERP = 63,
+  BRIG_OPCODE_SAD = 64,
+  BRIG_OPCODE_SADHI = 65,
+  BRIG_OPCODE_SEGMENTP = 66,
+  BRIG_OPCODE_FTOS = 67,
+  BRIG_OPCODE_STOF = 68,
+  BRIG_OPCODE_CMP = 69,
+  BRIG_OPCODE_CVT = 70,
+  BRIG_OPCODE_LD = 71,
+  BRIG_OPCODE_ST = 72,
+  BRIG_OPCODE_ATOMIC = 73,
+  BRIG_OPCODE_ATOMICNORET = 74,
+  BRIG_OPCODE_SIGNAL = 75,
+  BRIG_OPCODE_SIGNALNORET = 76,
+  BRIG_OPCODE_MEMFENCE = 77,
+  BRIG_OPCODE_RDIMAGE = 78,
+  BRIG_OPCODE_LDIMAGE = 79,
+  BRIG_OPCODE_STIMAGE = 80,
+  BRIG_OPCODE_QUERYIMAGE = 81,
+  BRIG_OPCODE_QUERYSAMPLER = 82,
+  BRIG_OPCODE_CBR = 83,
+  BRIG_OPCODE_BR = 84,
+  BRIG_OPCODE_SBR = 85,
+  BRIG_OPCODE_BARRIER = 86,
+  BRIG_OPCODE_WAVEBARRIER = 87,
+  BRIG_OPCODE_ARRIVEFBAR = 88,
+  BRIG_OPCODE_INITFBAR = 89,
+  BRIG_OPCODE_JOINFBAR = 90,
+  BRIG_OPCODE_LEAVEFBAR = 91,
+  BRIG_OPCODE_RELEASEFBAR = 92,
+  BRIG_OPCODE_WAITFBAR = 93,
+  BRIG_OPCODE_LDF = 94,
+  BRIG_OPCODE_ACTIVELANECOUNT = 95,
+  BRIG_OPCODE_ACTIVELANEID = 96,
+  BRIG_OPCODE_ACTIVELANEMASK = 97,
+  BRIG_OPCODE_ACTIVELANESHUFFLE = 98,
+  BRIG_OPCODE_CALL = 99,
+  BRIG_OPCODE_SCALL = 100,
+  BRIG_OPCODE_ICALL = 101,
+  BRIG_OPCODE_LDI = 102,
+  BRIG_OPCODE_RET = 103,
+  BRIG_OPCODE_ALLOCA = 104,
+  BRIG_OPCODE_CURRENTWORKGROUPSIZE = 105,
+  BRIG_OPCODE_DIM = 106,
+  BRIG_OPCODE_GRIDGROUPS = 107,
+  BRIG_OPCODE_GRIDSIZE = 108,
+  BRIG_OPCODE_PACKETCOMPLETIONSIG = 109,
+  BRIG_OPCODE_PACKETID = 110,
+  BRIG_OPCODE_WORKGROUPID = 111,
+  BRIG_OPCODE_WORKGROUPSIZE = 112,
+  BRIG_OPCODE_WORKITEMABSID = 113,
+  BRIG_OPCODE_WORKITEMFLATABSID = 114,
+  BRIG_OPCODE_WORKITEMFLATID = 115,
+  BRIG_OPCODE_WORKITEMID = 116,
+  BRIG_OPCODE_CLEARDETECTEXCEPT = 117,
+  BRIG_OPCODE_GETDETECTEXCEPT = 118,
+  BRIG_OPCODE_SETDETECTEXCEPT = 119,
+  BRIG_OPCODE_ADDQUEUEWRITEINDEX = 120,
+  BRIG_OPCODE_AGENTCOUNT = 121,
+  BRIG_OPCODE_AGENTID = 122,
+  BRIG_OPCODE_CASQUEUEWRITEINDEX = 123,
+  BRIG_OPCODE_LDK = 124,
+  BRIG_OPCODE_LDQUEUEREADINDEX = 125,
+  BRIG_OPCODE_LDQUEUEWRITEINDEX = 126,
+  BRIG_OPCODE_QUEUEID = 127,
+  BRIG_OPCODE_QUEUEPTR = 128,
+  BRIG_OPCODE_STQUEUEREADINDEX = 129,
+  BRIG_OPCODE_STQUEUEWRITEINDEX = 130,
+  BRIG_OPCODE_CLOCK = 131,
+  BRIG_OPCODE_CUID = 132,
+  BRIG_OPCODE_DEBUGTRAP = 133,
+  BRIG_OPCODE_GROUPBASEPTR = 134,
+  BRIG_OPCODE_KERNARGBASEPTR = 135,
+  BRIG_OPCODE_LANEID = 136,
+  BRIG_OPCODE_MAXCUID = 137,
+  BRIG_OPCODE_MAXWAVEID = 138,
+  BRIG_OPCODE_NULLPTR = 139,
+  BRIG_OPCODE_WAVEID = 140
 };
 
 typedef uint8_t BrigPack8_t;
@@ -426,6 +463,14 @@  enum BrigProfile {
   BRIG_PROFILE_FULL = 1
 };
 
+typedef uint16_t BrigRegisterKind16_t;
+enum BrigRegisterKind {
+  BRIG_REGISTER_CONTROL = 0,
+  BRIG_REGISTER_SINGLE = 1,
+  BRIG_REGISTER_DOUBLE = 2,
+  BRIG_REGISTER_QUAD = 3
+};
+
 typedef uint8_t BrigRound8_t;
 enum BrigRound {
   BRIG_ROUND_NONE = 0,
@@ -440,33 +485,63 @@  enum BrigRound {
   BRIG_ROUND_INTEGER_NEAR_EVEN_SAT = 9,
   BRIG_ROUND_INTEGER_ZERO_SAT = 10,
   BRIG_ROUND_INTEGER_PLUS_INFINITY_SAT = 11,
-  BRIG_ROUND_INTEGER_MINUS_INFINITY_SAT = 12
+  BRIG_ROUND_INTEGER_MINUS_INFINITY_SAT = 12,
+  BRIG_ROUND_INTEGER_SIGNALLING_NEAR_EVEN = 13,
+  BRIG_ROUND_INTEGER_SIGNALLING_ZERO = 14,
+  BRIG_ROUND_INTEGER_SIGNALLING_PLUS_INFINITY = 15,
+  BRIG_ROUND_INTEGER_SIGNALLING_MINUS_INFINITY = 16,
+  BRIG_ROUND_INTEGER_SIGNALLING_NEAR_EVEN_SAT = 17,
+  BRIG_ROUND_INTEGER_SIGNALLING_ZERO_SAT = 18,
+  BRIG_ROUND_INTEGER_SIGNALLING_PLUS_INFINITY_SAT = 19,
+  BRIG_ROUND_INTEGER_SIGNALLING_MINUS_INFINITY_SAT = 20
 };
 
-typedef uint8_t BrigSamplerBoundaryMode8_t;
-enum BrigSamplerBoundaryMode {
-  BRIG_BOUNDARY_CLAMP = 0,
-  BRIG_BOUNDARY_WRAP = 1,
-  BRIG_BOUNDARY_MIRROR = 2,
-  BRIG_BOUNDARY_MIRRORONCE = 3,
-  BRIG_BOUNDARY_BORDER = 4
+typedef uint8_t BrigSamplerAddressing8_t;
+enum BrigSamplerAddressing {
+  BRIG_ADDRESSING_UNDEFINED = 0,
+  BRIG_ADDRESSING_CLAMP_TO_EDGE = 1,
+  BRIG_ADDRESSING_CLAMP_TO_BORDER = 2,
+  BRIG_ADDRESSING_REPEAT = 3,
+  BRIG_ADDRESSING_MIRRORED_REPEAT = 4
 };
 
-enum BrigSamplerCoord {
-  BRIG_COORD_NORMALIZED = 0,
-  BRIG_COORD_UNNORMALIZED = 1
+typedef uint8_t BrigSamplerCoordNormalization8_t;
+enum BrigSamplerCoordNormalization {
+  BRIG_COORD_UNNORMALIZED = 0,
+  BRIG_COORD_NORMALIZED = 1
 };
 
+typedef uint8_t BrigSamplerFilter8_t;
 enum BrigSamplerFilter {
   BRIG_FILTER_NEAREST = 0,
   BRIG_FILTER_LINEAR = 1
 };
 
-typedef uint8_t BrigSamplerModifier8_t;
-enum BrigSamplerModifierMask {
-  BRIG_SAMPLER_FILTER = 63,
-  BRIG_SAMPLER_COORD = 64,
-  BRIG_SAMPLER_COORD_UNNORMALIZED = 64
+typedef uint8_t BrigSamplerQuery8_t;
+enum BrigSamplerQuery {
+  BRIG_SAMPLER_QUERY_ADDRESSING = 0,
+  BRIG_SAMPLER_QUERY_COORD = 1,
+  BRIG_SAMPLER_QUERY_FILTER = 2
+};
+
+typedef uint32_t BrigSectionIndex32_t;
+enum BrigSectionIndex {
+  BRIG_SECTION_INDEX_DATA = 0,
+  BRIG_SECTION_INDEX_CODE = 1,
+  BRIG_SECTION_INDEX_OPERAND = 2,
+  BRIG_SECTION_INDEX_BEGIN_IMPLEMENTATION_DEFINED = 3
+};
+
+struct BrigSectionHeader {
+  uint32_t byteCount;
+  uint32_t headerByteCount;
+  uint32_t nameLength;
+  uint8_t name[1];
+};
+
+typedef uint8_t BrigSegCvtModifier8_t;
+enum BrigSegCvtModifierMask {
+  BRIG_SEG_CVT_NONULL = 1
 };
 
 typedef uint8_t BrigSegment8_t;
@@ -482,15 +557,6 @@  enum BrigSegment {
   BRIG_SEGMENT_ARG = 8
 };
 
-typedef uint8_t BrigSymbolModifier8_t;
-enum BrigSymbolModifierMask {
-  BRIG_SYMBOL_LINKAGE = 3,
-  BRIG_SYMBOL_DECLARATION = 4,
-  BRIG_SYMBOL_CONST = 8,
-  BRIG_SYMBOL_ARRAY = 16,
-  BRIG_SYMBOL_FLEX_ARRAY = 32
-};
-
 enum {
   BRIG_TYPE_PACK_SHIFT = 5,
   BRIG_TYPE_BASE_MASK = (1 << BRIG_TYPE_PACK_SHIFT) - 1,
@@ -523,8 +589,10 @@  enum BrigType {
   BRIG_TYPE_B128 = 17,
   BRIG_TYPE_SAMP = 18,
   BRIG_TYPE_ROIMG = 19,
-  BRIG_TYPE_RWIMG = 20,
-  BRIG_TYPE_FBAR = 21,
+  BRIG_TYPE_WOIMG = 20,
+  BRIG_TYPE_RWIMG = 21,
+  BRIG_TYPE_SIG32 = 22,
+  BRIG_TYPE_SIG64 = 23,
   BRIG_TYPE_U8X4 = BRIG_TYPE_U8 | BRIG_TYPE_PACK_32,
   BRIG_TYPE_U8X8 = BRIG_TYPE_U8 | BRIG_TYPE_PACK_64,
   BRIG_TYPE_U8X16 = BRIG_TYPE_U8 | BRIG_TYPE_PACK_128,
@@ -551,15 +619,26 @@  enum BrigType {
   BRIG_TYPE_F64X2 = BRIG_TYPE_F64 | BRIG_TYPE_PACK_128
 };
 
+struct BrigUInt64 {
+  uint32_t lo;
+  uint32_t hi;
+};
+
+typedef uint8_t BrigVariableModifier8_t;
+enum BrigVariableModifierMask {
+  BRIG_SYMBOL_DECLARATION = 0,
+  BRIG_SYMBOL_DEFINITION = 1,
+  BRIG_SYMBOL_CONST = 2,
+  BRIG_SYMBOL_ARRAY = 4,
+  BRIG_SYMBOL_FLEX_ARRAY = 8
+};
+
+typedef uint32_t BrigVersion32_t;
 enum BrigVersion {
-  /* This is what spec says:
-  BRIG_VERSION_MAJOR = 0,
-  BRIG_VERSION_MINOR = 0
-  And this is actually expected by libHSAIL: */
   BRIG_VERSION_HSAIL_MAJOR = 0,
-  BRIG_VERSION_HSAIL_MINOR = 96,
+  BRIG_VERSION_HSAIL_MINOR = 99,
   BRIG_VERSION_BRIG_MAJOR = 0,
-  BRIG_VERSION_BRIG_MINOR = 1
+  BRIG_VERSION_BRIG_MINOR = 99
 };
 
 typedef uint8_t BrigWidth8_t;
@@ -579,7 +658,7 @@  enum BrigWidth {
   BRIG_WIDTH_2048 = 12,
   BRIG_WIDTH_4096 = 13,
   BRIG_WIDTH_8192 = 14,
-  BRIG_WIDTH_16364 = 15,
+  BRIG_WIDTH_16384 = 15,
   BRIG_WIDTH_32768 = 16,
   BRIG_WIDTH_65536 = 17,
   BRIG_WIDTH_131072 = 18,
@@ -601,293 +680,140 @@  enum BrigWidth {
   BRIG_WIDTH_ALL = 34
 };
 
-struct BrigSectionHeader {
-  uint32_t size;
-};
-
-struct BrigString {
+struct BrigData {
   uint32_t byteCount;
   uint8_t bytes[1];
 };
 
-struct BrigBlockEnd {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-};
-
-struct BrigBlockNumeric {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigType16_t type;
-  uint16_t reserved;
-  uint32_t elementCount;
-  BrigStringOffset32_t data;
-};
-
-struct BrigBlockStart {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  BrigStringOffset32_t name;
-};
-
-struct BrigBlockString {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigStringOffset32_t string;
-};
-
-struct BrigDirectiveBase {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-};
-
-struct BrigDirectiveCallableBase {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  BrigStringOffset32_t name;
-  uint16_t inArgCount;
-  uint16_t outArgCount;
+struct BrigBase {
+  uint16_t byteCount;
+  BrigKinds16_t kind;
 };
 
-struct BrigDirectiveArgScope {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
+struct BrigDirectiveArgBlock {
+  BrigBase base;
 };
 
 struct BrigDirectiveComment {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  BrigStringOffset32_t name;
+  BrigBase base;
+  BrigDataOffsetString32_t name;
 };
 
 struct BrigDirectiveControl {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
+  BrigBase base;
   BrigControlDirective16_t control;
-  BrigType16_t type;
   uint16_t reserved;
-  uint16_t valueCount;
-  BrigOperandOffset32_t values[1];
+  BrigDataOffsetOperandList32_t operands;
 };
 
 struct BrigDirectiveExecutable {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  BrigStringOffset32_t name;
-  uint16_t inArgCount;
+  BrigBase base;
+  BrigDataOffsetString32_t name;
   uint16_t outArgCount;
-  BrigDirectiveOffset32_t firstInArg;
-  BrigDirectiveOffset32_t firstScopedDirective;
-  BrigDirectiveOffset32_t nextTopLevelDirective;
-  uint32_t instCount;
+  uint16_t inArgCount;
+  BrigCodeOffset32_t firstInArg;
+  BrigCodeOffset32_t firstCodeBlockEntry;
+  BrigCodeOffset32_t nextModuleEntry;
+  uint32_t codeBlockEntryCount;
   BrigExecutableModifier8_t modifier;
-  uint8_t reserved[3];
+  BrigLinkage8_t linkage;
+  uint16_t reserved;
 };
 
 struct BrigDirectiveExtension {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  BrigStringOffset32_t name;
+  BrigBase base;
+  BrigDataOffsetString32_t name;
 };
 
 struct BrigDirectiveFbarrier {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  BrigStringOffset32_t name;
-};
-
-struct BrigDirectiveFile {
-   uint16_t size;
-   BrigDirectiveKinds16_t kind;
-   BrigCodeOffset32_t code;
-   uint32_t fileid;
-   BrigStringOffset32_t filename;
-};
-
-struct BrigDirectiveImageInit {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  uint32_t width;
-  uint32_t height;
-  uint32_t depth;
-  uint32_t array;
-  BrigImageOrder8_t order;
-  BrigImageFormat8_t format;
+  BrigBase base;
+  BrigDataOffsetString32_t name;
+  BrigExecutableModifier8_t modifier;
+  BrigLinkage8_t linkage;
   uint16_t reserved;
 };
 
 struct BrigDirectiveLabel {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  BrigStringOffset32_t name;
-};
-
-struct BrigDirectiveLabelList {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  BrigDirectiveOffset32_t label;
-  uint16_t labelCount;
-  uint16_t reserved;
-  BrigDirectiveOffset32_t labels[1];
+  BrigBase base;
+  BrigDataOffsetString32_t name;
 };
 
 struct BrigDirectiveLoc {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  uint32_t fileid;
+  BrigBase base;
+  BrigDataOffsetString32_t filename;
   uint32_t line;
   uint32_t column;
 };
 
+struct BrigDirectiveNone {
+  BrigBase base;
+};
+
 struct BrigDirectivePragma {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  BrigStringOffset32_t name;
-};
-
-struct BrigDirectiveSamplerInit {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigSamplerModifier8_t modifier;
-  BrigSamplerBoundaryMode8_t boundaryU;
-  BrigSamplerBoundaryMode8_t boundaryV;
-  BrigSamplerBoundaryMode8_t boundaryW;
-};
-
-struct BrigDirectiveSignature {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  BrigStringOffset32_t name;
-  uint16_t inArgCount;
-  uint16_t outArgCount;
-  struct {
-    BrigType16_t type;
-    uint8_t align;
-    BrigSymbolModifier8_t modifier;
-    uint32_t dimLo;
-    uint32_t dimHi;
-  } args[1];
-};
-
-struct BrigDirectiveSymbol {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  BrigStringOffset32_t name;
-  BrigDirectiveOffset32_t init;
-  BrigType16_t type;
-  BrigSegment8_t segment;
-  uint8_t align;
-  uint32_t dimLo;
-  uint32_t dimHi;
-  BrigSymbolModifier8_t modifier;
-  uint8_t reserved[3];
+  BrigBase base;
+  BrigDataOffsetOperandList32_t operands;
 };
 
-struct BrigDirectiveVariableInit {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  BrigStringOffset32_t data;
-  uint32_t elementCount;
+struct BrigDirectiveVariable {
+  BrigBase base;
+  BrigDataOffsetString32_t name;
+  BrigOperandOffset32_t init;
   BrigType16_t type;
-  uint16_t reserved;
+  BrigSegment8_t segment;
+  BrigAlignment8_t align;
+  BrigUInt64 dim;
+  BrigVariableModifier8_t modifier;
+  BrigLinkage8_t linkage;
+  BrigAllocation8_t allocation;
+  uint8_t reserved;
 };
 
 struct BrigDirectiveVersion {
-  uint16_t size;
-  BrigDirectiveKinds16_t kind;
-  BrigCodeOffset32_t code;
-  /* Spec says:
-  uint16_t major;
-  uint16_t minor;
-     but libHSAIL actually wants: */
-  uint32_t hsailMajor;
-  uint32_t hsailMinor;
-  uint32_t brigMajor;
-  uint32_t brigMinor;
-  /* This is the same as the spec: */
+  BrigBase base;
+  BrigVersion32_t hsailMajor;
+  BrigVersion32_t hsailMinor;
+  BrigVersion32_t brigMajor;
+  BrigVersion32_t brigMinor;
   BrigProfile8_t profile;
   BrigMachineModel8_t machineModel;
   uint16_t reserved;
 };
 
-struct BrigInstAtomic {
-  uint16_t size;
-  BrigInstKinds16_t kind;
+struct BrigInstBase {
+  BrigBase base;
   BrigOpcode16_t opcode;
   BrigType16_t type;
-  BrigOperandOffset32_t operands[5];
-  BrigSegment8_t segment;
-  BrigMemorySemantic8_t memorySemantic;
-  BrigAtomicOperation8_t atomicOperation;
-  int8_t reserved;
+  BrigDataOffsetOperandList32_t operands;
 };
 
-struct BrigInstAtomicImage {
-  uint16_t size;
-  BrigInstKinds16_t kind;
-  BrigOpcode16_t opcode;
-  BrigType16_t type;
-  BrigOperandOffset32_t operands[5];
-  BrigType16_t imageType;
-  BrigType16_t coordType;
-  BrigImageGeometry8_t geometry;
-  BrigAtomicOperation8_t atomicOperation;
-  uint16_t reserved;
+struct BrigInstAddr {
+  BrigInstBase base;
+  BrigSegment8_t segment;
+  uint8_t reserved[3];
 };
 
-struct BrigInstBar {
-  uint16_t size;
-  BrigInstKinds16_t kind;
-  BrigOpcode16_t opcode;
-  BrigType16_t type;
-  BrigOperandOffset32_t operands[5];
-  BrigMemoryFence8_t memoryFence;
-  BrigWidth8_t width;
-  uint16_t reserved;
+struct BrigInstAtomic {
+  BrigInstBase base;
+  BrigSegment8_t segment;
+  BrigMemoryOrder8_t memoryOrder;
+  BrigMemoryScope8_t memoryScope;
+  BrigAtomicOperation8_t atomicOperation;
+  uint8_t equivClass;
+  uint8_t reserved[3];
 };
 
 struct BrigInstBasic {
-  uint16_t size;
-  BrigInstKinds16_t kind;
-  BrigOpcode16_t opcode;
-  BrigType16_t type;
-  BrigOperandOffset32_t operands[5];
+  BrigInstBase base;
 };
 
-struct BrigInstMod {
-  uint16_t size;
-  BrigInstKinds16_t kind;
-  BrigOpcode16_t opcode;
-  BrigType16_t type;
-  BrigOperandOffset32_t operands[5];
-  BrigAluModifier16_t modifier;
-  BrigPack8_t pack;
-  uint8_t reserved;
+struct BrigInstBr {
+  BrigInstBase base;
+  BrigWidth8_t width;
+  uint8_t reserved[3];
 };
 
 struct BrigInstCmp {
-  uint16_t size;
-  BrigInstKinds16_t kind;
-  BrigOpcode16_t opcode;
-  BrigType16_t type;
-  BrigOperandOffset32_t operands[5];
+  BrigInstBase base;
   BrigType16_t sourceType;
   BrigAluModifier16_t modifier;
   BrigCompareOperation8_t compare;
@@ -896,210 +822,163 @@  struct BrigInstCmp {
 };
 
 struct BrigInstCvt {
-  uint16_t size;
-  BrigInstKinds16_t kind;
-  BrigOpcode16_t opcode;
-  BrigType16_t type;
-  BrigOperandOffset32_t operands[5];
+  BrigInstBase base;
   BrigType16_t sourceType;
   BrigAluModifier16_t modifier;
 };
 
 struct BrigInstImage {
-  uint16_t size;
-  BrigInstKinds16_t kind;
-  BrigOpcode16_t opcode;
-  BrigType16_t type;
-  BrigOperandOffset32_t operands[5];
+  BrigInstBase base;
   BrigType16_t imageType;
   BrigType16_t coordType;
   BrigImageGeometry8_t geometry;
-  uint8_t reserved[3];
-};
-
-struct BrigInstMem {
-  uint16_t size;
-  BrigInstKinds16_t kind;
-  BrigOpcode16_t opcode;
-  BrigType16_t type;
-  BrigOperandOffset32_t operands[5];
-  BrigSegment8_t segment;
-  BrigMemoryModifier8_t modifier;
   uint8_t equivClass;
-  BrigWidth8_t width;
-};
-
-struct BrigInstAddr {
-  uint16_t size;
-  BrigInstKinds16_t kind;
-  BrigOpcode16_t opcode;
-  BrigType16_t type;
-  BrigOperandOffset32_t operands[5];
-  BrigSegment8_t segment;
-  uint8_t reserved[3];
-};
-
-struct BrigInstSourceType {
-  uint16_t size;
-  BrigInstKinds16_t kind;
-  BrigOpcode16_t opcode;
-  BrigType16_t type;
-  BrigOperandOffset32_t operands[5];
-  BrigType16_t sourceType;
   uint16_t reserved;
 };
 
-struct BrigInstSeg {
-  uint16_t size;
-  BrigInstKinds16_t kind;
-  BrigOpcode16_t opcode;
-  BrigType16_t type;
-  BrigOperandOffset32_t operands[5];
+struct BrigInstLane {
+  BrigInstBase base;
   BrigType16_t sourceType;
-  BrigSegment8_t segment;
+  BrigWidth8_t width;
   uint8_t reserved;
 };
 
-struct BrigInstFbar {
-  uint16_t size;
-  BrigInstKinds16_t kind;
-  BrigOpcode16_t opcode;
-  BrigType16_t type;
-  BrigOperandOffset32_t operands[5];
-  BrigMemoryFence8_t memoryFence;
+struct BrigInstMem {
+  BrigInstBase base;
+  BrigSegment8_t segment;
+  BrigAlignment8_t align;
+  uint8_t equivClass;
   BrigWidth8_t width;
-  uint16_t reserved;
+  BrigMemoryModifier8_t modifier;
+  uint8_t reserved[3];
 };
 
-struct BrigInstBr {
-  uint16_t size;
-  BrigInstKinds16_t kind;
-  BrigOpcode16_t opcode;
-  BrigType16_t type;
-  BrigOperandOffset32_t operands[5];
-  BrigAluModifier16_t modifier;
-  BrigWidth8_t width;
-  uint8_t reserved;
+struct BrigInstMemFence {
+  BrigInstBase base;
+  BrigMemoryOrder8_t memoryOrder;
+  BrigMemoryScope8_t globalSegmentMemoryScope;
+  BrigMemoryScope8_t groupSegmentMemoryScope;
+  BrigMemoryScope8_t imageSegmentMemoryScope;
 };
 
-struct BrigInstNone {
-  uint16_t size;
-  BrigInstKinds16_t kind;
+struct BrigInstMod {
+  BrigInstBase base;
+  BrigAluModifier16_t modifier;
+  BrigPack8_t pack;
+  uint8_t reserved;
 };
 
-struct BrigOperandBase {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
+struct BrigInstQueryImage {
+  BrigInstBase base;
+  BrigType16_t imageType;
+  BrigImageGeometry8_t geometry;
+  BrigImageQuery8_t query;
 };
 
-struct BrigOperand {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
+struct BrigInstQuerySampler {
+  BrigInstBase base;
+  BrigSamplerQuery8_t query;
+  uint8_t reserved[3];
 };
 
-struct BrigOperandAddress {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
-  BrigDirectiveOffset32_t symbol;
-  BrigStringOffset32_t reg;
-  uint32_t offsetLo;
-  uint32_t offsetHi;
-  BrigType16_t type;
+struct BrigInstQueue {
+  BrigInstBase base;
+  BrigSegment8_t segment;
+  BrigMemoryOrder8_t memoryOrder;
   uint16_t reserved;
 };
 
-struct BrigOperandList {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
-  uint16_t elementCount;
-  uint16_t reserved;
-  BrigDirectiveOffset32_t elements[1];
+struct BrigInstSeg {
+  BrigInstBase base;
+  BrigSegment8_t segment;
+  uint8_t reserved[3];
 };
 
-struct BrigOperandArgumentList {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
-  uint16_t elementCount;
-  uint16_t reserved;
-  BrigDirectiveOffset32_t elements[1];
+struct BrigInstSegCvt {
+  BrigInstBase base;
+  BrigType16_t sourceType;
+  BrigSegment8_t segment;
+  BrigSegCvtModifier8_t modifier;
 };
 
+struct BrigInstSignal {
+  BrigInstBase base;
+  BrigType16_t signalType;
+  BrigMemoryOrder8_t memoryOrder;
+  BrigAtomicOperation8_t signalOperation;
+};
 
-struct BrigOperandFunctionList {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
-  uint16_t elementCount;
+struct BrigInstSourceType {
+  BrigInstBase base;
+  BrigType16_t sourceType;
   uint16_t reserved;
-  BrigDirectiveOffset32_t elements[1];
 };
 
-struct BrigOperandRef {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
-  BrigDirectiveOffset32_t ref;
+struct BrigOperandAddress {
+  BrigBase base;
+  BrigCodeOffset32_t symbol;
+  BrigOperandOffset32_t reg;
+  BrigUInt64 offset;
 };
 
-struct BrigOperandLabelRef {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
-  BrigDirectiveOffset32_t ref;
+struct BrigOperandCodeList {
+  BrigBase base;
+  BrigDataOffsetCodeList32_t elements;
 };
 
-struct BrigOperandArgumentRef {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
-  BrigDirectiveOffset32_t ref;
+struct BrigOperandCodeRef {
+  BrigBase base;
+  BrigCodeOffset32_t ref;
 };
 
-struct BrigOperandFunctionRef {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
-  BrigDirectiveOffset32_t ref;
+struct BrigOperandData {
+  BrigBase base;
+  BrigDataOffset32_t data;
 };
 
-struct BrigOperandSignatureRef {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
-  BrigDirectiveOffset32_t ref;
+struct BrigOperandImageProperties {
+  BrigBase base;
+  uint64_t width;
+  uint64_t height;
+  uint64_t depth;
+  uint64_t array;
+  BrigImageGeometry8_t geometry;
+  BrigImageChannelOrder8_t channelOrder;
+  BrigImageChannelType8_t channelType;
+  uint8_t reserved;
 };
 
-struct BrigOperandFbarrierRef {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
-  BrigDirectiveOffset32_t ref;
+struct BrigOperandOperandList {
+  BrigBase base;
+  BrigDataOffsetOperandList32_t elements;
 };
 
-struct BrigOperandImmed {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
-  BrigType16_t type;
-  uint16_t byteCount;
-  uint8_t bytes[1];
+struct BrigOperandReg {
+  BrigBase base;
+  BrigRegisterKind16_t regKind;
+  uint16_t regNum;
 };
 
-struct BrigOperandReg {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
-  BrigStringOffset32_t reg;
-  BrigType16_t type;
-  uint16_t reserved;
+struct BrigOperandSamplerProperties {
+  BrigBase base;
+  BrigSamplerCoordNormalization8_t coord;
+  BrigSamplerFilter8_t filter;
+  BrigSamplerAddressing8_t addressing;
+  uint8_t reserved;
 };
 
-struct BrigOperandRegVector {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
-  BrigType16_t type;
-  uint16_t regCount;
-  BrigStringOffset32_t regs[1];
+struct BrigOperandString {
+  BrigBase base;
+  BrigDataOffsetString32_t string;
 };
 
 struct BrigOperandWavesize {
-  uint16_t size;
-  BrigOperandKinds16_t kind;
-  BrigType16_t type;
-  uint16_t reserved;
+  BrigBase base;
 };
 
-
+struct BrigModule {
+  uint32_t sectionCount;
+  BrigSectionHeader* section[1];
+};
 
 #endif /* HSA_BRIG_FORMAT_H */
diff --git a/gcc/hsa-brig.c b/gcc/hsa-brig.c
index 0f0b1b0..ca213b8 100644
--- a/gcc/hsa-brig.c
+++ b/gcc/hsa-brig.c
@@ -32,11 +32,9 @@  along with GCC; see the file COPYING3.  If not see
 #include "gimple-pretty-print.h"
 #include "diagnostic-core.h"
 
-#define BRIG_SECTION_STRING_NAME ".brig_strtab"
-#define BRIG_SECTION_DIRECTIVE_NAME ".brig_directives"
-#define BRIG_SECTION_CODE_NAME ".brig_code"
-#define BRIG_SECTION_OPERAND_NAME ".brig_operands"
-#define BRIG_SECTION_DEBUG_NAME ".brig_debug"
+#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)
 
@@ -60,8 +58,10 @@  struct hsa_brig_data_chunk
 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;
+  unsigned total_size, header_byte_count;
 
   /* Buffers of binary data, each containing BRIG_CHUNK_MAX_SIZE bytes.  */
   vec <struct hsa_brig_data_chunk> chunks;
@@ -70,17 +70,15 @@  public:
   struct hsa_brig_data_chunk *cur_chunk;
 
   void allocate_new_chunk ();
-  void init ();
+  void init (const char *name);
   void release ();
-  void output (const char *section_name);
+  void output ();
   unsigned add (const void *data, unsigned len);
   void round_size_up (int factor);
 };
 
-static struct hsa_brig_section brig_string, brig_directive, brig_code;
-static struct hsa_brig_section brig_operand, brig_debug;
+static struct hsa_brig_section brig_data, brig_code, brig_operand;
 static uint32_t brig_insn_count;
-
 static bool brig_initialized = false;
 
 /* Add a new chunk, allocate data for it and initialize it.  */
@@ -98,11 +96,19 @@  hsa_brig_section::allocate_new_chunk ()
 /* Initialize the brig section.  */
 
 void
-hsa_brig_section::init ()
+hsa_brig_section::init (const char *name)
 {
-  total_size = sizeof (struct BrigSectionHeader);
+  struct BrigSectionHeader sample;
+
+  section_name = name;
+  total_size = sizeof(sample.byteCount) + sizeof(sample.headerByteCount)
+        + sizeof(sample.nameLength);
+  /* Add strlen + null termination to the section size*/
+  total_size = total_size + strlen(section_name) + 1;
   chunks.create (1);
   allocate_new_chunk ();
+  round_size_up (4);
+  header_byte_count = total_size;
 }
 
 /* Free all data in the section.  */
@@ -116,19 +122,21 @@  hsa_brig_section::release ()
   cur_chunk = NULL;
 }
 
-/* Write the section to the output file to a section called SECTION_NAME.
-   Switches the output section and does not restore it. */
+/* 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 (const char *section_name)
+hsa_brig_section::output ()
 {
   struct BrigSectionHeader section_header;
 
   switch_to_section (get_section (section_name, SECTION_NOTYPE, NULL));
 
-  section_header.size = htole32 (total_size);
-  assemble_string ((const char *)&section_header, sizeof (section_header));
-
+  section_header.byteCount = htole32 (total_size);
+  section_header.nameLength = htole32 (strlen(section_name));
+  section_header.headerByteCount = htole32 (header_byte_count);
+  assemble_string ((const char*) &section_header, 12);
+  assemble_string (section_name, (section_header.nameLength + 1));
   for (unsigned i = 0; i < chunks.length (); i++)
     assemble_string (chunks[i].data, chunks[i].size);
 }
@@ -174,7 +182,7 @@  hsa_brig_section::round_size_up (int factor)
   cur_chunk->size += padding;
 }
 
-/* BRIG String hashing.  */
+/* BRIG string data hashing.  */
 
 struct brig_string_slot
 {
@@ -237,8 +245,8 @@  sanitize_hsa_name (char *p)
       *p = '_';
 }
 
-/* Emit a null terminated string STR to the string section and return its
-   offset in it.  */
+/* 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.  */
 
 static unsigned
 brig_emit_string (const char *str, char prefix = 0)
@@ -263,14 +271,14 @@  brig_emit_string (const char *str, char prefix = 0)
     {
       brig_string_slot *new_slot = XCNEW (brig_string_slot);
 
-      /* In theory we should fill in struct BrigString and stream that but that
-	 would mean copying the string to a buffer for no good reason, so we
-	 just emaulate it.   */
-      offset = brig_string.add (&hdr_len, sizeof (hdr_len));
+      /* In theory we should fill in BrigData but that would mean copying
+         the string to a buffer for no reason, so we just emaulate it. */
+      offset = brig_data.add (&hdr_len, sizeof (hdr_len));
       if (prefix)
-	brig_string.add (&prefix, 1);
-      brig_string.add (str2, slen);
-      brig_string.round_size_up (4);
+        brig_data.add (&prefix, 1);
+
+      brig_data.add (str2, slen);
+      brig_data.round_size_up (4);
 
       /* XXX could use the string we just copied into brig_string->cur_chunk */
       new_slot->s = str2;
@@ -300,46 +308,26 @@  static struct operand_queue
 
 } op_queue;
 
-/* Offsets of corresponding register names so that we don't have to generate
-   them repeatedly.  */
-static unsigned c_reg_names[HSA_C_REGISTER_COUNT];
-static unsigned s_reg_names[HSA_S_REGISTER_COUNT];
-static unsigned d_reg_names[HSA_D_REGISTER_COUNT];
-static unsigned q_reg_names[HSA_Q_REGISTER_COUNT];
-/* Offsets of operands describing registers so that we don't generate them
-   repeatadly.  */
-static unsigned c_regs[HSA_C_REGISTER_COUNT];
-static unsigned s_regs[HSA_S_REGISTER_COUNT];
-static unsigned d_regs[HSA_D_REGISTER_COUNT];
-static unsigned q_regs[HSA_Q_REGISTER_COUNT];
-
-
-/* unless already initialized, Initialzie infrastructure to produce BRIG.  */
+/* Unless already initialized, initialzie infrastructure to produce BRIG.  */
 
 static void
 brig_init (void)
 {
   struct BrigDirectiveVersion verdir;
-
   brig_insn_count = 0;
 
   if (brig_initialized)
     return;
 
   brig_string_htab = new hash_table<brig_string_slot_hasher> (37);
-  brig_string.init ();
-  brig_directive.init ();
-  brig_code.init ();
-  brig_operand.init ();
-  brig_debug.init ();
-
-  verdir.size = htole16 (sizeof (verdir));
-  verdir.kind = htole16 (BRIG_DIRECTIVE_VERSION);
-  verdir.code = htole32 (brig_code.total_size);
-  /*verdir.major = htole16 (BRIG_VERSION_MAJOR);
-  verdir.minor = htole16 (BRIG_VERSION_MINOR);*/
-  verdir.hsailMajor = htole32 (BRIG_VERSION_HSAIL_MAJOR);
-  verdir.hsailMinor = htole32 (BRIG_VERSION_HSAIL_MINOR);
+  brig_data.init (BRIG_SECTION_DATA_NAME);
+  brig_code.init (BRIG_SECTION_CODE_NAME);
+  brig_operand.init (BRIG_SECTION_OPERAND_NAME);
+
+  verdir.base.byteCount = htole16 (sizeof (verdir));
+  verdir.base.kind = htole16 (BRIG_KIND_DIRECTIVE_VERSION);
+  verdir.hsailMajor = htole32 (BRIG_VERSION_HSAIL_MAJOR) ;
+  verdir.hsailMinor =  htole32 (BRIG_VERSION_HSAIL_MINOR);
   verdir.brigMajor = htole32 (BRIG_VERSION_BRIG_MAJOR);
   verdir.brigMinor = htole32 (BRIG_VERSION_BRIG_MINOR);
   verdir.profile = hsa_full_profile_p () ? BRIG_PROFILE_FULL: BRIG_PROFILE_BASE;
@@ -348,8 +336,7 @@  brig_init (void)
   else
     verdir.machineModel = BRIG_MACHINE_SMALL;
   verdir.reserved = 0;
-  brig_directive.add (&verdir, sizeof (verdir));
-
+  brig_code.add (&verdir, sizeof (verdir));
   brig_initialized = true;
 }
 
@@ -359,22 +346,43 @@  static void
 brig_release_data (void)
 {
   delete brig_string_htab;
-  brig_string.release ();
-  brig_directive.release ();
+  brig_data.release ();
   brig_code.release ();
   brig_operand.release ();
-  brig_debug.release ();
 
   brig_initialized = 0;
 }
 
+/* Find the alignment base on the type.  */
+
+static BrigAlignment8_t
+get_alignment (BrigType16_t type)
+{
+  BrigType16_t bit_type ;
+  bit_type = bittype_for_type (type) ;
+
+  if (bit_type == BRIG_TYPE_B1)
+    return BRIG_ALIGNMENT_1;
+  if (bit_type == BRIG_TYPE_B8)
+    return BRIG_ALIGNMENT_1;
+  if (bit_type == BRIG_TYPE_B16)
+    return BRIG_ALIGNMENT_2;
+  if (bit_type == BRIG_TYPE_B32)
+    return BRIG_ALIGNMENT_4;
+  if (bit_type == BRIG_TYPE_B64)
+    return BRIG_ALIGNMENT_8;
+  if (bit_type == BRIG_TYPE_B128)
+    return BRIG_ALIGNMENT_16;
+  gcc_unreachable ();
+}
+
 /* Emit directive describing a symbol if it has not been emitted already.
    Return the offset of the directive.  */
 
 static unsigned
-emit_symbol_directive (struct hsa_symbol *symbol)
+emit_directive_variable (struct hsa_symbol *symbol)
 {
-  struct BrigDirectiveSymbol symdir;
+  struct BrigDirectiveVariable dirvar;
   unsigned name_offset;
   static unsigned res_name_offset;
   char prefix;
@@ -382,13 +390,14 @@  emit_symbol_directive (struct hsa_symbol *symbol)
   if (symbol->offset)
     return symbol->offset;
 
-  symdir.size = htole16 (sizeof (symdir));
-  symdir.kind = htole16 (BRIG_DIRECTIVE_VARIABLE);
-  symdir.code = htole32 (brig_code.total_size);
+  dirvar.base.byteCount = htole16 (sizeof (dirvar));
+  dirvar.base.kind = htole16 (BRIG_KIND_DIRECTIVE_VARIABLE);
+  dirvar.allocation = BRIG_ALLOCATION_AUTOMATIC;
 
   if (symbol->decl && is_global_var (symbol->decl))
     {
       prefix = '&';
+      dirvar.allocation = BRIG_ALLOCATION_PROGRAM ;
       if (TREE_CODE (symbol->decl) == VAR_DECL)
 	warning (0, "referring to global symbol %q+D by name from HSA code won't work", symbol->decl);
     }
@@ -400,6 +409,7 @@  emit_symbol_directive (struct hsa_symbol *symbol)
       if (res_name_offset == 0)
 	res_name_offset = brig_emit_string (symbol->name, '%');
       name_offset = res_name_offset;
+      dirvar.allocation = BRIG_ALLOCATION_NONE;
     }
   else if (symbol->name)
     name_offset = brig_emit_string (symbol->name, prefix);
@@ -411,19 +421,18 @@  emit_symbol_directive (struct hsa_symbol *symbol)
       name_offset = brig_emit_string (buf, prefix);
     }
 
-  symdir.name = htole32 (name_offset);
-  symdir.init = 0;
-  symdir.type = htole16 (symbol->type);
-  symdir.segment = symbol->segment;
-  /* FIXME: For now assume natural alignment.  */
-  symdir.align = 0;
-  symdir.dimLo = htole32 (symbol->dimLo);
-  symdir.dimHi = htole32 (symbol->dimHi);
-  symdir.modifier = 0;
-  if (symbol->segment == BRIG_SEGMENT_KERNARG)
-    symdir.modifier = BRIG_SYMBOL_DECLARATION;
-  memset (&symdir.reserved, 0, sizeof (symdir.reserved));
-  symbol->offset = brig_directive.add (&symdir, sizeof (symdir));
+  dirvar.name = htole32 (name_offset);
+  dirvar.init = 0;
+  dirvar.type = htole16 (symbol->type);
+  dirvar.segment = symbol->segment;
+  dirvar.align = get_alignment (dirvar.type);
+  dirvar.linkage = BRIG_LINKAGE_FUNCTION ;
+  dirvar.dim.lo = htole32 (symbol->dimLo);
+  dirvar.dim.hi = htole32 (symbol->dimHi);
+  dirvar.modifier = BRIG_SYMBOL_DEFINITION;
+  dirvar.reserved = 0;
+
+  symbol->offset = brig_code.add (&dirvar, sizeof (dirvar));
   return symbol->offset;
 }
 
@@ -440,10 +449,10 @@  emit_function_directives (void)
   hsa_symbol *sym;
 
   name_offset = brig_emit_string (hsa_cfun.name, '&');
-  inarg_off = brig_directive.total_size + sizeof(fndir)
-    + (hsa_cfun.output_arg ? sizeof (struct BrigDirectiveSymbol) : 0);
+  inarg_off = brig_code.total_size + sizeof(fndir)
+    + (hsa_cfun.output_arg ? sizeof (struct BrigDirectiveVariable) : 0);
   scoped_off = inarg_off
-    + hsa_cfun.input_args_count * sizeof (struct BrigDirectiveSymbol);
+    + hsa_cfun.input_args_count * sizeof (struct BrigDirectiveVariable);
   for (hash_table <hsa_noop_symbol_hasher>::iterator iter
 	 = hsa_cfun.local_symbols->begin ();
        iter != hsa_cfun.local_symbols->end ();
@@ -452,43 +461,47 @@  emit_function_directives (void)
       count++;
   count += hsa_cfun.spill_symbols.length();
 
-  next_toplev_off = scoped_off + count * sizeof (struct BrigDirectiveSymbol);
+  next_toplev_off = scoped_off + count * sizeof (struct BrigDirectiveVariable);
 
-  fndir.size = htole16 (sizeof (fndir));
-  fndir.kind = htole16 (BRIG_DIRECTIVE_KERNEL);
-  fndir.code = htole32 (brig_code.total_size);
+  fndir.base.byteCount = htole16 (sizeof (fndir));
+  fndir.base.kind = htole16 (BRIG_KIND_DIRECTIVE_KERNEL);
   fndir.name = htole32 (name_offset);
   fndir.inArgCount = htole16 (hsa_cfun.input_args_count);
   fndir.outArgCount = htole16 (hsa_cfun.output_arg ? 1 : 0);
   fndir.firstInArg = htole32 (inarg_off);
-  fndir.firstScopedDirective = htole32 (scoped_off);
-  fndir.nextTopLevelDirective = htole32 (next_toplev_off);
-  fndir.instCount = htole32 (0);
-  fndir.modifier = 0;
+  fndir.firstCodeBlockEntry = htole32 (scoped_off);
+  fndir.nextModuleEntry = htole32 (next_toplev_off);
+  fndir.linkage = BRIG_LINKAGE_PROGRAM;
+  fndir.codeBlockEntryCount = htole32 (0);
+  fndir.modifier = BRIG_EXECUTABLE_DEFINITION;
   memset (&fndir.reserved, 0, sizeof (fndir.reserved));
-  brig_directive.add (&fndir, sizeof (fndir));
+
+  brig_code.add (&fndir, sizeof (fndir));
   /* XXX terrible hack: we need to set instCount after we emit all
      insns, but we need to emit directive in order, and we emit directives
-     during insn emitting.  So we need to emit the FUNCTION directive 
+     during insn emitting.  So we need to emit the FUNCTION directive
      early, then the insns, and then we need to set instCount, so remember
      a pointer to it, in some horrible way.  cur_chunk.data+size points
      directly to after fndir here.  */
   ptr_to_fndir
-      = (BrigDirectiveExecutable *)(brig_directive.cur_chunk->data
-				    + brig_directive.cur_chunk->size
-				    - sizeof (fndir));
+      = (BrigDirectiveExecutable *)(brig_code.cur_chunk->data
+                                    + brig_code.cur_chunk->size
+                                    - sizeof (fndir));
 
   if (hsa_cfun.output_arg)
-    emit_symbol_directive (hsa_cfun.output_arg);
+    emit_directive_variable(hsa_cfun.output_arg);
   for (int i = 0; i < hsa_cfun.input_args_count; i++)
-    emit_symbol_directive (&hsa_cfun.input_args[i]);
+    emit_directive_variable(&hsa_cfun.input_args[i]);
   for (hash_table <hsa_noop_symbol_hasher>::iterator iter
 	 = hsa_cfun.local_symbols->begin ();
        iter != hsa_cfun.local_symbols->end ();
        ++iter)
-    emit_symbol_directive (*iter);
+    emit_directive_variable(*iter);
   for (int i = 0; hsa_cfun.spill_symbols.iterate (i, &sym); i++)
-    emit_symbol_directive (sym);
+    {
+      emit_directive_variable (sym);
+      brig_insn_count++;
+    }
   return ptr_to_fndir;
 }
 
@@ -501,13 +514,13 @@  emit_bb_label_directive (hsa_bb *hbb)
   struct BrigDirectiveLabel lbldir;
   char buf[32];
 
-  lbldir.size = htole16 (sizeof (lbldir));
-  lbldir.kind = htole16 (BRIG_DIRECTIVE_LABEL);
-  lbldir.code = htole32 (brig_code.total_size);
+  lbldir.base.byteCount = htole16 (sizeof (lbldir));
+  lbldir.base.kind = htole16 (BRIG_KIND_DIRECTIVE_LABEL);
   sprintf (buf, "BB_%u_%i", DECL_UID (current_function_decl), hbb->index);
   lbldir.name = htole32 (brig_emit_string (buf, '@'));
-  hbb->label_ref.directive_offset = brig_directive.add (&lbldir,
-							sizeof (lbldir));
+
+  hbb->label_ref.directive_offset = brig_code.add (&lbldir, sizeof (lbldir));
+  brig_insn_count++;
 }
 
 BrigType16_t
@@ -574,6 +587,7 @@  bittype_for_type (BrigType16_t t)
       return t;
     }
 }
+
 /* Map a normal HSAIL type to the type of the equivalent BRIG operand
    holding such, for constants and registers.  */
 
@@ -647,28 +661,6 @@  enqueue_op (hsa_op_base *op)
   if (op->offset)
     return op->offset;
 
-  if (hsa_op_reg *reg = dyn_cast <hsa_op_reg *> (op))
-    {
-      unsigned *cache;
-      if (reg->reg_class == 'c')
-	cache = &c_regs[(int) reg->hard_num];
-      else if (reg->reg_class == 's')
-	cache = &s_regs[(int) reg->hard_num];
-      else if (reg->reg_class == 'd')
-	cache = &d_regs[(int) reg->hard_num];
-      else if (reg->reg_class == 'q')
-	cache = &q_regs[(int) reg->hard_num];
-      else
-	gcc_unreachable ();
-
-      if (*cache)
-	{
-	  op->offset = *cache;
-	  return *cache;
-	}
-      *cache = op_queue.projected_size;
-    }
-
   ret = op_queue.projected_size;
   op->offset = op_queue.projected_size;
 
@@ -678,64 +670,29 @@  enqueue_op (hsa_op_base *op)
     op_queue.last_op->next = op;
   op_queue.last_op = op;
 
-  if (hsa_op_immed *imm = dyn_cast <hsa_op_immed *> (op))
-    {
-      unsigned len = 8;
-      switch (imm->type)
-	{
-	case BRIG_TYPE_U8:
-	case BRIG_TYPE_S8:
-	  len += 1;
-	  break;
-	case BRIG_TYPE_U16:
-	case BRIG_TYPE_S16:
-	case BRIG_TYPE_F16:
-	  len += 2;
-	  break;
-	case BRIG_TYPE_U32:
-	case BRIG_TYPE_S32:
-	case BRIG_TYPE_F32:
-	case BRIG_TYPE_U8X4:
-	case BRIG_TYPE_S8X4:
-	case BRIG_TYPE_U16X2:
-	case BRIG_TYPE_S16X2:
-	case BRIG_TYPE_F16X2:
-	  len += 4;
-	  break;
-	case BRIG_TYPE_U64:
-	case BRIG_TYPE_S64:
-	case BRIG_TYPE_F64:
-	case BRIG_TYPE_U8X8:
-	case BRIG_TYPE_S8X8:
-	case BRIG_TYPE_U16X4:
-	case BRIG_TYPE_S16X4:
-	case BRIG_TYPE_F16X4:
-	case BRIG_TYPE_U32X2:
-	case BRIG_TYPE_S32X2:
-	case BRIG_TYPE_F32X2:
-	  len += 8;
-	  break;
-	default:
-	  gcc_unreachable ();
-	}
-      op_queue.projected_size += ((len + 3) / 4) * 4;
-    }
+  if (is_a <hsa_op_immed *> (op))
+    op_queue.projected_size += sizeof (struct BrigOperandData);
   else if (is_a <hsa_op_reg *> (op))
     op_queue.projected_size += sizeof (struct BrigOperandReg);
   else if (is_a <hsa_op_address *> (op))
+    {
     op_queue.projected_size += sizeof (struct BrigOperandAddress);
+    }
   else if (is_a <hsa_op_label *> (op))
-    op_queue.projected_size += sizeof (struct BrigOperandRef);
+    op_queue.projected_size += sizeof (struct BrigOperandCodeRef);
   else
     gcc_unreachable ();
   return ret;
 }
 
 /* Emit an immediate BRIG operand IMM.  */
+
 static void
 emit_immediate_operand (hsa_op_immed *imm)
 {
-  struct BrigOperandImmed out;
+  struct BrigOperandData out;
+  uint32_t byteCount;
+
   union
   {
     uint8_t b8;
@@ -831,43 +788,15 @@  emit_immediate_operand (hsa_op_immed *imm)
       gcc_unreachable ();
     }
 
-  out.size = htole16 ((8 + len + 3) & ~3);
-  out.kind = htole16 (BRIG_OPERAND_IMMED);
-  out.type = htole16 (bittype_for_type (imm->type));
-  out.byteCount = htole16 (len);
-  brig_operand.add (&out, 8);
-  brig_operand.add (&bytes, len);
-  brig_operand.round_size_up (4);
-}
-
-/* Emit a register name into the strings section, unless already emitted.
-   Return its offset in the string section.  */
-
-static unsigned
-emit_register_name  (hsa_op_reg *reg)
-{
-  unsigned *cache;
-  unsigned offset;
-  char buf[32];
-
-  if (reg->reg_class == 'c')
-    cache = &c_reg_names[(int) reg->hard_num];
-  else if (reg->reg_class == 's')
-    cache = &s_reg_names[(int) reg->hard_num];
-  else if (reg->reg_class == 'd')
-    cache = &d_reg_names[(int) reg->hard_num];
-  else if (reg->reg_class == 'q')
-    cache = &q_reg_names[(int) reg->hard_num];
-  else
-    gcc_unreachable ();
+  out.base.byteCount = htole16 (sizeof (out));
+  out.base.kind = htole16 (BRIG_KIND_OPERAND_DATA);
+  byteCount = len ;
 
-  if (*cache)
-    return *cache;
+  out.data = brig_data.add (&byteCount, sizeof (byteCount));
+  brig_data.add (&bytes, len);
 
-  sprintf (buf, "%c%i", reg->reg_class, reg->hard_num);
-  offset = brig_emit_string (buf, '$');
-  *cache = offset;
-  return offset;
+  brig_operand.add (&out, sizeof(out));
+  brig_data.round_size_up (4);
 }
 
 /* Emit a register BRIG operand REG.  */
@@ -877,63 +806,62 @@  emit_register_operand (hsa_op_reg *reg)
 {
   struct BrigOperandReg out;
 
-  out.size = htole16 (sizeof (out));
-  out.kind = htole16 (BRIG_OPERAND_REG);
-  out.reg = htole32 (emit_register_name (reg));
-  /* FIXME, hack, real regalloc */
-  out.type = htole16 (regtype_for_type (reg->type));
-  out.reserved = 0;
+  out.base.byteCount = htole16 (sizeof (out));
+  out.base.kind = htole16 (BRIG_KIND_OPERAND_REG);
+  out.regNum = htole32 (reg->hard_num);
+
+  if (BRIG_TYPE_B32 == regtype_for_type (reg->type))
+    out.regKind = BRIG_REGISTER_SINGLE;
+  else if (BRIG_TYPE_B64 == regtype_for_type (reg->type))
+    out.regKind = BRIG_REGISTER_DOUBLE;
+  else if (BRIG_TYPE_B128 == regtype_for_type (reg->type))
+    out.regKind = BRIG_REGISTER_QUAD;
+  else if (BRIG_TYPE_B1 == regtype_for_type (reg->type))
+    out.regKind = BRIG_REGISTER_CONTROL;
+  else
+    gcc_unreachable ();
+
   brig_operand.add (&out, sizeof (out));
 }
 
-/* Emit an address BRIG opernad ADDR.  */
+/* Emit an address BRIG operand ADDR.  */
 
 static void
 emit_address_operand (hsa_op_address *addr)
 {
   struct BrigOperandAddress out;
 
-  out.size = htole16 (sizeof (out));
-  out.kind = htole16 (BRIG_OPERAND_ADDRESS);
+  out.base.byteCount = htole16 (sizeof (out));
+  out.base.kind = htole16 (BRIG_KIND_OPERAND_ADDRESS);
   out.symbol = addr->symbol
-    ? htole32 (emit_symbol_directive (addr->symbol)) : 0;
-  out.reg = addr->reg ? htole32 (emit_register_name (addr->reg)) : 0;
+    ? htole32 (emit_directive_variable (addr->symbol)) : 0;
+  out.reg = addr->reg ? htole32 (enqueue_op (addr->reg)) : 0;
 
   /* FIXME: This is very clumsy.  */
   if (sizeof (addr->imm_offset) == 8)
     {
-      out.offsetLo = htole32 ((uint32_t)addr->imm_offset);
-      out.offsetHi = htole32 (((long long) addr->imm_offset) >> 32);
+      out.offset.lo = htole32 ((uint32_t)addr->imm_offset);
+      out.offset.hi = htole32 (((long long) addr->imm_offset) >> 32);
     }
   else
     {
-      out.offsetLo = htole32 (addr->imm_offset);
-      out.offsetHi = 0;
+      out.offset.lo = htole32 (addr->imm_offset);
+      out.offset.hi = 0;
     }
 
-  BrigType16_t optype;
-  if (addr->symbol)
-    optype = hsa_get_segment_addr_type (addr->symbol->segment);
-  else
-    optype = hsa_get_segment_addr_type (BRIG_SEGMENT_FLAT);
-  /* The standard (PRM 19.8.3 BrigOperandAddress) says these should be U types
-     but the validator insists these are B types, so as a hackish workaround,
-     we run the type through regtype_for_type.  */
-  out.type = htole16 (regtype_for_type (optype));
-  out.reserved = 0;
   brig_operand.add (&out, sizeof (out));
 }
 
-/* Emit an address BRIG opernad ADDR.  */
+/* Emit a label BRIG operand LABEL.  */
 
 static void
 emit_label_operand (hsa_op_label *lbl)
 {
-  struct BrigOperandRef out;
+  struct BrigOperandCodeRef out;
 
   gcc_assert (lbl->directive_offset);
-  out.size = htole16 (sizeof (out));
-  out.kind = htole16 (BRIG_OPERAND_LABEL_REF);
+  out.base.byteCount = htole16 (sizeof (out));
+  out.base.kind = htole16 (BRIG_KIND_OPERAND_CODE_REF);
   out.ref = htole32 (lbl->directive_offset);
   brig_operand.add (&out, sizeof (out));
 }
@@ -966,6 +894,9 @@  static void
 emit_memory_insn (hsa_insn_mem *mem)
 {
   struct BrigInstMem repr;
+  BrigOperandOffset32_t operand_offsets[2];
+  uint32_t byteCount;
+
   hsa_op_address *addr = as_a <hsa_op_address *> (mem->operands[1]);
 
   /* This is necessary because of the errorneous typedef of
@@ -973,36 +904,47 @@  emit_memory_insn (hsa_insn_mem *mem)
      random stuff (which we do not want so that we can test things don't
      change).  */
   memset (&repr, 0, sizeof (repr));
-  repr.size = htole16 (sizeof (repr));
-  repr.kind = htole16 (BRIG_INST_MEM);
-  repr.opcode = htole16 (mem->opcode);
-  repr.type = htole16 (mem->type);
-  repr.operands[0] = htole32 (enqueue_op (mem->operands[0]));
-  repr.operands[1] = htole32 (enqueue_op (mem->operands[1]));
-  repr.operands[2] = 0;
-  repr.operands[3] = 0;
-  repr.operands[4] = 0;
+  repr.base.base.byteCount = htole16 (sizeof (repr));
+  repr.base.base.kind = htole16 (BRIG_KIND_INST_MEM);
+  repr.base.opcode = htole16 (mem->opcode);
+  repr.base.type = htole16 (mem->type);
+
+  operand_offsets[0] = htole32 (enqueue_op (mem->operands[0]));
+  operand_offsets[1] = htole32 (enqueue_op (mem->operands[1]));
+  /* We have two operands so use 4 * 2 for the byteCount */
+  byteCount = htole32 (4 * 2);
+
+  repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
+  brig_data.add (&operand_offsets, sizeof (operand_offsets));
+  brig_data.round_size_up (4);
+
   if (addr->symbol)
     repr.segment = addr->symbol->segment;
   else
     repr.segment = BRIG_SEGMENT_FLAT;
-  repr.modifier = mem->semantic ? mem->semantic : BRIG_SEMANTIC_REGULAR;
+  repr.modifier = 0 ;
   repr.equivClass = mem->equiv_class;
-  if (mem->opcode == BRIG_OPCODE_LD)
+  repr.align = BRIG_ALIGNMENT_1;
+  if (mem->opcode == BRIG_OPCODE_LD
+      || mem->opcode == BRIG_OPCODE_ST)
     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 memory instruction and all nececcary directives, schedule
+/* Emit an HSA memory instruction and all necessary directives, schedule
    necessary operands for writing .  */
 
 static void
 emit_atomic_insn (hsa_insn_atomic *mem)
 {
   struct BrigInstAtomic repr;
+  BrigOperandOffset32_t operand_offsets[4];
+  uint32_t byteCount;
+
   hsa_op_address *addr = as_a <hsa_op_address *> (mem->operands[1]);
 
   /* This is necessary because of the errorneous typedef of
@@ -1010,93 +952,130 @@  emit_atomic_insn (hsa_insn_atomic *mem)
      random stuff (which we do not want so that we can test things don't
      change).  */
   memset (&repr, 0, sizeof (repr));
-  repr.size = htole16 (sizeof (repr));
-  repr.kind = htole16 (BRIG_INST_ATOMIC);
-  repr.opcode = htole16 (mem->opcode);
-  repr.type = htole16 (mem->type);
-  repr.operands[0] = htole32 (enqueue_op (mem->operands[0]));
-  repr.operands[1] = htole32 (enqueue_op (mem->operands[1]));
-  repr.operands[2] = htole32 (enqueue_op (mem->operands[2]));
-  if (mem->atomicop == BRIG_ATOMIC_CAS)
-    repr.operands[3] = htole32 (enqueue_op (mem->operands[3]));
+  repr.base.base.byteCount = htole16 (sizeof (repr));
+  repr.base.base.kind = htole16 (BRIG_KIND_INST_ATOMIC);
+  repr.base.opcode = htole16 (mem->opcode);
+  repr.base.type = htole16 (mem->type);
+
+  operand_offsets[0] = htole32 (enqueue_op (mem->operands[0]));
+  operand_offsets[1] = htole32 (enqueue_op (mem->operands[1]));
+  operand_offsets[2] = htole32 (enqueue_op (mem->operands[2]));
+  operand_offsets[3] = htole32 (enqueue_op (mem->operands[3]));
+
+  /* We have 4 operands so use 4 * 4 for the byteCount */
+  byteCount = htole32 (4 * 4);
+
+  repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
+  brig_data.add (&operand_offsets, sizeof (operand_offsets));
+  brig_data.round_size_up (4);
+
   if (addr->symbol)
     repr.segment = addr->symbol->segment;
   else
     repr.segment = BRIG_SEGMENT_FLAT;
-  repr.memorySemantic = mem->semantic ? mem->semantic : BRIG_SEMANTIC_REGULAR;
+  repr.memoryOrder = mem->memoryorder;
+  repr.memoryScope = mem->memoryscope;
   repr.atomicOperation = mem->atomicop;
+
   brig_code.add (&repr, sizeof (repr));
   brig_insn_count++;
 }
 
-/* Emit an HSA LDA instruction and all nececcary directives, schedule
+/* Emit an HSA LDA instruction and all necessary directives, schedule
    necessary operands for writing .  */
 
 static void
 emit_addr_insn (hsa_insn_addr *insn)
 {
   struct BrigInstAddr repr;
+  BrigOperandOffset32_t operand_offsets[2];
+  uint32_t byteCount;
+
   hsa_op_address *addr = as_a <hsa_op_address *> (insn->operands[1]);
 
-  repr.size = htole16 (sizeof (repr));
-  repr.kind = htole16 (BRIG_INST_ADDR);
-  repr.opcode = htole16 (insn->opcode);
-  repr.type = htole16 (insn->type);
-  repr.operands[0] = htole32 (enqueue_op (insn->operands[0]));
-  repr.operands[1] = htole32 (enqueue_op (insn->operands[1]));
-  repr.operands[2] = 0;
-  repr.operands[3] = 0;
-  repr.operands[4] = 0;
+  repr.base.base.byteCount = htole16 (sizeof (repr));
+  repr.base.base.kind = htole16 (BRIG_KIND_INST_ADDR);
+  repr.base.opcode = htole16 (insn->opcode);
+  repr.base.type = htole16 (insn->type);
+
+  operand_offsets[0] = htole32 (enqueue_op (insn->operands[0]));
+  operand_offsets[1] = htole32 (enqueue_op (insn->operands[1]));
+
+  /* We have two operands so use 4 * 2 for the byteCount */
+  byteCount = htole32 (4 * 2);
+
+  repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
+  brig_data.add (&operand_offsets, sizeof (operand_offsets));
+  brig_data.round_size_up (4);
+
   if (addr->symbol)
     repr.segment = addr->symbol->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 nececcary directives,
+/* 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 BrigInstSeg repr;
+  BrigOperandOffset32_t operand_offsets[2];
+  uint32_t byteCount;
+
+  repr.base.base.byteCount = htole16 (sizeof (repr));
+  repr.base.base.kind = htole16 (BRIG_KIND_INST_SEG);
+  repr.base.opcode = htole16 (seg->opcode);
+  repr.base.type = htole16 (seg->type);
+
+  operand_offsets[0] = htole32 (enqueue_op (seg->operands[0]));
+  operand_offsets[1] = htole32 (enqueue_op (seg->operands[1]));
+
+  /* We have two operands so use 4 * 2 for the byteCount */
+  byteCount = htole32 (4 * 2);
+
+  repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
+  brig_data.add (&operand_offsets, sizeof (operand_offsets));
+  brig_data.round_size_up (4);
 
-  repr.size = htole16 (sizeof (repr));
-  repr.kind = htole16 (BRIG_INST_SEG);
-  repr.opcode = htole16 (seg->opcode);
-  repr.type = htole16 (seg->type);
-  repr.operands[0] = htole32 (enqueue_op (seg->operands[0]));
-  repr.operands[1] = htole32 (enqueue_op (seg->operands[1]));
-  repr.operands[2] = 0;
-  repr.operands[3] = 0;
-  repr.operands[4] = 0;
-  repr.sourceType = htole16 (seg->src_type);
   repr.segment = seg->segment;
-  repr.reserved = 0;
+  memset (&repr.reserved, 0, sizeof (repr.reserved));
+
   brig_code.add (&repr, sizeof (repr));
+
   brig_insn_count++;
 }
 
-/* Emit an HSA comparison instruction and all nececcary directives,
+/* 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;
+  BrigOperandOffset32_t operand_offsets[3];
+  uint32_t byteCount;
+
+  repr.base.base.byteCount = htole16 (sizeof (repr));
+  repr.base.base.kind = htole16 (BRIG_KIND_INST_CMP);
+  repr.base.opcode = htole16 (cmp->opcode);
+  repr.base.type = htole16 (cmp->type);
+
+  operand_offsets[0] = htole32 (enqueue_op (cmp->operands[0]));
+  operand_offsets[1] = htole32 (enqueue_op (cmp->operands[1]));
+  operand_offsets[2] = htole32 (enqueue_op (cmp->operands[2]));
+  /* We have three operands so use 4 * 3 for the byteCount */
+  byteCount = htole32 (4 * 3);
+
+  repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
+  brig_data.add (&operand_offsets, sizeof (operand_offsets));
+  brig_data.round_size_up (4);
 
-  repr.size = htole16 (sizeof (repr));
-  repr.kind = htole16 (BRIG_INST_CMP);
-  repr.opcode = htole16 (cmp->opcode);
-  repr.type = htole16 (cmp->type);
-  repr.operands[0] = htole32 (enqueue_op (cmp->operands[0]));
-  repr.operands[1] = htole32 (enqueue_op (cmp->operands[1]));
-  repr.operands[2] = htole32 (enqueue_op (cmp->operands[2]));
-  repr.operands[3] = 0;
-  repr.operands[4] = 0;
   if (is_a <hsa_op_reg *> (cmp->operands[1]))
     repr.sourceType = htole16 (as_a <hsa_op_reg *> (cmp->operands[1])->type);
   else
@@ -1105,17 +1084,21 @@  emit_cmp_insn (hsa_insn_cmp *cmp)
   repr.compare = cmp->compare;
   repr.pack = 0;
   repr.reserved = 0;
+
   brig_code.add (&repr, sizeof (repr));
   brig_insn_count++;
 }
 
-/* Emit an HSA branching instruction and all nececcary directives, schedule
+/* Emit an HSA branching instruction and all necessary directives, schedule
    necessary operands for writing .  */
 
 static void
 emit_branch_insn (hsa_insn_br *br)
 {
   struct BrigInstBr repr;
+  BrigOperandOffset32_t operand_offsets[2];
+  uint32_t byteCount;
+
   basic_block target = NULL;
   edge_iterator ei;
   edge e;
@@ -1123,12 +1106,14 @@  emit_branch_insn (hsa_insn_br *br)
   /* At the moment we only handle direct conditional jumps.  */
   gcc_assert (br->opcode == BRIG_OPCODE_CBR
 	      && !br->operands[2]);
-  repr.size = htole16 (sizeof (repr));
-  repr.kind = htole16 (BRIG_INST_BR);
-  repr.opcode = htole16 (br->opcode);
+  repr.base.base.byteCount = htole16 (sizeof (repr));
+  repr.base.base.kind = htole16 (BRIG_KIND_INST_BR);
+  repr.base.opcode = htole16 (br->opcode);
   repr.width = BRIG_WIDTH_1;
-  repr.type = htole16 (br->type);
-  repr.operands[0] = htole32 (enqueue_op (br->operands[0]));
+  /* For Conditional jumps the type is always B1 */
+  repr.base.type = htole16 (BRIG_TYPE_B1);
+
+  operand_offsets[0] = htole32 (enqueue_op (br->operands[0]));
 
   FOR_EACH_EDGE (e, ei, br->bb->succs)
     if (e->flags & EDGE_TRUE_VALUE)
@@ -1137,14 +1122,17 @@  emit_branch_insn (hsa_insn_br *br)
 	break;
       }
   gcc_assert (target);
-  repr.operands[1] = htole32 (enqueue_op (&hsa_bb_for_bb (target)->label_ref));
-  repr.operands[2] = 0;
-  repr.operands[3] = 0;
-  repr.operands[4] = 0;
-
-  repr.modifier = 0;
+  operand_offsets[1] = htole32 (enqueue_op
+				(&hsa_bb_for_bb (target)->label_ref));
+
+  /* We have 2 operands so use 4 * 2 for the byteCount */
+  byteCount = htole32 (4 * 2);
+  repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
+  brig_data.add (&operand_offsets, sizeof (operand_offsets));
+  brig_data.round_size_up (4);
   repr.width = BRIG_WIDTH_1;
-  repr.reserved = 0;
+  memset (&repr.reserved, 0, sizeof (repr.reserved));
+
   brig_code.add (&repr, sizeof (repr));
   brig_insn_count++;
 }
@@ -1163,23 +1151,36 @@  float_type_p (BrigType16_t t)
     }
 }
 
-/* Emit a HSA convert instruction and all nececcary directives, schedule
+/* Emit a HSA convert instruction and all necessary directives, schedule
    necessary operands for writing.  */
+
 static void
 emit_cvt_insn (hsa_insn_basic *insn)
 {
   struct BrigInstCvt repr;
   BrigType16_t srctype;
+  BrigOperandOffset32_t operand_offsets[1];
+  uint32_t byteCount, operand_count=0;
+
+  repr.base.base.byteCount = htole16 (sizeof (repr));
+  repr.base.base.kind = htole16 (BRIG_KIND_INST_CVT);
+  repr.base.opcode = htole16 (insn->opcode);
+  repr.base.type = htole16 (insn->type);
 
-  repr.size = htole16 (sizeof (repr));
-  repr.kind = htole16 (BRIG_INST_CVT);
-  repr.opcode = htole16 (insn->opcode);
-  repr.type = htole16 (insn->type);
   for (int i = 0; i < HSA_OPERANDS_PER_INSN; i++)
     if (insn->operands[i])
-      repr.operands[i] = htole32 (enqueue_op (insn->operands[i]));
+      {
+        operand_offsets[i] = htole32 (enqueue_op (insn->operands[i]));
+        operand_count = operand_count + 1;
+      }
     else
-      repr.operands[i] = 0;
+      operand_offsets[i] = 0;
+
+  byteCount = htole32 (4 * operand_count) ;
+  repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
+  brig_data.add (&operand_offsets,
+		 operand_count * sizeof (BrigOperandOffset32_t));
+
   if (is_a <hsa_op_reg *> (insn->operands[1]))
     srctype = as_a <hsa_op_reg *> (insn->operands[1])->type;
   else
@@ -1193,11 +1194,12 @@  emit_cvt_insn (hsa_insn_basic *insn)
     repr.modifier = BRIG_ROUND_FLOAT_NEAR_EVEN;
   else
     repr.modifier = 0;
+
   brig_code.add (&repr, sizeof (repr));
   brig_insn_count++;
 }
 
-/* Emit a basic HSA instruction and all nececcary directives, schedule
+/* Emit a basic HSA instruction and all necessary directives, schedule
    necessary operands for writing .  */
 
 static void
@@ -1206,6 +1208,8 @@  emit_basic_insn (hsa_insn_basic *insn)
   /* We assume that BrigInstMod has a BrigInstBasic prefix.  */
   struct BrigInstMod repr;
   BrigType16_t type;
+  BrigOperandOffset32_t operand_offsets[HSA_OPERANDS_PER_INSN];
+  uint32_t byteCount, operand_count = 0;
 
   if (insn->opcode == BRIG_OPCODE_CVT)
     {
@@ -1213,9 +1217,9 @@  emit_basic_insn (hsa_insn_basic *insn)
       return;
     }
 
-  repr.size = htole16 (sizeof (BrigInstBasic));
-  repr.kind = htole16 (BRIG_INST_BASIC);
-  repr.opcode = htole16 (insn->opcode);
+  repr.base.base.byteCount = htole16 (sizeof (BrigInstBasic));
+  repr.base.base.kind = htole16 (BRIG_KIND_INST_BASIC);
+  repr.base.opcode = htole16 (insn->opcode);
   switch (insn->opcode)
     {
       /* XXX The spec says mov can take all types.  But the LLVM based
@@ -1233,12 +1237,23 @@  emit_basic_insn (hsa_insn_basic *insn)
 	type = insn->type;
 	break;
     }
-  repr.type = htole16 (type);
+  repr.base.type = htole16 (type);
+
   for (int i = 0; i < HSA_OPERANDS_PER_INSN; i++)
     if (insn->operands[i])
-      repr.operands[i] = htole32 (enqueue_op (insn->operands[i]));
+      {
+	operand_offsets[i] = htole32 (enqueue_op (insn->operands[i]));
+	operand_count = operand_count + 1;
+      }
     else
-      repr.operands[i] = 0;
+      operand_offsets[i] = 0;
+
+  byteCount = htole32 (4 * operand_count) ;
+  repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
+  brig_data.add (&operand_offsets,
+		 operand_count * sizeof (BrigOperandOffset32_t));
+  brig_data.round_size_up (4);
+
   if ((type & BRIG_TYPE_PACK_MASK) != BRIG_TYPE_PACK_NONE)
     {
       if (float_type_p (type))
@@ -1252,8 +1267,8 @@  emit_basic_insn (hsa_insn_basic *insn)
       else
 	repr.pack = BRIG_PACK_P;
       repr.reserved = 0;
-      repr.size = htole16 (sizeof (BrigInstMod));
-      repr.kind = htole16 (BRIG_INST_MOD);
+      repr.base.base.byteCount = htole16 (sizeof (BrigInstMod));
+      repr.base.base.kind = htole16 (BRIG_KIND_INST_MOD);
       brig_code.add (&repr, sizeof (struct BrigInstMod));
     }
   else
@@ -1261,7 +1276,7 @@  emit_basic_insn (hsa_insn_basic *insn)
   brig_insn_count++;
 }
 
-/* Emit an HSA instruction and all nececcary directives, schedule necessary
+/* Emit an HSA instruction and all necessary directives, schedule necessary
    operands for writing .  */
 
 static void
@@ -1310,6 +1325,9 @@  perhaps_emit_branch (basic_block bb, basic_block next_bb)
 {
   basic_block t_bb = NULL, ff = NULL;
   struct BrigInstBr repr;
+  BrigOperandOffset32_t operand_offsets[1];
+  uint32_t byteCount;
+
   edge_iterator ei;
   edge e;
 
@@ -1329,26 +1347,26 @@  perhaps_emit_branch (basic_block bb, basic_block next_bb)
       || ff == EXIT_BLOCK_PTR_FOR_FN (cfun))
     return;
 
-  repr.size = htole16 (sizeof (repr));
-  repr.kind = htole16 (BRIG_INST_BR);
-  repr.opcode = htole16 (BRIG_OPCODE_BRN);
-  repr.type = htole16 (BRIG_TYPE_NONE);
+  repr.base.base.byteCount = htole16 (sizeof (repr));
+  repr.base.base.kind = htole16 (BRIG_KIND_INST_BR);
+  repr.base.opcode = htole16 (BRIG_OPCODE_BR);
+  repr.base.type = htole16 (BRIG_TYPE_NONE);
   /* Direct branches to labels must be width(all).  */
   repr.width = BRIG_WIDTH_ALL;
-  repr.operands[0] = htole32 (enqueue_op (&hsa_bb_for_bb (ff)->label_ref));
-  repr.operands[1] = 0;
-  repr.operands[2] = 0;
-  repr.operands[3] = 0;
-  repr.operands[4] = 0;
 
-  repr.modifier = 0;
-  repr.width = BRIG_WIDTH_ALL;
-  repr.reserved = 0;
+  operand_offsets[0] = htole32 (enqueue_op (&hsa_bb_for_bb (ff)->label_ref));
+  /* We have 1 operand so use 4 * 1 for the byteCount */
+  byteCount = htole32 (4 * 1);
+  repr.base.operands = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
+  brig_data.add (&operand_offsets, sizeof (operand_offsets));
+  brig_data.round_size_up (4);
+  memset (&repr.reserved, 0, sizeof (repr.reserved));
   brig_code.add (&repr, sizeof (repr));
   brig_insn_count++;
 }
 
 /* Emit the a function with name NAME to the various brig sections.  */
+
 void
 hsa_brig_emit_function (void)
 {
@@ -1377,14 +1395,12 @@  hsa_brig_emit_function (void)
       prev_bb = bb;
     }
   perhaps_emit_branch (prev_bb, NULL);
-  ptr_to_fndir->instCount = brig_insn_count;
-  ptr_to_fndir->nextTopLevelDirective = brig_directive.total_size;
+  ptr_to_fndir->codeBlockEntryCount = brig_insn_count ;
+  ptr_to_fndir->nextModuleEntry = brig_code.total_size;
 
   emit_queued_operands ();
 }
 
-/* Write BRIG sections to the output file.  */
-
 void
 hsa_output_brig (void)
 {
@@ -1394,11 +1410,11 @@  hsa_output_brig (void)
     return;
 
   saved_section = in_section;
-  brig_string.output (BRIG_SECTION_STRING_NAME);
-  brig_directive.output (BRIG_SECTION_DIRECTIVE_NAME);
-  brig_code.output (BRIG_SECTION_CODE_NAME);
-  brig_operand.output (BRIG_SECTION_OPERAND_NAME);
-  brig_debug.output (BRIG_SECTION_DEBUG_NAME);
+
+  brig_data.output ();
+  brig_code.output ();
+  brig_operand.output ();
+
   if (saved_section)
     switch_to_section (saved_section);
 
diff --git a/gcc/hsa-dump.c b/gcc/hsa-dump.c
index 2e2adbc..1f9f9cd 100644
--- a/gcc/hsa-dump.c
+++ b/gcc/hsa-dump.c
@@ -78,10 +78,14 @@  hsa_type_name (BrigType16_t type)
       return "samp";
     case BRIG_TYPE_ROIMG:
       return "roimg";
+    case BRIG_TYPE_WOIMG:
+      return "woimg";
     case BRIG_TYPE_RWIMG:
       return "rwimg";
-    case BRIG_TYPE_FBAR:
-      return "fbar";
+    case BRIG_TYPE_SIG32:
+      return "sig32";
+    case BRIG_TYPE_SIG64:
+      return "sig64";
     case BRIG_TYPE_U8X4:
       return "u8x4";
     case BRIG_TYPE_U8X8:
@@ -228,8 +232,6 @@  hsa_opcode_name (BrigOpcode16_t opcode)
       return "expand";
     case BRIG_OPCODE_LDA:
       return "lda";
-    case BRIG_OPCODE_LDC:
-      return "ldc";
     case BRIG_OPCODE_MOV:
       return "mov";
     case BRIG_OPCODE_SHUFFLE:
@@ -294,38 +296,32 @@  hsa_opcode_name (BrigOpcode16_t opcode)
       return "atomic";
     case BRIG_OPCODE_ATOMICNORET:
       return "atomicnoret";
+    case BRIG_OPCODE_SIGNAL:
+      return "signal";
+    case BRIG_OPCODE_SIGNALNORET:
+      return "signalnoret";
+    case BRIG_OPCODE_MEMFENCE:
+      return "memfence";
     case BRIG_OPCODE_RDIMAGE:
       return "rdimage";
     case BRIG_OPCODE_LDIMAGE:
       return "ldimage";
     case BRIG_OPCODE_STIMAGE:
       return "stimage";
-    case BRIG_OPCODE_ATOMICIMAGE:
-      return "atomicimage";
-    case BRIG_OPCODE_ATOMICIMAGENORET:
-      return "atomicimagenoret";
-    case BRIG_OPCODE_QUERYIMAGEARRAY:
-      return "queryimagearray";
-    case BRIG_OPCODE_QUERYIMAGEDEPTH:
-      return "queryimagedepth";
-    case BRIG_OPCODE_QUERYIMAGEFORMAT:
-      return "queryimageformat";
-    case BRIG_OPCODE_QUERYIMAGEHEIGHT:
-      return "queryimageheight";
-    case BRIG_OPCODE_QUERYIMAGEORDER:
-      return "queryimageorder";
-    case BRIG_OPCODE_QUERYIMAGEWIDTH:
-      return "queryimagewidth";
-    case BRIG_OPCODE_QUERYSAMPLERCOORD:
-      return "querysamplercoord";
-    case BRIG_OPCODE_QUERYSAMPLERFILTER:
-      return "querysamplerfilter";
+    case BRIG_OPCODE_QUERYIMAGE:
+      return "queryimage";
+    case BRIG_OPCODE_QUERYSAMPLER:
+      return "querysampler";
     case BRIG_OPCODE_CBR:
       return "cbr";
-    case BRIG_OPCODE_BRN:
-      return "brn";
+    case BRIG_OPCODE_BR:
+      return "br";
+    case BRIG_OPCODE_SBR:
+      return "sbr";
     case BRIG_OPCODE_BARRIER:
       return "barrier";
+    case BRIG_OPCODE_WAVEBARRIER:
+      return "wavebarrier";
     case BRIG_OPCODE_ARRIVEFBAR:
       return "arrivefbar";
     case BRIG_OPCODE_INITFBAR:
@@ -340,64 +336,38 @@  hsa_opcode_name (BrigOpcode16_t opcode)
       return "waitfbar";
     case BRIG_OPCODE_LDF:
       return "ldf";
-    case BRIG_OPCODE_SYNC:
-      return "sync";
-    case BRIG_OPCODE_COUNTLANE:
-      return "countlane";
-    case BRIG_OPCODE_COUNTUPLANE:
-      return "countuplane";
-    case BRIG_OPCODE_MASKLANE:
-      return "masklane";
-    case BRIG_OPCODE_SENDLANE:
-      return "sendlane";
-    case BRIG_OPCODE_RECEIVELANE:
-      return "receivelane";
+    case BRIG_OPCODE_ACTIVELANECOUNT:
+      return "activelanecount";
+    case BRIG_OPCODE_ACTIVELANEID:
+      return "activelaneid";
+    case BRIG_OPCODE_ACTIVELANEMASK:
+      return "activelanemask";
+    case BRIG_OPCODE_ACTIVELANESHUFFLE:
+      return "activelaneshuffle";
     case BRIG_OPCODE_CALL:
       return "call";
+    case BRIG_OPCODE_SCALL:
+      return "scall";
+    case BRIG_OPCODE_ICALL:
+      return "icall";
+    case BRIG_OPCODE_LDI:
+      return "ldi";
     case BRIG_OPCODE_RET:
       return "ret";
-    case BRIG_OPCODE_SYSCALL:
-      return "syscall";
     case BRIG_OPCODE_ALLOCA:
       return "alloca";
-    case BRIG_OPCODE_CLEARDETECTEXCEPT:
-      return "cleardetectexcept";
-    case BRIG_OPCODE_CLOCK:
-      return "clock";
-    case BRIG_OPCODE_CUID:
-      return "cuid";
     case BRIG_OPCODE_CURRENTWORKGROUPSIZE:
       return "currentworkgroupsize";
-    case BRIG_OPCODE_DEBUGTRAP:
-      return "debugtrap";
     case BRIG_OPCODE_DIM:
       return "dim";
-    case BRIG_OPCODE_DISPATCHID:
-      return "dispatchid";
-    case BRIG_OPCODE_DISPATCHPTR:
-      return "dispatchptr";
-    case BRIG_OPCODE_GETDETECTEXCEPT:
-      return "getdetectexcept";
     case BRIG_OPCODE_GRIDGROUPS:
       return "gridgroups";
     case BRIG_OPCODE_GRIDSIZE:
       return "gridsize";
-    case BRIG_OPCODE_LANEID:
-      return "laneid";
-    case BRIG_OPCODE_MAXCUID:
-      return "maxcuid";
-    case BRIG_OPCODE_MAXWAVEID:
-      return "maxwaveid";
-    case BRIG_OPCODE_NULLPTR:
-      return "nullptr";
-    case BRIG_OPCODE_QID:
-      return "qid";
-    case BRIG_OPCODE_QPTR:
-      return "qptr";
-    case BRIG_OPCODE_SETDETECTEXCEPT:
-      return "setdetectexcept";
-    case BRIG_OPCODE_WAVEID:
-      return "waveid";
+    case BRIG_OPCODE_PACKETCOMPLETIONSIG:
+      return "packetcompletionsig";
+    case BRIG_OPCODE_PACKETID:
+      return "packetid";
     case BRIG_OPCODE_WORKGROUPID:
       return "workgroupid";
     case BRIG_OPCODE_WORKGROUPSIZE:
@@ -410,6 +380,54 @@  hsa_opcode_name (BrigOpcode16_t opcode)
       return "workitemflatid";
     case BRIG_OPCODE_WORKITEMID:
       return "workitemid";
+    case BRIG_OPCODE_CLEARDETECTEXCEPT:
+      return "cleardetectexcept";
+    case BRIG_OPCODE_GETDETECTEXCEPT:
+      return "getdetectexcept";
+    case BRIG_OPCODE_SETDETECTEXCEPT:
+      return "setdetectexcept";
+    case BRIG_OPCODE_ADDQUEUEWRITEINDEX:
+      return "addqueuewriteindex";
+    case BRIG_OPCODE_AGENTCOUNT:
+      return "agentcount";
+    case BRIG_OPCODE_AGENTID:
+      return "agentid";
+    case BRIG_OPCODE_CASQUEUEWRITEINDEX:
+      return "casqueuewriteindex";
+    case BRIG_OPCODE_LDK:
+      return "ldk";
+    case BRIG_OPCODE_LDQUEUEREADINDEX:
+      return "ldqueuereadindex";
+    case BRIG_OPCODE_LDQUEUEWRITEINDEX:
+      return "ldqueuewriteindex";
+    case BRIG_OPCODE_QUEUEID:
+      return "queueid";
+    case BRIG_OPCODE_QUEUEPTR:
+      return "queueptr";
+    case BRIG_OPCODE_STQUEUEREADINDEX:
+      return "stqueuereadindex";
+    case BRIG_OPCODE_STQUEUEWRITEINDEX:
+      return "stqueuewriteindex";
+    case BRIG_OPCODE_CLOCK:
+      return "clock";
+    case BRIG_OPCODE_CUID:
+      return "cuid";
+    case BRIG_OPCODE_DEBUGTRAP:
+      return "debugtrap";
+    case BRIG_OPCODE_GROUPBASEPTR:
+      return "groupbaseptr";
+    case BRIG_OPCODE_KERNARGBASEPTR:
+      return "kernargbaseptr";
+    case BRIG_OPCODE_LANEID:
+      return "laneid";
+    case BRIG_OPCODE_MAXCUID:
+      return "maxcuid";
+    case BRIG_OPCODE_MAXWAVEID:
+      return "maxwaveid";
+    case BRIG_OPCODE_NULLPTR:
+      return "nullptr";
+    case BRIG_OPCODE_WAVEID:
+      return "waveid";
     default:
       return "UNKNOWN_OPCODE";
     }
@@ -513,61 +531,101 @@  hsa_cmpop_name (BrigCompareOperation8_t cmpop)
     }
 }
 
-/* Return textual name for memory semantics.  */
+/* Return textual name for memory order.  */
 
 static const char *
-hsa_memsem_name (enum BrigMemorySemantic sem)
+hsa_memsem_name (enum BrigMemoryOrder mo)
 {
-  switch (sem)
+  switch (mo)
     {
-    case BRIG_SEMANTIC_NONE:
-    case BRIG_SEMANTIC_REGULAR:
+    case BRIG_MEMORY_ORDER_NONE:
       return "";
-    case BRIG_SEMANTIC_ACQUIRE:
-      return "acq";
-    case BRIG_SEMANTIC_RELEASE:
-      return "rel";
-    case BRIG_SEMANTIC_ACQUIRE_RELEASE:
-      return "ar";
-    case BRIG_SEMANTIC_PARTIAL_ACQUIRE:
-      return "part_acq";
-    case BRIG_SEMANTIC_PARTIAL_RELEASE:
-      return "part_rel";
-    case BRIG_SEMANTIC_PARTIAL_ACQUIRE_RELEASE:
-      return "part_ar";
+    case BRIG_MEMORY_ORDER_RELAXED:
+      return "rlx";
+    case BRIG_MEMORY_ORDER_SC_ACQUIRE:
+      return "scacq";
+    case BRIG_MEMORY_ORDER_SC_RELEASE:
+      return "screl";
+    case BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE:
+      return "scar";
     default:
-      return "UNKNOWN_SEMANTIC";
+      return "UNKNOWN_MEMORY_ORDER";
     }
+}
 
+/* Return textual name for memory scope. */
+
+static const char *
+hsa_memscope_name (enum BrigMemoryScope scope)
+{
+  switch (scope)
+    {
+    case BRIG_MEMORY_SCOPE_NONE:
+      return "";
+    case BRIG_MEMORY_SCOPE_WORKITEM:
+      return "wi";
+    case BRIG_MEMORY_SCOPE_WAVEFRONT:
+      return "wv";
+    case BRIG_MEMORY_SCOPE_WORKGROUP:
+      return "wg";
+    case BRIG_MEMORY_SCOPE_COMPONENT:
+      return "cmp";
+    case BRIG_MEMORY_SCOPE_SYSTEM:
+      return "sys";
+    default:
+      return "UNKNOWN_SCOPE";
+    }
 }
 
+/* Return textual name for atomic operation. */
+
 static const char *
 hsa_atomicop_name (enum BrigAtomicOperation op)
 {
   switch (op)
     {
+    case BRIG_ATOMIC_ADD:
+      return "add";
     case BRIG_ATOMIC_AND:
       return "and";
-    case BRIG_ATOMIC_OR:
-      return "or";
-    case BRIG_ATOMIC_XOR:
-      return "xor";
     case BRIG_ATOMIC_CAS:
       return "cas";
     case BRIG_ATOMIC_EXCH:
       return "exch";
-    case BRIG_ATOMIC_ADD:
-      return "add";
-    case BRIG_ATOMIC_INC:
-      return "inc";
-    case BRIG_ATOMIC_DEC:
-      return "dec";
-    case BRIG_ATOMIC_MIN:
-      return "min";
+    case BRIG_ATOMIC_LD:
+      return "ld";
     case BRIG_ATOMIC_MAX:
       return "max";
+    case BRIG_ATOMIC_MIN:
+      return "min";
+    case BRIG_ATOMIC_OR:
+      return "or";
+    case BRIG_ATOMIC_ST:
+      return "st";
     case BRIG_ATOMIC_SUB:
       return "sub";
+    case BRIG_ATOMIC_WRAPDEC:
+      return "wrapdec";
+    case BRIG_ATOMIC_WRAPINC:
+      return "wrapinc";
+    case BRIG_ATOMIC_XOR:
+      return "xor";
+    case BRIG_ATOMIC_WAIT_EQ:
+      return "wait_eq";
+    case BRIG_ATOMIC_WAIT_NE:
+      return "wait_ne";
+    case BRIG_ATOMIC_WAIT_LT:
+      return "wait_lt";
+    case BRIG_ATOMIC_WAIT_GTE:
+      return "wait_gte";
+    case BRIG_ATOMIC_WAITTIMEOUT_EQ:
+      return "waittimeout_eq";
+    case BRIG_ATOMIC_WAITTIMEOUT_NE:
+      return "waittimeout_ne";
+    case BRIG_ATOMIC_WAITTIMEOUT_LT:
+      return "waittimeout_lt";
+    case BRIG_ATOMIC_WAITTIMEOUT_GTE:
+      return "waittimeout_gte";
     default:
       return "UNKNOWN_ATOMIC_OP";
     }
@@ -673,9 +731,10 @@  dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int indent)
       fprintf (f, "_%s", hsa_atomicop_name (mem->atomicop));
       if (addr->symbol)
 	fprintf (f, "_%s", hsa_seg_name (addr->symbol->segment));
-      if (mem->semantic != BRIG_SEMANTIC_NONE
-	  && mem->semantic != BRIG_SEMANTIC_REGULAR)
-	fprintf (f, "_%s", hsa_memsem_name (mem->semantic));
+      if (mem->memoryorder != BRIG_MEMORY_ORDER_NONE)
+	fprintf (f, "_%s", hsa_memsem_name (mem->memoryorder));
+      if (mem->memoryscope != BRIG_MEMORY_SCOPE_NONE)
+	fprintf (f, "_%s", hsa_memscope_name (mem->memoryscope));
       fprintf (f, "_%s ", hsa_type_name (mem->type));
 
       dump_hsa_imm_or_reg (f, mem->operands[0]);
@@ -698,9 +757,10 @@  dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int indent)
       fprintf (f, "%s", hsa_opcode_name (mem->opcode));
       if (addr->symbol)
 	fprintf (f, "_%s", hsa_seg_name (addr->symbol->segment));
-      if (mem->semantic != BRIG_SEMANTIC_NONE
-	  && mem->semantic != BRIG_SEMANTIC_REGULAR)
-	fprintf (f, "_%s", hsa_memsem_name (mem->semantic));
+      if (mem->memoryorder != BRIG_MEMORY_ORDER_NONE)
+	fprintf (f, "_%s", hsa_memsem_name (mem->memoryorder));
+      if (mem->memoryscope != BRIG_MEMORY_SCOPE_NONE)
+	fprintf (f, "_%s", hsa_memscope_name (mem->memoryscope));
       if (mem->equiv_class != 0)
 	fprintf (f, "_equiv(%i)", mem->equiv_class);
       fprintf (f, "_%s ", hsa_type_name (mem->type));
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 101acb4..05e3015 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -156,7 +156,7 @@  hsa_init_data_for_cfun ()
 			 sizeof (struct hsa_op_address), sym_init_len);
 
   memset (&hsa_cfun, 0, sizeof (hsa_cfun));
-  hsa_cfun.prologue.label_ref.kind = BRIG_OPERAND_LABEL_REF;
+  hsa_cfun.prologue.label_ref.kind = BRIG_KIND_OPERAND_CODE_REF;
   hsa_cfun.local_symbols
     = new hash_table <hsa_noop_symbol_hasher> (sym_init_len);
   hsa_cfun.reg_count = 0;
@@ -524,7 +524,7 @@  hsa_alloc_immed_op (tree tree_val)
 		       && !POINTER_TYPE_P (TREE_TYPE (tree_val)));
 
   memset (imm, 0 , sizeof (hsa_op_immed));
-  imm->kind = BRIG_OPERAND_IMMED;
+  imm->kind = BRIG_KIND_OPERAND_DATA;
   imm->type = hsa_type_for_scalar_tree_type (TREE_TYPE (tree_val), true);
   imm->value = tree_val;
 
@@ -540,7 +540,7 @@  hsa_alloc_reg_op (void)
 
   hreg = (hsa_op_reg *) pool_alloc (hsa_allocp_operand_reg);
   memset (hreg, 0, sizeof (hsa_op_reg));
-  hreg->kind = BRIG_OPERAND_REG;
+  hreg->kind = BRIG_KIND_OPERAND_REG;
   /* TODO: Try removing later on.  I suppose this is not necessary but I'd
      rather avoid surprises.  */
   hreg->uses = vNULL;
@@ -559,7 +559,7 @@  hsa_alloc_addr_op (hsa_symbol *sym, hsa_op_reg *reg, HOST_WIDE_INT offset)
 
   addr = (hsa_op_address *) pool_alloc (hsa_allocp_operand_address);
   memset (addr, 0, sizeof (hsa_op_address));
-  addr->kind = BRIG_OPERAND_ADDRESS;
+  addr->kind = BRIG_KIND_OPERAND_ADDRESS;
   addr->symbol = sym;
   addr->reg = reg;
   addr->imm_offset = offset;
@@ -1652,10 +1652,12 @@  specialop:
 	dest = hsa_reg_for_gimple_ssa (lhs, ssa_map);
 
 	meminsn->opcode = BRIG_OPCODE_LD;
+	/* Should check what the memory scope is */
+	meminsn->memoryscope = BRIG_MEMORY_SCOPE_WORKGROUP;
 	meminsn->type = mem_type_for_type (hsa_type_for_scalar_tree_type (TREE_TYPE (lhs), false));
 	meminsn->operands[0] = dest;
 	meminsn->operands[1] = addr;
-	meminsn->semantic = BRIG_SEMANTIC_ACQUIRE;
+	meminsn->memoryorder = BRIG_MEMORY_ORDER_SC_ACQUIRE;
 
 	set_reg_def (dest, meminsn);
 	if (addr->reg)
@@ -1677,6 +1679,8 @@  specialop:
 	dest = hsa_reg_for_gimple_ssa (lhs, ssa_map);
 
 	atominsn->opcode = BRIG_OPCODE_ATOMIC;
+	/* Should check what the memory scope is */
+	atominsn->memoryscope = BRIG_MEMORY_SCOPE_WORKGROUP;
 	atominsn->type = bittype_for_type (hsa_type_for_scalar_tree_type (TREE_TYPE (lhs), false));
 	atominsn->operands[0] = dest;
 	atominsn->operands[1] = addr;
@@ -1686,7 +1690,7 @@  specialop:
 	atominsn->operands[3]
 	  = hsa_reg_or_immed_for_gimple_op (gimple_call_arg (stmt, 2),
 					    hbb, ssa_map, atominsn);
-	atominsn->semantic = BRIG_SEMANTIC_ACQUIRE_RELEASE;
+	atominsn->memoryorder = BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE;
 	atominsn->atomicop = BRIG_ATOMIC_CAS;
 
 	set_reg_def (dest, atominsn);
@@ -1812,7 +1816,7 @@  hsa_init_new_bb (basic_block bb)
   bb->aux = hbb;
   hbb->bb = bb;
   hbb->index = hsa_cfun.hbb_count++;
-  hbb->label_ref.kind = BRIG_OPERAND_LABEL_REF;
+  hbb->label_ref.kind = BRIG_KIND_OPERAND_CODE_REF;
   return hbb;
 }
 
diff --git a/gcc/hsa.h b/gcc/hsa.h
index a14f38c..fb66fc4 100644
--- a/gcc/hsa.h
+++ b/gcc/hsa.h
@@ -27,11 +27,6 @@  along with GCC; see the file COPYING3.  If not see
 #include "hash-table.h"
 #include "basic-block.h"
 
-#define HSA_C_REGISTER_COUNT 8
-#define HSA_S_REGISTER_COUNT 128
-#define HSA_D_REGISTER_COUNT 64
-#define HSA_Q_REGISTER_COUNT 32
-
 struct hsa_insn_basic;
 typedef hsa_insn_basic *hsa_insn_basic_p;
 
@@ -78,7 +73,7 @@  struct hsa_op_base
   unsigned offset;
 
   /* The type of a particular operand.  */
-  BrigOperandKinds16_t kind;
+  BrigKinds16_t kind;
 };
 
 /* An immediate HSA operand.  */
@@ -87,6 +82,11 @@  struct hsa_op_immed : public hsa_op_base
 {
   /* Type of the. */
   BrigType16_t type;
+
+  /* Offset to which the associated immediate operand structure will be written.
+     Zero if not yet scheduled for writing */
+  unsigned offset;
+
   /* Value as represented by middle end.  */
   tree value;
 };
@@ -98,7 +98,7 @@  template <>
 inline bool
 is_a_helper <hsa_op_immed *>::test (hsa_op_base *p)
 {
-  return p->kind == BRIG_OPERAND_IMMED;
+  return p->kind == BRIG_KIND_OPERAND_DATA;
 }
 
 /* HSA register operand.  */
@@ -131,6 +131,7 @@  struct hsa_op_reg : public hsa_op_base
      class). */
   char hard_num;
 };
+
 typedef struct hsa_op_reg *hsa_op_reg_p;
 
 /* Report whether or not P is a register operand.  */
@@ -140,7 +141,7 @@  template <>
 inline bool
 is_a_helper <hsa_op_reg *>::test (hsa_op_base *p)
 {
-  return p->kind == BRIG_OPERAND_REG;
+  return p->kind == BRIG_KIND_OPERAND_REG;
 }
 
 /* An address HSA operand.  */
@@ -164,7 +165,7 @@  template <>
 inline bool
 is_a_helper <hsa_op_address *>::test (hsa_op_base *p)
 {
-  return p->kind == BRIG_OPERAND_ADDRESS;
+  return p->kind == BRIG_KIND_OPERAND_ADDRESS;
 }
 
 /* A reference-to-label HSA operand.  In reality this is a reference to a start
@@ -183,7 +184,7 @@  template <>
 inline bool
 is_a_helper <hsa_op_label *>::test (hsa_op_base *p)
 {
-  return p->kind == BRIG_OPERAND_LABEL_REF;
+  return p->kind == BRIG_KIND_OPERAND_CODE_REF;
 }
 
 #define HSA_OPERANDS_PER_INSN 5
@@ -254,7 +255,7 @@  template <>
 inline bool
 is_a_helper <hsa_insn_br *>::test (hsa_insn_basic *p)
 {
-  return p->opcode == BRIG_OPCODE_BRN
+  return p->opcode == BRIG_OPCODE_BR
     || p->opcode == BRIG_OPCODE_CBR;
 }
 
@@ -291,7 +292,10 @@  struct hsa_insn_mem : public hsa_insn_basic
   uint8_t equiv_class;
 
   /* Things like aquire/release/aligned.  */
-  enum BrigMemorySemantic semantic;
+  enum BrigMemoryOrder memoryorder;
+
+  /* Scope of the atomic opeeration. */
+  enum BrigMemoryScope memoryscope;
 
   /* TODO:  Add width modifier, perhaps also other things.  */
 };