static CGEN_INSN_LIST * hash_insn_array (CGEN_CPU_DESC cd, const CGEN_INSN * insns, int count, int entsize ATTRIBUTE_UNUSED, CGEN_INSN_LIST ** htable, CGEN_INSN_LIST * hentbuf) { int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG; int i; for (i = count - 1; i >= 0; --i, ++hentbuf) { unsigned int hash; char buf [4]; unsigned long value; const CGEN_INSN *insn = &insns[i]; if (! (* cd->dis_hash_p) (insn)) continue; /* We don't know whether the target uses the buffer or the base insn to hash on, so set both up. */ value = CGEN_INSN_BASE_VALUE (insn); bfd_put_bits ((bfd_vma) value, buf, CGEN_INSN_MASK_BITSIZE (insn), big_p); hash = (* cd->dis_hash) (buf, value); add_insn_to_hash_chain (hentbuf, insn, htable, hash); } return hentbuf; }
static CGEN_INSN_LIST * hash_insn_list (CGEN_CPU_DESC cd, const CGEN_INSN_LIST *insns, CGEN_INSN_LIST **htable, CGEN_INSN_LIST *hentbuf) { int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG; const CGEN_INSN_LIST *ilist; for (ilist = insns; ilist != NULL; ilist = ilist->next, ++ hentbuf) { unsigned int hash; char buf[4]; unsigned long value; if (! (* cd->dis_hash_p) (ilist->insn)) continue; /* We don't know whether the target uses the buffer or the base insn to hash on, so set both up. */ value = CGEN_INSN_BASE_VALUE (ilist->insn); bfd_put_bits((bfd_vma) value, buf, CGEN_INSN_MASK_BITSIZE (ilist->insn), big_p); hash = (* cd->dis_hash) (buf, value); add_insn_to_hash_chain (hentbuf, ilist->insn, htable, hash); } return hentbuf; }
static int my_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info) { bfd_byte buffer[CGEN_MAX_INSN_SIZE]; bfd_byte *buf = buffer; int status; int buflen = (pc & 3) == 0 ? 4 : 2; int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG; bfd_byte *x; /* Read the base part of the insn. */ status = (*info->read_memory_func) (pc - ((!big_p && (pc & 3) != 0) ? 2 : 0), buf, buflen, info); if (status != 0) { (*info->memory_error_func) (status, pc, info); return -1; } /* 32 bit insn? */ x = (big_p ? &buf[0] : &buf[3]); if ((pc & 3) == 0 && (*x & 0x80) != 0) return print_insn (cd, pc, info, buf, buflen); /* Print the first insn. */ if ((pc & 3) == 0) { buf += (big_p ? 0 : 2); if (print_insn (cd, pc, info, buf, 2) == 0) (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); buf += (big_p ? 2 : -2); } x = (big_p ? &buf[0] : &buf[1]); if (*x & 0x80) { /* Parallel. */ (*info->fprintf_func) (info->stream, " || "); *x &= 0x7f; } else (*info->fprintf_func) (info->stream, " -> "); /* The "& 3" is to pass a consistent address. Parallel insns arguably both begin on the word boundary. Also, branch insns are calculated relative to the word boundary. */ if (print_insn (cd, pc & ~ (bfd_vma) 3, info, buf, 2) == 0) (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); return (pc & 3) ? 2 : 4; }