/*
 * Copyright 2021 Alyssa Rosenzweig
 * SPDX-License-Identifier: MIT
 */

#include "agx_compiler.h"
#include "agx_opcodes.h"

/* Binary patches needed for branch offsets */
struct agx_branch_fixup {
   /* Offset into the binary to patch */
   off_t offset;

   /* Value to patch with will be block->offset */
   agx_block *block;

   /* If true, skips to the last instruction of the target block */
   bool skip_to_end;
};

static void
pack_assert_internal(const agx_instr *I, bool condition, const char *msg)
{
   if (!condition) {
      fprintf(stderr, "Packing assertion failed for instruction:\n\n");
      agx_print_instr(I, stderr);
      fprintf(stderr, "\n%s\n", msg);
      abort();
   }
}

#define pack_assert_msg(I, cond, msg)                                          \
   pack_assert_internal(I, cond, msg ": " #cond)

#define pack_assert(I, cond) pack_assert_internal(I, cond, #cond)

static void
assert_register_is_aligned(const agx_instr *I, agx_index reg)
{
   pack_assert_msg(I, reg.type == AGX_INDEX_REGISTER, "expecting a register");

   switch (reg.size) {
   case AGX_SIZE_16:
      return;
   case AGX_SIZE_32:
      pack_assert_msg(I, (reg.value & 1) == 0, "unaligned reg");
      return;
   case AGX_SIZE_64:
      pack_assert_msg(I, (reg.value & 3) == 0, "unaligned reg");
      return;
   }

   unreachable("Invalid register size");
}

/* Texturing has its own operands */
static unsigned
agx_pack_sample_coords(const agx_instr *I, agx_index index, bool *flag,
                       bool *is_16)
{
   /* TODO: Do we have a use case for 16-bit coords? */
   pack_assert_msg(I, index.size == AGX_SIZE_32, "32-bit coordinates");
   pack_assert_msg(I, index.value < 0x100, "coordinate register bound");

   *is_16 = false;
   *flag = index.discard;
   return index.value;
}

static unsigned
agx_pack_texture(const agx_instr *I, agx_index base, agx_index index,
                 unsigned *packed_base, unsigned *flag)
{
   if (base.type == AGX_INDEX_IMMEDIATE) {
      pack_assert(I, base.value == 0);

      /* Texture state registers */
      *packed_base = 0;

      if (index.type == AGX_INDEX_REGISTER) {
         pack_assert(I, index.size == AGX_SIZE_16);
         *flag = 1;
      } else {
         pack_assert(I, index.type == AGX_INDEX_IMMEDIATE);
         *flag = 0;
      }
   } else {
      pack_assert(I, base.type == AGX_INDEX_UNIFORM);
      pack_assert(I, base.size == AGX_SIZE_64);
      pack_assert(I, (base.value & 3) == 0);
      pack_assert(I, index.size == AGX_SIZE_32);

      /* Bindless */
      *packed_base = base.value >> 2;
      *flag = 3;
   }

   return index.value;
}

static unsigned
agx_pack_sampler(const agx_instr *I, agx_index index, bool *flag)
{
   if (index.type == AGX_INDEX_REGISTER) {
      pack_assert(I, index.size == AGX_SIZE_16);
      *flag = 1;
   } else {
      pack_assert(I, index.type == AGX_INDEX_IMMEDIATE);
      *flag = 0;
   }

   return index.value;
}

static unsigned
agx_pack_sample_compare_offset(const agx_instr *I, agx_index index)
{
   if (index.type == AGX_INDEX_NULL)
      return 0;

   pack_assert(I, index.size == AGX_SIZE_32);
   pack_assert(I, index.value < 0x100);
   assert_register_is_aligned(I, index);
   return index.value;
}

static unsigned
agx_pack_lod(const agx_instr *I, agx_index index, unsigned *lod_mode)
{
   /* For automatic LOD, the LOD field is unused. Assert as much. */
   if ((*lod_mode) == AGX_LOD_MODE_AUTO_LOD) {
      pack_assert(I, index.type == AGX_INDEX_IMMEDIATE);
      pack_assert(I, index.value == 0);
      return 0;
   }

   if (index.type == AGX_INDEX_UNIFORM) {
      /* Translate LOD mode from register mode to uniform mode */
      pack_assert(I,
                  ((*lod_mode) & BITFIELD_BIT(2)) && "must start as reg mode");
      *lod_mode = (*lod_mode) & ~BITFIELD_BIT(2);
      pack_assert(I, index.value < 0x200);
   } else {
      /* Otherwise must be registers */
      pack_assert(I, index.type == AGX_INDEX_REGISTER);
      pack_assert(I, index.value < 0x100);
   }

   return index.value;
}

static unsigned
agx_pack_pbe_source(const agx_instr *I, agx_index index, bool *flag)
{
   pack_assert(I, index.size == AGX_SIZE_16 || index.size == AGX_SIZE_32);
   assert_register_is_aligned(I, index);

   *flag = (index.size == AGX_SIZE_32);
   return index.value;
}

static unsigned
agx_pack_pbe_lod(const agx_instr *I, agx_index index, bool *flag)
{
   pack_assert(I, index.size == AGX_SIZE_16);

   if (index.type == AGX_INDEX_IMMEDIATE)
      *flag = true;
   else if (index.type == AGX_INDEX_REGISTER)
      *flag = false;
   else
      unreachable("Invalid PBE LOD type");

   return index.value;
}

/* Load/stores have their own operands */

static unsigned
agx_pack_memory_reg(const agx_instr *I, agx_index index, bool *flag)
{
   assert_register_is_aligned(I, index);

   *flag = (index.size >= AGX_SIZE_32);
   return index.value;
}

static unsigned
agx_pack_memory_base(const agx_instr *I, agx_index index, bool *flag)
{
   pack_assert(I, index.size == AGX_SIZE_64);
   pack_assert(I, (index.value & 1) == 0);

   /* Can't seem to access high uniforms from memory instructions */
   pack_assert(I, index.value < 0x100);

   if (index.type == AGX_INDEX_UNIFORM) {
      *flag = 1;
   } else {
      pack_assert(I, index.type == AGX_INDEX_REGISTER);
      *flag = 0;
   }

   return index.value;
}

static unsigned
agx_pack_memory_index(const agx_instr *I, agx_index index, bool *flag)
{
   if (index.type == AGX_INDEX_IMMEDIATE) {
      pack_assert(I, index.value < 0x10000);
      *flag = 1;

      return index.value;
   } else {
      pack_assert(I, index.type == AGX_INDEX_REGISTER);
      pack_assert(I, index.size == AGX_SIZE_32);
      pack_assert(I, (index.value & 1) == 0);
      pack_assert(I, index.value < 0x100);

      *flag = 0;
      return index.value;
   }
}

static uint16_t
agx_pack_local_base(const agx_instr *I, agx_index index, unsigned *flags)
{
   pack_assert(I, index.size == AGX_SIZE_16);

   if (index.type == AGX_INDEX_IMMEDIATE) {
      pack_assert(I, index.value == 0);
      *flags = 2;
      return 0;
   } else if (index.type == AGX_INDEX_UNIFORM) {
      *flags = 1 | ((index.value >> 8) << 1);
      return index.value & BITFIELD_MASK(8);
   } else {
      assert_register_is_aligned(I, index);
      *flags = 0;
      return index.value;
   }
}

static uint16_t
agx_pack_local_index(const agx_instr *I, agx_index index, bool *flag)
{
   pack_assert(I, index.size == AGX_SIZE_16);

   if (index.type == AGX_INDEX_IMMEDIATE) {
      pack_assert(I, index.value < 0x10000);
      *flag = 1;
      return index.value;
   } else {
      assert_register_is_aligned(I, index);
      *flag = 0;
      return index.value;
   }
}

static unsigned
agx_pack_atomic_source(const agx_instr *I, agx_index index)
{
   pack_assert_msg(I, index.size == AGX_SIZE_32, "no 64-bit atomics yet");
   assert_register_is_aligned(I, index);
   return index.value;
}

static unsigned
agx_pack_atomic_dest(const agx_instr *I, agx_index index, bool *flag)
{
   /* Atomic destinstions are optional (e.g. for update with no return) */
   if (index.type == AGX_INDEX_NULL) {
      *flag = 0;
      return 0;
   }

   /* But are otherwise registers */
   pack_assert_msg(I, index.size == AGX_SIZE_32, "no 64-bit atomics yet");
   assert_register_is_aligned(I, index);
   *flag = 1;
   return index.value;
}

/* ALU goes through a common path */

static unsigned
agx_pack_alu_dst(const agx_instr *I, agx_index dest)
{
   assert_register_is_aligned(I, dest);
   unsigned reg = dest.value;
   enum agx_size size = dest.size;
   pack_assert(I, reg < 0x100);

   return (dest.cache ? (1 << 0) : 0) | ((size >= AGX_SIZE_32) ? (1 << 1) : 0) |
          ((size == AGX_SIZE_64) ? (1 << 2) : 0) | ((reg << 2));
}

static unsigned
agx_pack_alu_src(const agx_instr *I, agx_index src)
{
   unsigned value = src.value;
   enum agx_size size = src.size;

   if (src.type == AGX_INDEX_IMMEDIATE) {
      /* Flags 0 for an 8-bit immediate */
      pack_assert(I, value < 0x100);

      return (value & BITFIELD_MASK(6)) | ((value >> 6) << 10);
   } else if (src.type == AGX_INDEX_UNIFORM) {
      pack_assert(I, size == AGX_SIZE_16 || size == AGX_SIZE_32);
      pack_assert(I, value < AGX_NUM_UNIFORMS);

      return (value & BITFIELD_MASK(6)) |
             ((value & BITFIELD_BIT(8)) ? (1 << 6) : 0) |
             ((size == AGX_SIZE_32) ? (1 << 7) : 0) | (0x1 << 8) |
             (((value >> 6) & BITFIELD_MASK(2)) << 10);
   } else {
      assert_register_is_aligned(I, src);
      pack_assert(I, !(src.cache && src.discard));

      unsigned hint = src.discard ? 0x3 : src.cache ? 0x2 : 0x1;
      unsigned size_flag = (size == AGX_SIZE_64)   ? 0x3
                           : (size == AGX_SIZE_32) ? 0x2
                           : (size == AGX_SIZE_16) ? 0x0
                                                   : 0x0;

      return (value & BITFIELD_MASK(6)) | (hint << 6) | (size_flag << 8) |
             (((value >> 6) & BITFIELD_MASK(2)) << 10);
   }
}

static unsigned
agx_pack_cmpsel_src(const agx_instr *I, agx_index src, enum agx_size dest_size)
{
   unsigned value = src.value;
   ASSERTED enum agx_size size = src.size;

   if (src.type == AGX_INDEX_IMMEDIATE) {
      /* Flags 0x4 for an 8-bit immediate */
      pack_assert(I, value < 0x100);

      return (value & BITFIELD_MASK(6)) | (0x4 << 6) | ((value >> 6) << 10);
   } else if (src.type == AGX_INDEX_UNIFORM) {
      pack_assert(I, size == AGX_SIZE_16 || size == AGX_SIZE_32);
      pack_assert(I, size == dest_size);
      pack_assert(I, value < 0x200);

      return (value & BITFIELD_MASK(6)) | ((value >> 8) << 6) | (0x3 << 7) |
             (((value >> 6) & BITFIELD_MASK(2)) << 10);
   } else {
      pack_assert(I, src.type == AGX_INDEX_REGISTER);
      pack_assert(I, !(src.cache && src.discard));
      pack_assert(I, size == AGX_SIZE_16 || size == AGX_SIZE_32);
      pack_assert(I, size == dest_size);
      assert_register_is_aligned(I, src);

      unsigned hint = src.discard ? 0x3 : src.cache ? 0x2 : 0x1;

      return (value & BITFIELD_MASK(6)) | (hint << 6) |
             (((value >> 6) & BITFIELD_MASK(2)) << 10);
   }
}

static unsigned
agx_pack_sample_mask_src(const agx_instr *I, agx_index src)
{
   unsigned value = src.value;
   unsigned packed_value =
      (value & BITFIELD_MASK(6)) | (((value >> 6) & BITFIELD_MASK(2)) << 10);

   if (src.type == AGX_INDEX_IMMEDIATE) {
      pack_assert(I, value < 0x100);
      return packed_value | (1 << 7);
   } else {
      pack_assert(I, src.type == AGX_INDEX_REGISTER);
      assert_register_is_aligned(I, src);
      pack_assert(I, !(src.cache && src.discard));

      return packed_value;
   }
}

static unsigned
agx_pack_float_mod(agx_index src)
{
   return (src.abs ? (1 << 0) : 0) | (src.neg ? (1 << 1) : 0);
}

static bool
agx_all_16(agx_instr *I)
{
   agx_foreach_dest(I, d) {
      if (!agx_is_null(I->dest[d]) && I->dest[d].size != AGX_SIZE_16)
         return false;
   }

   agx_foreach_src(I, s) {
      if (!agx_is_null(I->src[s]) && I->src[s].size != AGX_SIZE_16)
         return false;
   }

   return true;
}

/* Generic pack for ALU instructions, which are quite regular */

static void
agx_pack_alu(struct util_dynarray *emission, agx_instr *I)
{
   struct agx_opcode_info info = agx_opcodes_info[I->op];
   struct agx_encoding encoding = info.encoding;

   bool is_f16 = (I->op == AGX_OPCODE_HMUL || I->op == AGX_OPCODE_HFMA ||
                  I->op == AGX_OPCODE_HADD);

   pack_assert_msg(I, encoding.exact, "invalid encoding");

   uint64_t raw = encoding.exact;
   uint16_t extend = 0;

   // TODO: assert saturable
   if (I->saturate)
      raw |= (1 << 6);

   if (info.nr_dests) {
      pack_assert(I, info.nr_dests == 1);
      unsigned D = agx_pack_alu_dst(I, I->dest[0]);
      unsigned extend_offset = (sizeof(extend) * 8) - 4;

      raw |= (D & BITFIELD_MASK(8)) << 7;
      extend |= ((D >> 8) << extend_offset);

      if (info.immediates & AGX_IMMEDIATE_INVERT_COND) {
         raw |= (uint64_t)(I->invert_cond) << 47;
      }
   } else if (info.immediates & AGX_IMMEDIATE_NEST) {
      raw |= (I->invert_cond << 8);
      raw |= (I->nest << 11);
      raw |= (I->icond << 13);
   }

   for (unsigned s = 0; s < info.nr_srcs; ++s) {
      bool is_cmpsel = (s >= 2) && (I->op == AGX_OPCODE_ICMPSEL ||
                                    I->op == AGX_OPCODE_FCMPSEL);

      unsigned src = is_cmpsel
                        ? agx_pack_cmpsel_src(I, I->src[s], I->dest[0].size)
                        : agx_pack_alu_src(I, I->src[s]);

      unsigned src_short = (src & BITFIELD_MASK(10));
      unsigned src_extend = (src >> 10);

      /* Size bit always zero and so omitted for 16-bit */
      if (is_f16 && !is_cmpsel)
         pack_assert(I, (src_short & (1 << 9)) == 0);

      if (info.is_float || (I->op == AGX_OPCODE_FCMPSEL && !is_cmpsel)) {
         unsigned fmod = agx_pack_float_mod(I->src[s]);
         unsigned fmod_offset = is_f16 ? 9 : 10;
         src_short |= (fmod << fmod_offset);
      } else if (I->op == AGX_OPCODE_IMAD || I->op == AGX_OPCODE_IADD) {
         /* Force unsigned for immediates so uadd_sat works properly */
         bool zext = I->src[s].abs || I->src[s].type == AGX_INDEX_IMMEDIATE;
         bool extends = I->src[s].size < AGX_SIZE_64;

         unsigned sxt = (extends && !zext) ? (1 << 10) : 0;

         unsigned negate_src = (I->op == AGX_OPCODE_IMAD) ? 2 : 1;
         pack_assert(I, !I->src[s].neg || s == negate_src);
         src_short |= sxt;
      }

      /* Sources come at predictable offsets */
      unsigned offset = 16 + (12 * s);
      raw |= (((uint64_t)src_short) << offset);

      /* Destination and each source get extended in reverse order */
      unsigned extend_offset = (sizeof(extend) * 8) - ((s + 3) * 2);
      extend |= (src_extend << extend_offset);
   }

   if ((I->op == AGX_OPCODE_IMAD && I->src[2].neg) ||
       (I->op == AGX_OPCODE_IADD && I->src[1].neg))
      raw |= (1 << 27);

   if (info.immediates & AGX_IMMEDIATE_TRUTH_TABLE) {
      raw |= (I->truth_table & 0x3) << 26;
      raw |= (uint64_t)(I->truth_table >> 2) << 38;
   } else if (info.immediates & AGX_IMMEDIATE_SHIFT) {
      pack_assert(I, I->shift <= 4);
      raw |= (uint64_t)(I->shift & 1) << 39;
      raw |= (uint64_t)(I->shift >> 1) << 52;
   } else if (info.immediates & AGX_IMMEDIATE_BFI_MASK) {
      raw |= (uint64_t)(I->bfi_mask & 0x3) << 38;
      raw |= (uint64_t)((I->bfi_mask >> 2) & 0x3) << 50;
      raw |= (uint64_t)((I->bfi_mask >> 4) & 0x1) << 63;
   } else if (info.immediates & AGX_IMMEDIATE_SIMD_OP) {
      raw |= (uint64_t)(I->simd_op & 0x1) << 28;
      raw |= (uint64_t)((I->simd_op >> 1) & 0x7) << 38;
      raw |= (uint64_t)((I->simd_op >> 4) & 0x1) << 47;
   } else if (info.immediates & AGX_IMMEDIATE_SR) {
      raw |= (uint64_t)(I->sr & 0x3F) << 16;
      raw |= (uint64_t)(I->sr >> 6) << 26;
   } else if (info.immediates & AGX_IMMEDIATE_WRITEOUT)
      raw |= (uint64_t)(I->imm) << 8;
   else if (info.immediates & AGX_IMMEDIATE_IMM)
      raw |= (uint64_t)(I->imm) << 16;
   else if (info.immediates & AGX_IMMEDIATE_ROUND)
      raw |= (uint64_t)(I->imm) << 26;
   else if (info.immediates & (AGX_IMMEDIATE_FCOND | AGX_IMMEDIATE_ICOND))
      raw |= (uint64_t)(I->fcond) << 61;

   /* Determine length bit */
   unsigned length = encoding.length_short;
   if (I->op == AGX_OPCODE_MOV_IMM && I->dest[0].size == AGX_SIZE_16)
      length -= 2;

   uint64_t short_mask = BITFIELD64_MASK(8 * length);
   bool length_bit = (extend || (raw & ~short_mask));

   if (encoding.extensible && length_bit) {
      raw |= (1 << 15);
      length += (length > 8) ? 4 : 2;
   }

   /* Pack! */
   if (length <= sizeof(uint64_t)) {
      unsigned extend_offset = ((length - sizeof(extend)) * 8);

      /* XXX: Encode these special cases better */
      switch (I->op) {
      case AGX_OPCODE_IADD:
      case AGX_OPCODE_ICMP_BALLOT:
      case AGX_OPCODE_ICMP_QUAD_BALLOT:
      case AGX_OPCODE_FCMP_BALLOT:
      case AGX_OPCODE_FCMP_QUAD_BALLOT:
         extend_offset -= 16;
         break;
      default:
         break;
      }

      raw |= (uint64_t)extend << extend_offset;
      memcpy(util_dynarray_grow_bytes(emission, 1, length), &raw, length);
   } else {
      /* So far, >8 byte ALU is only to store the extend bits */
      unsigned extend_offset = (((length - sizeof(extend)) * 8) - 64);
      unsigned hi = ((uint64_t)extend) << extend_offset;

      memcpy(util_dynarray_grow_bytes(emission, 1, 8), &raw, 8);
      memcpy(util_dynarray_grow_bytes(emission, 1, length - 8), &hi,
             length - 8);
   }
}

static void
agx_pack_instr(struct util_dynarray *emission, struct util_dynarray *fixups,
               agx_instr *I, enum u_tristate needs_g13x_coherency)
{
   switch (I->op) {
   case AGX_OPCODE_LD_TILE:
   case AGX_OPCODE_ST_TILE: {
      bool load = (I->op == AGX_OPCODE_LD_TILE);
      unsigned D = agx_pack_alu_dst(I, load ? I->dest[0] : I->src[0]);
      pack_assert(I, I->mask < 0x10);
      pack_assert(I, I->pixel_offset < 0x200);

      agx_index sample_index = load ? I->src[0] : I->src[1];
      agx_index coords = load ? I->src[1] : I->src[2];
      pack_assert(I, sample_index.type == AGX_INDEX_REGISTER ||
                        sample_index.type == AGX_INDEX_IMMEDIATE);
      pack_assert(I, sample_index.size == AGX_SIZE_16);
      unsigned St = (sample_index.type == AGX_INDEX_REGISTER) ? 1 : 0;
      unsigned S = sample_index.value;
      pack_assert(I, S < 0x100);

      pack_assert(I, I->explicit_coords == (coords.type == AGX_INDEX_REGISTER));
      unsigned C = I->explicit_coords ? coords.value : 0;

      uint64_t raw = agx_opcodes_info[I->op].encoding.exact |
                     ((uint64_t)(D & BITFIELD_MASK(8)) << 7) | (St << 22) |
                     ((uint64_t)(I->format) << 24) |
                     ((uint64_t)(C & BITFIELD_MASK(6)) << 16) |
                     ((uint64_t)(I->pixel_offset & BITFIELD_MASK(7)) << 28) |
                     (load || I->explicit_coords ? (1ull << 35) : 0) |
                     ((uint64_t)(I->mask) << 36) |
                     ((uint64_t)(I->pixel_offset >> 7) << 40) |
                     ((uint64_t)(S & BITFIELD_MASK(6)) << 42) |
                     (I->explicit_coords ? (1ull << 55) : 0) |
                     ((uint64_t)(S >> 6) << 56) | ((uint64_t)(C >> 6) << 58) |
                     (((uint64_t)(D >> 8)) << 60);

      unsigned size = 8;
      memcpy(util_dynarray_grow_bytes(emission, 1, size), &raw, size);
      break;
   }

   case AGX_OPCODE_SAMPLE_MASK: {
      unsigned S = agx_pack_sample_mask_src(I, I->src[1]);
      unsigned T = I->src[0].value;
      bool Tt = I->src[0].type == AGX_INDEX_IMMEDIATE;
      pack_assert(I, Tt || I->src[0].type == AGX_INDEX_REGISTER);
      uint32_t raw = 0xc1 | (Tt ? BITFIELD_BIT(8) : 0) |
                     ((T & BITFIELD_MASK(6)) << 9) | ((S & 0xff) << 16) |
                     ((T >> 6) << 24) | ((S >> 8) << 26);

      unsigned size = 4;
      memcpy(util_dynarray_grow_bytes(emission, 1, size), &raw, size);
      break;
   }

   case AGX_OPCODE_WAIT: {
      uint64_t raw =
         agx_opcodes_info[I->op].encoding.exact | (I->scoreboard << 8);

      unsigned size = 2;
      memcpy(util_dynarray_grow_bytes(emission, 1, size), &raw, size);
      break;
   }

   case AGX_OPCODE_ITER:
   case AGX_OPCODE_ITERPROJ:
   case AGX_OPCODE_LDCF: {
      bool flat = (I->op == AGX_OPCODE_LDCF);
      bool perspective = (I->op == AGX_OPCODE_ITERPROJ);
      unsigned D = agx_pack_alu_dst(I, I->dest[0]);
      unsigned channels = (I->channels & 0x3);

      agx_index src_I = I->src[0];
      pack_assert(I, src_I.type == AGX_INDEX_IMMEDIATE ||
                        src_I.type == AGX_INDEX_REGISTER);

      unsigned cf_I = src_I.value;
      unsigned cf_J = 0;

      if (perspective) {
         agx_index src_J = I->src[1];
         pack_assert(I, src_J.type == AGX_INDEX_IMMEDIATE);
         cf_J = src_J.value;
      }

      pack_assert(I, cf_I < 0x100);
      pack_assert(I, cf_J < 0x100);

      enum agx_interpolation interp = I->interpolation;
      agx_index sample_index = flat ? agx_null() : I->src[perspective ? 2 : 1];

      /* Fix up the interpolation enum to distinguish the sample index source */
      if (interp == AGX_INTERPOLATION_SAMPLE) {
         if (sample_index.type == AGX_INDEX_REGISTER)
            interp = AGX_INTERPOLATION_SAMPLE_REGISTER;
         else
            pack_assert(I, sample_index.type == AGX_INDEX_IMMEDIATE);
      } else {
         sample_index = agx_zero();
      }

      bool kill = false;    // TODO: optimize
      bool forward = false; // TODO: optimize

      uint64_t raw =
         0x21 | (flat ? (1 << 7) : 0) | (perspective ? (1 << 6) : 0) |
         ((D & 0xFF) << 7) | (1ull << 15) | /* XXX */
         ((cf_I & BITFIELD_MASK(6)) << 16) |
         ((src_I.type == AGX_INDEX_REGISTER) ? (1 << 23) : 0) |
         ((cf_J & BITFIELD_MASK(6)) << 24) | (((uint64_t)channels) << 30) |
         (((uint64_t)sample_index.value) << 32) | (forward ? (1ull << 46) : 0) |
         (((uint64_t)interp) << 48) | (kill ? (1ull << 52) : 0) |
         (((uint64_t)(D >> 8)) << 56) | ((uint64_t)(cf_I >> 6) << 58) |
         ((uint64_t)(cf_J >> 6) << 60);

      unsigned size = 8;
      memcpy(util_dynarray_grow_bytes(emission, 1, size), &raw, size);
      break;
   }

   case AGX_OPCODE_ST_VARY: {
      agx_index index_src = I->src[0];
      agx_index value = I->src[1];

      pack_assert(I, index_src.type == AGX_INDEX_IMMEDIATE ||
                        index_src.type == AGX_INDEX_REGISTER);
      pack_assert(I, index_src.value < BITFIELD_MASK(8));
      pack_assert(I, value.type == AGX_INDEX_REGISTER);
      pack_assert(I, value.size == AGX_SIZE_32);

      uint64_t raw = 0x11 | (I->last ? (1 << 7) : 0) |
                     ((value.value & 0x3F) << 9) |
                     (((uint64_t)(index_src.value & 0x3F)) << 16) |
                     (index_src.type == AGX_INDEX_IMMEDIATE ? (1 << 23) : 0) |
                     ((value.value >> 6) << 24) |
                     ((index_src.value >> 6) << 26) | (0x8u << 28); /* XXX */

      unsigned size = 4;
      memcpy(util_dynarray_grow_bytes(emission, 1, size), &raw, size);
      break;
   }

   case AGX_OPCODE_DEVICE_LOAD:
   case AGX_OPCODE_DEVICE_STORE:
   case AGX_OPCODE_UNIFORM_STORE: {
      bool is_device_store = I->op == AGX_OPCODE_DEVICE_STORE;
      bool is_uniform_store = I->op == AGX_OPCODE_UNIFORM_STORE;
      bool is_store = is_device_store || is_uniform_store;
      bool has_base = !is_uniform_store;

      /* Uniform stores are required to be 16-bit. The encoding that should be
       * 32-bit annoyingly doesn't work. Fix up the format and size so we can
       * use scalar 32-bit values in the IR and avoid special casing earlier in
       * the compiler.
       */
      enum agx_format format = is_uniform_store ? AGX_FORMAT_I16 : I->format;
      agx_index reg = is_store ? I->src[0] : I->dest[0];
      unsigned mask = I->mask;

      if (is_uniform_store && reg.size != AGX_SIZE_16) {
         if (reg.size == AGX_SIZE_64) {
            assert(mask == 1);
            mask = BITFIELD_MASK(4);
         } else {
            assert(reg.size == AGX_SIZE_32);
            assert(mask == 1 || mask == 3);
            mask = BITFIELD_MASK(mask == 3 ? 4 : 2);
         }

         reg.size = AGX_SIZE_16;
      }

      unsigned offset_src = (has_base ? 1 : 0) + (is_store ? 1 : 0);

      bool Rt, At = false, Ot;
      unsigned R = agx_pack_memory_reg(I, reg, &Rt);
      unsigned A =
         has_base ? agx_pack_memory_base(I, I->src[is_store ? 1 : 0], &At) : 0;
      unsigned O = agx_pack_memory_index(I, I->src[offset_src], &Ot);
      unsigned u1 = is_uniform_store ? 0 : 1; // XXX
      unsigned u3 = 0;
      unsigned u4 = is_uniform_store ? 0 : I->coherent ? 7 : 4;
      unsigned u5 = 0;
      bool L = true; /* TODO: when would you want short? */

      pack_assert(I, mask != 0);
      pack_assert(I, format <= 0x10);

      uint64_t raw =
         agx_opcodes_info[I->op].encoding.exact |
         ((format & BITFIELD_MASK(3)) << 7) | ((R & BITFIELD_MASK(6)) << 10) |
         ((A & BITFIELD_MASK(4)) << 16) | ((O & BITFIELD_MASK(4)) << 20) |
         (Ot ? (1 << 24) : 0) | (I->src[offset_src].abs ? (1 << 25) : 0) |
         (is_uniform_store ? (2 << 25) : 0) | (u1 << 26) | (At << 27) |
         (u3 << 28) | (I->scoreboard << 30) |
         (((uint64_t)((O >> 4) & BITFIELD_MASK(4))) << 32) |
         (((uint64_t)((A >> 4) & BITFIELD_MASK(4))) << 36) |
         (((uint64_t)((R >> 6) & BITFIELD_MASK(2))) << 40) |
         (((uint64_t)I->shift) << 42) | (((uint64_t)u4) << 44) |
         (L ? (1ull << 47) : 0) | (((uint64_t)(format >> 3)) << 48) |
         (((uint64_t)Rt) << 49) | (((uint64_t)u5) << 50) |
         (((uint64_t)mask) << 52) | (((uint64_t)(O >> 8)) << 56);

      unsigned size = L ? 8 : 6;
      memcpy(util_dynarray_grow_bytes(emission, 1, size), &raw, size);
      break;
   }

   case AGX_OPCODE_LOCAL_LOAD:
   case AGX_OPCODE_LOCAL_STORE: {
      bool is_load = I->op == AGX_OPCODE_LOCAL_LOAD;
      bool L = true; /* TODO: when would you want short? */
      unsigned At;
      bool Rt, Ot;

      unsigned R =
         agx_pack_memory_reg(I, is_load ? I->dest[0] : I->src[0], &Rt);
      unsigned A = agx_pack_local_base(I, is_load ? I->src[0] : I->src[1], &At);
      unsigned O =
         agx_pack_local_index(I, is_load ? I->src[1] : I->src[2], &Ot);

      uint64_t raw =
         agx_opcodes_info[I->op].encoding.exact | (Rt ? BITFIELD64_BIT(8) : 0) |
         ((R & BITFIELD_MASK(6)) << 9) | (L ? BITFIELD64_BIT(15) : 0) |
         ((A & BITFIELD_MASK(6)) << 16) | (At << 22) | (I->format << 24) |
         ((O & BITFIELD64_MASK(6)) << 28) | (Ot ? BITFIELD64_BIT(34) : 0) |
         (((uint64_t)I->mask) << 36) | (((uint64_t)(O >> 6)) << 48) |
         (((uint64_t)(A >> 6)) << 58) | (((uint64_t)(R >> 6)) << 60);

      unsigned size = L ? 8 : 6;
      memcpy(util_dynarray_grow_bytes(emission, 1, size), &raw, size);
      break;
   }

   case AGX_OPCODE_ATOMIC: {
      bool At, Ot, Rt;
      unsigned A = agx_pack_memory_base(I, I->src[1], &At);
      unsigned O = agx_pack_memory_index(I, I->src[2], &Ot);
      unsigned R = agx_pack_atomic_dest(I, I->dest[0], &Rt);
      unsigned S = agx_pack_atomic_source(I, I->src[0]);

      /* Due to a hardware quirk, there is a bit in the atomic instruction that
       * differs based on the target GPU. So, if we're packing an atomic, the
       * shader must be keyed to a particular GPU (either needs_g13x_coherency
       * or not needs_g13x_coherency). Assert that here.
       *
       * needs_g13x_coherency == U_TRISTATE_UNSET is only allowed for shaders
       * that do not use atomics and are therefore portable across devices.
       */
      assert(needs_g13x_coherency != U_TRISTATE_UNSET);

      uint64_t raw =
         agx_opcodes_info[I->op].encoding.exact |
         (((uint64_t)I->atomic_opc) << 6) | ((R & BITFIELD_MASK(6)) << 10) |
         ((A & BITFIELD_MASK(4)) << 16) | ((O & BITFIELD_MASK(4)) << 20) |
         (Ot ? (1 << 24) : 0) | (I->src[2].abs ? (1 << 25) : 0) | (At << 27) |
         (I->scoreboard << 30) |
         (((uint64_t)((O >> 4) & BITFIELD_MASK(4))) << 32) |
         (((uint64_t)((A >> 4) & BITFIELD_MASK(4))) << 36) |
         (((uint64_t)(R >> 6)) << 40) |
         (needs_g13x_coherency == U_TRISTATE_YES ? BITFIELD64_BIT(45) : 0) |
         (Rt ? BITFIELD64_BIT(47) : 0) | (((uint64_t)S) << 48) |
         (((uint64_t)(O >> 8)) << 56);

      memcpy(util_dynarray_grow_bytes(emission, 1, 8), &raw, 8);
      break;
   }

   case AGX_OPCODE_LOCAL_ATOMIC: {
      bool L = true; /* TODO: Don't force */

      unsigned At;
      bool Rt = false, Ot;

      bool Ra = I->dest[0].type != AGX_INDEX_NULL;
      unsigned R = Ra ? agx_pack_memory_reg(I, I->dest[0], &Rt) : 0;
      unsigned S = agx_pack_atomic_source(I, I->src[0]);
      unsigned A = agx_pack_local_base(I, I->src[1], &At);
      unsigned O = agx_pack_local_index(I, I->src[2], &Ot);

      uint64_t raw =
         agx_opcodes_info[I->op].encoding.exact | (Rt ? BITFIELD64_BIT(8) : 0) |
         ((R & BITFIELD_MASK(6)) << 9) | (L ? BITFIELD64_BIT(15) : 0) |
         ((A & BITFIELD_MASK(6)) << 16) | (At << 22) |
         (((uint64_t)I->atomic_opc) << 24) | ((O & BITFIELD64_MASK(6)) << 28) |
         (Ot ? BITFIELD64_BIT(34) : 0) | (Ra ? BITFIELD64_BIT(38) : 0) |
         (((uint64_t)(O >> 6)) << 48) | (((uint64_t)(A >> 6)) << 58) |
         (((uint64_t)(R >> 6)) << 60);

      uint64_t raw2 = S;

      memcpy(util_dynarray_grow_bytes(emission, 1, 8), &raw, 8);
      memcpy(util_dynarray_grow_bytes(emission, 1, 2), &raw2, 2);
      break;
   }

   case AGX_OPCODE_TEXTURE_LOAD:
   case AGX_OPCODE_IMAGE_LOAD:
   case AGX_OPCODE_TEXTURE_SAMPLE: {
      pack_assert(I, I->mask != 0);
      pack_assert(I, I->format <= 0x10);

      bool Rt, Ct, St, Cs;
      unsigned Tt;
      unsigned U;
      enum agx_lod_mode lod_mode = I->lod_mode;

      unsigned R = agx_pack_memory_reg(I, I->dest[0], &Rt);
      unsigned C = agx_pack_sample_coords(I, I->src[0], &Ct, &Cs);
      unsigned T = agx_pack_texture(I, I->src[2], I->src[3], &U, &Tt);
      unsigned S = agx_pack_sampler(I, I->src[4], &St);
      unsigned O = agx_pack_sample_compare_offset(I, I->src[5]);
      unsigned D = agx_pack_lod(I, I->src[1], &lod_mode);

      unsigned q1 = I->shadow;
      unsigned q2 = I->query_lod ? 2 : 0;
      unsigned q3 = 0xc; // XXX
      unsigned kill = 0; // helper invocation kill bit

      /* Set bit 43 for image loads. This seems to makes sure that image loads
       * get the value written by the latest image store, not some other image
       * store that was already in flight, fixing
       *
       *    KHR-GLES31.core.shader_image_load_store.basic-glsl-misc-fs
       *
       * Apple seems to set this bit unconditionally for read/write image loads
       * and never for readonly image loads. Some sort of cache control.
       */
      if (I->op == AGX_OPCODE_IMAGE_LOAD) {
         q3 |= 1;

         /* Cache bypass for multidie coherency */
         if (I->coherent) {
            q3 |= 2;
         }
      }

      uint32_t extend = ((U & BITFIELD_MASK(5)) << 0) | (kill << 5) |
                        ((I->dim >> 3) << 7) | ((R >> 6) << 8) |
                        ((C >> 6) << 10) | ((D >> 6) << 12) | ((T >> 6) << 14) |
                        ((O & BITFIELD_MASK(6)) << 16) | (I->gather << 23) |
                        (I->offset << 27) | ((S >> 6) << 28) | ((O >> 6) << 30);

      bool L = (extend != 0);

      uint64_t raw =
         0x31 | ((I->op != AGX_OPCODE_TEXTURE_SAMPLE) ? (1 << 6) : 0) |
         (Rt ? (1 << 8) : 0) | ((R & BITFIELD_MASK(6)) << 9) |
         (L ? (1 << 15) : 0) | ((C & BITFIELD_MASK(6)) << 16) |
         (Ct ? (1 << 22) : 0) | (q1 << 23) | ((D & BITFIELD_MASK(6)) << 24) |
         (q2 << 30) | (((uint64_t)(T & BITFIELD_MASK(6))) << 32) |
         (((uint64_t)Tt) << 38) |
         (((uint64_t)(I->dim & BITFIELD_MASK(3))) << 40) |
         (((uint64_t)q3) << 43) | (((uint64_t)I->mask) << 48) |
         (((uint64_t)lod_mode) << 52) |
         (((uint64_t)(S & BITFIELD_MASK(6))) << 56) | (((uint64_t)St) << 62) |
         (((uint64_t)I->scoreboard) << 63);

      memcpy(util_dynarray_grow_bytes(emission, 1, 8), &raw, 8);
      if (L)
         memcpy(util_dynarray_grow_bytes(emission, 1, 4), &extend, 4);

      break;
   }

   case AGX_OPCODE_IMAGE_WRITE: {
      bool Ct, Dt, Rt, Cs;
      unsigned Tt;
      unsigned U;

      unsigned R = agx_pack_pbe_source(I, I->src[0], &Rt);
      unsigned C = agx_pack_sample_coords(I, I->src[1], &Ct, &Cs);
      unsigned D = agx_pack_pbe_lod(I, I->src[2], &Dt);
      unsigned T = agx_pack_texture(I, I->src[3], I->src[4], &U, &Tt);
      bool rtz = false;

      pack_assert(I, U < (1 << 5));
      pack_assert(I, D < (1 << 8));
      pack_assert(I, R < (1 << 8));
      pack_assert(I, C < (1 << 8));
      pack_assert(I, T < (1 << 8));
      pack_assert(I, Tt < (1 << 2));

      unsigned coherency = I->coherent ? 0xf : 0x9;

      uint64_t raw = agx_opcodes_info[I->op].encoding.exact |
                     (Rt ? (1 << 8) : 0) | ((R & BITFIELD_MASK(6)) << 9) |
                     ((C & BITFIELD_MASK(6)) << 16) | (Ct ? (1 << 22) : 0) |
                     ((D & BITFIELD_MASK(6)) << 24) | (Dt ? (1u << 31) : 0) |
                     (((uint64_t)(T & BITFIELD_MASK(6))) << 32) |
                     (((uint64_t)Tt) << 38) |
                     (((uint64_t)I->dim & BITFIELD_MASK(3)) << 40) |
                     (((uint64_t)coherency) << 43) | (Cs ? (1ull << 47) : 0) |
                     (((uint64_t)U) << 48) | (rtz ? (1ull << 53) : 0) |
                     ((I->dim & BITFIELD_BIT(4)) ? (1ull << 55) : 0) |
                     (((uint64_t)R >> 6) << 56) | (((uint64_t)C >> 6) << 58) |
                     (((uint64_t)D >> 6) << 60) | (((uint64_t)T >> 6) << 62);

      if (raw >> 48) {
         raw |= BITFIELD_BIT(15);
         memcpy(util_dynarray_grow_bytes(emission, 1, 8), &raw, 8);
      } else {
         memcpy(util_dynarray_grow_bytes(emission, 1, 6), &raw, 6);
      }

      break;
   }

   case AGX_OPCODE_BLOCK_IMAGE_STORE: {
      enum agx_format F = I->format;
      pack_assert(I, F < 0x10);

      unsigned Tt = 0;
      pack_assert(I, Tt < 0x4);

      unsigned U;
      unsigned T = agx_pack_texture(I, I->src[0], I->src[1], &U, &Tt);
      pack_assert(I, T < 0x100);
      pack_assert(I, U < (1 << 5));

      bool Cs = false;
      bool Ct = I->src[3].discard;
      unsigned C = I->src[3].value;

      agx_index offset = I->src[2];
      pack_assert(I, offset.size == AGX_SIZE_32);
      assert_register_is_aligned(I, offset);
      unsigned R = offset.value;

      bool unk1 = true;

      /* This bit has weird behaviour with the interaction of the texture state
       * index and the tilebuffer offset. Probably best not to use it for now.
       */
      unsigned unk3 = 1;

      uint32_t word0 = agx_opcodes_info[I->op].encoding.exact |
                       (1 << 15) /* we always set length bit for now */ |
                       ((F & 1) << 8) | ((R & BITFIELD_MASK(6)) << 9) |
                       ((C & BITFIELD_MASK(6)) << 16) | (Ct ? (1 << 22) : 0) |
                       (I->explicit_coords ? (1 << 23) : 0) |
                       (unk1 ? (1u << 31) : 0);

      uint32_t word1 = (T & BITFIELD_MASK(6)) | (Tt << 6) |
                       ((I->dim & BITFIELD_MASK(3)) << 8) | (9 << 11) |
                       (Cs ? (1 << 15) : 0) | (((uint64_t)U) << 16) |
                       ((I->dim & BITFIELD_BIT(3)) ? (1u << 23) : 0) |
                       ((R >> 6) << 24) | ((C >> 6) << 26);

      uint32_t word2 = (F >> 1) | (unk3 ? (1 << 3) : 0) | ((T >> 6) << 14);

      memcpy(util_dynarray_grow_bytes(emission, 1, 4), &word0, 4);
      memcpy(util_dynarray_grow_bytes(emission, 1, 4), &word1, 4);
      memcpy(util_dynarray_grow_bytes(emission, 1, 2), &word2, 2);
      break;
   }

   case AGX_OPCODE_ZS_EMIT: {
      agx_index S = I->src[0];
      if (S.type == AGX_INDEX_IMMEDIATE)
         pack_assert(I, S.value < BITFIELD_BIT(8));
      else
         assert_register_is_aligned(I, S);

      agx_index T = I->src[1];
      assert_register_is_aligned(I, T);

      pack_assert(I, I->zs >= 1 && I->zs <= 3);

      uint32_t word0 = agx_opcodes_info[I->op].encoding.exact |
                       ((S.type == AGX_INDEX_IMMEDIATE) ? (1 << 8) : 0) |
                       ((S.value & BITFIELD_MASK(6)) << 9) |
                       ((T.value & BITFIELD_MASK(6)) << 16) |
                       ((T.value >> 6) << 26) | ((S.value >> 6) << 24) |
                       (I->zs << 29);

      memcpy(util_dynarray_grow_bytes(emission, 1, 4), &word0, 4);
      break;
   }

   case AGX_OPCODE_JMP_EXEC_ANY:
   case AGX_OPCODE_JMP_EXEC_NONE:
   case AGX_OPCODE_JMP_EXEC_NONE_AFTER: {
      /* We don't implement indirect branches */
      pack_assert(I, I->target != NULL);

      /* We'll fix the offset later. */
      struct agx_branch_fixup fixup = {
         .block = I->target,
         .offset = emission->size,
         .skip_to_end = I->op == AGX_OPCODE_JMP_EXEC_NONE_AFTER,
      };

      util_dynarray_append(fixups, struct agx_branch_fixup, fixup);

      /* The rest of the instruction is fixed */
      struct agx_opcode_info info = agx_opcodes_info[I->op];
      uint64_t raw = info.encoding.exact;
      memcpy(util_dynarray_grow_bytes(emission, 1, 6), &raw, 6);
      break;
   }

   case AGX_OPCODE_DOORBELL: {
      pack_assert(I, I->imm < BITFIELD_MASK(8));
      struct agx_opcode_info info = agx_opcodes_info[I->op];
      uint64_t raw = info.encoding.exact | (I->imm << 40);
      memcpy(util_dynarray_grow_bytes(emission, 1, 6), &raw, 6);
      break;
   }

   case AGX_OPCODE_STACK_UNMAP:
   case AGX_OPCODE_STACK_MAP: {
      agx_index value = I->op == AGX_OPCODE_STACK_MAP ? I->src[0] : I->dest[0];

      pack_assert(I, value.type == AGX_INDEX_REGISTER);
      pack_assert(I, value.size == AGX_SIZE_32);
      pack_assert(I, I->imm < BITFIELD_MASK(16));

      unsigned q1 = 0;  // XXX
      unsigned q2 = 0;  // XXX
      unsigned q3 = 0;  // XXX
      unsigned q4 = 16; // XXX
      unsigned q5 = 16; // XXX

      struct agx_opcode_info info = agx_opcodes_info[I->op];
      uint64_t raw =
         info.encoding.exact | (q1 << 8) | ((value.value & 0x3F) << 10) |
         ((I->imm & 0xF) << 20) | (1ull << 24) | // XXX
         (1ull << 26) |                          // XXX
         (q2 << 30) | ((uint64_t)((I->imm >> 4) & 0xF) << 32) |
         ((uint64_t)q3 << 37) | ((uint64_t)(value.value >> 6) << 40) |
         ((uint64_t)q4 << 42) | (1ull << 47) | // XXX
         ((uint64_t)q5 << 48) | ((uint64_t)(I->imm >> 8) << 56);

      memcpy(util_dynarray_grow_bytes(emission, 1, 8), &raw, 8);
      break;
   }

   case AGX_OPCODE_STACK_LOAD:
   case AGX_OPCODE_STACK_STORE: {
      enum agx_format format = I->format;
      unsigned mask = I->mask;

      bool is_load = I->op == AGX_OPCODE_STACK_LOAD;
      bool L = true; /* TODO: when would you want short? */

      pack_assert(I, mask != 0);
      pack_assert(I, format <= 0x10);

      bool Rt, Ot;
      unsigned R =
         agx_pack_memory_reg(I, is_load ? I->dest[0] : I->src[0], &Rt);
      unsigned O =
         agx_pack_memory_index(I, is_load ? I->src[0] : I->src[1], &Ot);

      unsigned i1 = 1; // XXX
      unsigned i2 = 0; // XXX
      unsigned i5 = 4; // XXX

      uint64_t raw =
         agx_opcodes_info[I->op].encoding.exact |
         ((format & BITFIELD_MASK(2)) << 8) | ((R & BITFIELD_MASK(6)) << 10) |
         ((O & BITFIELD_MASK(4)) << 20) | (Ot ? (1 << 24) : 0) |
         ((uint64_t)i1 << 26) | ((uint64_t)I->scoreboard << 30) |
         (((uint64_t)((O >> 4) & BITFIELD_MASK(4))) << 32) |
         ((uint64_t)i2 << 36) |
         (((uint64_t)((R >> 6) & BITFIELD_MASK(2))) << 40) |
         ((uint64_t)i5 << 44) | (L ? (1ull << 47) : 0) |
         (((uint64_t)(format >> 2)) << 50) | (((uint64_t)Rt) << 49) |
         (((uint64_t)mask) << 52) | (((uint64_t)(O >> 8)) << 56);

      unsigned size = L ? 8 : 6;
      memcpy(util_dynarray_grow_bytes(emission, 1, size), &raw, size);
      break;
   }
   case AGX_OPCODE_STACK_ADJUST: {
      struct agx_opcode_info info = agx_opcodes_info[I->op];

      unsigned i0 = 0; // XXX
      unsigned i1 = 1; // XXX
      unsigned i2 = 2; // XXX
      unsigned i3 = 0; // XXX
      unsigned i4 = 0; // XXX

      uint64_t raw =
         info.encoding.exact | ((uint64_t)i0 << 8) | ((uint64_t)i1 << 26) |
         ((uint64_t)i2 << 36) | ((uint64_t)i3 << 44) | ((uint64_t)i4 << 50) |
         ((I->stack_size & 0xF) << 20) |
         ((uint64_t)((I->stack_size >> 4) & 0xF) << 32) | (1ull << 47) | // XXX
         ((uint64_t)(I->stack_size >> 8) << 56);

      memcpy(util_dynarray_grow_bytes(emission, 1, 8), &raw, 8);
      break;
   }

   default:
      agx_pack_alu(emission, I);
      return;
   }
}

/* Relative branches may be emitted before their targets, so we patch the
 * binary to fix up the branch offsets after the main emit */

static void
agx_fixup_branch(struct util_dynarray *emission, struct agx_branch_fixup fix)
{
   /* Branch offset is 2 bytes into the jump instruction */
   uint8_t *location = ((uint8_t *)emission->data) + fix.offset + 2;

   off_t target = fix.skip_to_end ? fix.block->last_offset : fix.block->offset;

   /* Offsets are relative to the jump instruction */
   int32_t patch = (int32_t)target - (int32_t)fix.offset;

   /* Patch the binary */
   memcpy(location, &patch, sizeof(patch));
}

void
agx_pack_binary(agx_context *ctx, struct util_dynarray *emission)
{
   struct util_dynarray fixups;
   util_dynarray_init(&fixups, ctx);

   agx_foreach_block(ctx, block) {
      /* Relative to the start of the binary, the block begins at the current
       * number of bytes emitted */
      block->offset = emission->size;

      agx_foreach_instr_in_block(block, ins) {
         block->last_offset = emission->size;
         agx_pack_instr(emission, &fixups, ins,
                        ctx->key->dev.needs_g13x_coherency);
      }
   }

   util_dynarray_foreach(&fixups, struct agx_branch_fixup, fixup)
      agx_fixup_branch(emission, *fixup);

   util_dynarray_fini(&fixups);

   /* Dougall calls the instruction in this footer "trap". Match the blob. */
   if (!ctx->key->no_stop || ctx->is_preamble) {
      for (unsigned i = 0; i < 8; ++i) {
         uint16_t trap = agx_opcodes_info[AGX_OPCODE_TRAP].encoding.exact;
         util_dynarray_append(emission, uint16_t, trap);
      }
   }
}
