+static void
+xtensa_coalesce_insn_tables (struct dis_private *priv)
+{
+ const int mask = ~(XTENSA_PROP_DATA | XTENSA_PROP_NO_TRANSFORM);
+ int count = priv->insn_table_entry_count;
+ int i, j;
+
+ /* Loop over all entries, combining adjacent ones that differ only in
+ the flag bits XTENSA_PROP_DATA and XTENSA_PROP_NO_TRANSFORM. */
+
+ for (i = j = 0; j < count; ++i)
+ {
+ property_table_entry *entry = priv->insn_table_entries + i;
+
+ *entry = priv->insn_table_entries[j];
+
+ for (++j; j < count; ++j)
+ {
+ property_table_entry *next = priv->insn_table_entries + j;
+ int fill = xtensa_compute_fill_extra_space (entry);
+ int size = entry->size + fill;
+
+ if (entry->address + size == next->address)
+ {
+ int entry_flags = entry->flags & mask;
+ int next_flags = next->flags & mask;
+
+ if (next_flags == entry_flags)
+ entry->size = next->address - entry->address + next->size;
+ else
+ break;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ priv->insn_table_entry_count = i;
+}
+
+static property_table_entry *
+xtensa_find_table_entry (bfd_vma memaddr, struct disassemble_info *info)
+{
+ struct dis_private *priv = (struct dis_private *) info->private_data;
+ int i;
+
+ if (priv->insn_table_entries == NULL
+ || priv->insn_table_entry_count < 0)
+ return NULL;
+
+ if (memaddr < priv->insn_table_cur_addr)
+ priv->insn_table_cur_idx = 0;
+
+ for (i = priv->insn_table_cur_idx; i < priv->insn_table_entry_count; ++i)
+ {
+ property_table_entry *block = priv->insn_table_entries + i;
+
+ if (block->size != 0)
+ {
+ if ((memaddr >= block->address
+ && memaddr < block->address + block->size)
+ || memaddr < block->address)
+ {
+ priv->insn_table_cur_addr = memaddr;
+ priv->insn_table_cur_idx = i;
+ return block;
+ }
+ }
+ }
+ return NULL;
+}
+
+/* Check whether an instruction crosses an instruction block boundary
+ (according to property tables).
+ If it does, return 0 (doesn't fit), else return 1. */
+
+static int
+xtensa_instruction_fits (bfd_vma memaddr, int size,
+ property_table_entry *insn_block)
+{
+ unsigned max_size;
+
+ /* If no property table info, assume it fits. */
+ if (insn_block == NULL || size <= 0)
+ return 1;
+
+ /* If too high, limit nextstop by the next insn address. */
+ if (insn_block->address > memaddr)
+ {
+ /* memaddr is not in an instruction block, but is followed by one. */
+ max_size = insn_block->address - memaddr;
+ }
+ else
+ {
+ /* memaddr is in an instruction block, go no further than the end. */
+ max_size = insn_block->address + insn_block->size - memaddr;
+ }
+
+ /* Crossing a boundary, doesn't "fit". */
+ if ((unsigned)size > max_size)
+ return 0;
+ return 1;
+}