From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Frank Ch. Eigler" To: cgen@sources.redhat.com, binutils@sources.redhat.com Subject: more cgen disassembly fixes Date: Mon, 07 May 2001 10:55:00 -0000 Message-id: <20010507135435.A30817@redhat.com> X-SW-Source: 2001-q2/msg00037.html Hi - I'm about to commit the following patch, which goes a little further in providing disassembly/assembly support to variable/funny length instruction sets. Again, no instant opcodes regeneration of working existing targets is necessary. 2001-05-07 Frank Ch. Eigler * iformat.scm (compute-insn-base-mask-length): Rewrite to tolerate various-base-length instruction sets. Index: cgen/iformat.scm =================================================================== RCS file: /cvs/src/src/cgen/iformat.scm,v retrieving revision 1.2 diff -u -r1.2 iformat.scm --- iformat.scm 2000/08/22 19:14:30 1.2 +++ iformat.scm 2001/05/07 17:52:32 @@ -90,11 +90,23 @@ ) ; Given FLD-LIST, compute the base length in bits. -; Computing the min of state-base-insn-bitsize and the total-length -; is for [V]LIW instruction sets. +; +; For variable length instruction sets, or with cpus with multiple +; instruction sets, compute the base appropriate for this set of +; ifields. Check that ifields are not shared among isas with +; inconsistent base insn lengths. (define (compute-insn-base-mask-length fld-list) - (min (state-base-insn-bitsize) (compute-insn-length fld-list)) + (let* ((isa-base-bitsizes + (remove-duplicates + (map isa-base-insn-bitsize + (map current-isa-lookup + (collect (lambda (ifld) + (bitset-attr->list (atlist-attr-value (obj-atlist ifld) 'ISA #f))) + fld-list)))))) + (if (= 1 (length isa-base-bitsizes)) + (min (car isa-base-bitsizes) (compute-insn-length fld-list)) + (error "ifields have inconsistent isa/base-insn-size values:" isa-base-bitsizes))) ) ; Given FLD-LIST, compute the bitmask of constant values in the base part 2001-05-07 Frank Ch. Eigler * cgen-dis.in (default_print_insn): Tolerate minbase_insn_bitsize / 8; + status = (*info->read_memory_func) (pc, buf, buflen, info); - status = (*info->read_memory_func) (pc, buf, cd->base_insn_bitsize / 8, info); + /* Try again with the minimum part, if min < base. */ + if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize)) + { + buflen = cd->min_insn_bitsize / 8; + status = (*info->read_memory_func) (pc, buf, buflen, info); + } + if (status != 0) { (*info->memory_error_func) (status, pc, info); return -1; } - return print_insn (cd, pc, info, buf, cd->base_insn_bitsize / 8); + return print_insn (cd, pc, info, buf, buflen); } /* Main entry point. Index: opcodes/cgen-ibld.in =================================================================== RCS file: /cvs/src/src/opcodes/cgen-ibld.in,v retrieving revision 1.7 diff -u -r1.7 cgen-ibld.in --- cgen-ibld.in 2001/03/27 21:37:47 1.7 +++ cgen-ibld.in 2001/05/07 17:52:32 @@ -428,9 +428,9 @@ word_length = total_length; } - /* Does the value reside in INSN_VALUE? */ + /* Does the value reside in INSN_VALUE, and at the right alignment? */ - if (CGEN_INT_INSN_P || word_offset == 0) + if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length)) { if (CGEN_INSN_LSB0_P) value = insn_value >> ((word_offset + start + 1) - length);