This is the mail archive of the
cgen@sources.redhat.com
mailing list for the CGEN project.
Re: incorrect disassembly on vliw / little endian
- To: cgen at sources dot redhat dot com
- Subject: Re: incorrect disassembly on vliw / little endian
- From: Patrick Macdonald <patrickm at redhat dot com>
- Date: Tue, 30 Jan 2001 20:09:01 -0500
- Organization: Red Hat Canada Limited
- References: <3A7593D9.B41DE8A6@redhat.com> <3A772B81.69E26AC5@redhat.com>
Patrick Macdonald wrote:
>
> Hello,
>
> This is a follow up to my prior note. This patch fixes the vliw,
> little endian problem I'm seeing. I have a few concerns though:
>
> 1. Is it too restrictive?
> 2. Can we assume that most reads/writes will be multiples of 8?
Missing an "even" there. Point 2 should read:
2. Can we assume that most reads/writes will be even multiples of
8 (except for 8)? (8/16/32)
> Comments/suggestions? If not, I'll submit it.
>
> Patrick
>
> binutils ==========
>
> RCS file: /cvs/src/src/opcodes/cgen-dis.in,v
> retrieving revision 1.5
> diff -c -p -r1.5 cgen-dis.in
> *** cgen-dis.in 2001/01/09 17:00:21 1.5
> --- cgen-dis.in 2001/01/30 20:40:06
> *************** print_insn (cd, pc, info, buf, buflen)
> *** 278,283 ****
> --- 278,296 ----
> & ex_info, & full_insn_value);
> if (rc != 0)
> return rc;
> +
> + /* The re-read on a vliw, little endian will transpose the
> bytes.
> + Correct this with a hi byte(s) / lo bytes(s) flip. Note that
> the
> + content of full_insn_value is not true little endian now. */
> + if (info->endian == BFD_ENDIAN_LITTLE &&
> + (CGEN_INSN_BITSIZE (insn) / 2) == cd->base_insn_bitsize)
> + {
> + unsigned long mask = ~(0xffffffff << cd->base_insn_bitsize);
> + unsigned long hi = (full_insn_value & mask) <<
> cd->base_insn_bitsize;
> + unsigned long lo = full_insn_value >> cd->base_insn_bitsize;
> + full_insn_value = hi | lo;
> + }
> +
> length = CGEN_EXTRACT_FN (cd, insn)
> (cd, insn, &ex_info, full_insn_value, &fields, pc);
> }
>
> Patrick Macdonald wrote:
> >
> > Hi,
> >
> > I'm using cgen on a vliw set with the following characteristics:
> > 16 bit base instruction, 16/32 bit additional bits based on
> > the contents of the base instruction, little endian.
> >
> > I guess it's best to describe my problem with an example:
> >
> > Let's say I have a 16 bit instruction (0xdead) and a 16 bit
> > variable (0xbeef). The assembler writes this to disk as
> > adde efbe, which is correct.
> >
> > On disassembly in @port@-dis.c, the first 16 bits are read in to
> > determine the instruction (0xdead). It matches with a 32 bit
> > instruction and the instruction is re-read as a 32 bit, little
> > endian instruction causing the full instruction to become 0xbeefdead
> > instead of the correct 0xdeadbeef.
> >
> > Before I start mangling the code, has anyone else encountered this
> > or am I just extremely lucky these days? Thoughts/hints/directions
> > gladly accepted.
> >
> > I'm leaning towards adding a check of endianess on the re-read and
> > flipping the bits if little endian. Based on the conditions to
> > enter the re-read, this would solve the problem for this particular
> > port without crippling others.
> >
> > Patrick