[MLton] bug with packed representations

Matthew Fluet fluet@cs.cornell.edu
Fri, 23 Apr 2004 09:29:56 -0400 (EDT)


> Matthew, can you tell if this is a bug in the x86 codegen or in the
> Machine program being fed to the codegen?

I'm going to blame it on the Machine program.  Here is the probematic
portion of machine:

    RW8(0): [(0x0:1 + 0x1:1), 0x0:7]
     = Word8_rshift (Cast (RP(0): ([([0x2:2, (0x0:1 + 0x1:1)] + 0x1:3), 0x0:29] + pt_34),
			   [0x2:2, (0x0:1 + 0x1:1), 0x0:5]),
		     0x2)
    RW8(1): [(0x0:1 + 0x1:1), 0x0:7]
     = Word8_andb (RW8(0): [(0x0:1 + 0x1:1), 0x0:7], 0x1)
    RW8(0): [(0x0:1 + 0x1:1), 0x0:7]  = RW8(1): [(0x0:1 + 0x1:1), 0x0:7]

I can see that the goal of the first assignment is to get the low bits out
of RP(0) and then shift to get the two-valued variant (represented by one
bit) into the low order bit.

Unfortunately, projecting the low bits via a Cast doesn't mesh well with
the x86 codegen's translation of a Cast:

	  | Cast (z, _) => toX86Operand z

And I think this is the correct interpretation.  Thus far, we've only used
Cast to indicate that we were changing our interpretation of bits, but not
the actual bits themselves (or the number of bits).  So the toX86Operand
just car's down the Casts, ignoring the types, to get to a base operand
that corresponds to some actual bits (or a location of bits).

That leads to trying to move a 32bit register (RP(0) in %edi) into an 8bit
register (Cast(RP(0) : ..., ...) in $dh).

I think the Machine should be:

    RW32(0): [([0x2:2, (0x0:1 + 0x1:1)] + 0x1:3), 0x0:29]
     = Cast (RP(0): ([([0x2:2, (0x0:1 + 0x1:1)] + 0x1:3), 0x0:29] + pt_34),
	     [0x2:2, (0x0:1 + 0x1:1), 0x0:5])
    RW32(1): [([0x2:2, (0x0:1 + 0x1:1)] + 0x1:3), 0x0:5]
     = Word32_toWord8 (RW32(0))
    RW8(0): [(0x0:1 + 0x1:1), 0x0:7]
     = Word8_rshift (Cast (RW32(1): [([0x2:2, (0x0:1 + 0x1:1)] + 0x1:3), 0x0:5],
			   [0x2:2, (0x0:1 + 0x1:1), 0x0:5]),
		     0x2)
    RW8(1): [(0x0:1 + 0x1:1), 0x0:7]
     = Word8_andb (RW8(0): [(0x0:1 + 0x1:1), 0x0:7], 0x1)
    RW8(0): [(0x0:1 + 0x1:1), 0x0:7]  = RW8(1): [(0x0:1 + 0x1:1), 0x0:7]

If you want to change the number of bits in an operand, you need to do so
via some primitive that knows how to do so.

It would seem to me that we should require a Cast statement to preserve
the number of bits; if it does not, it could be ambiguous as to which bits
we want to pull out.  Presumably, you are doing the right thing elswhere,
where you pull out the high bits of a word that holds the packed
representation of a sub-component.  So, we just need to do the same thing
to pull out the low bits via a primitive, not a Cast.

>
> testing size
> 	movb %edi,%dh
> .p2align 4
> L_889:
> L_973:
> 	movb %edi,%dh
> 	shrb $0x2,%dh
> 	andb $0x1,%dh
> L_974:
> 	movl ((gcState+200)+(0*4)),%esi
> 	cmpl $0,%esi
> 	jle L_891
> L_975:
> 	decl %esi
> 	movl %esi,((gcState+200)+(0*4))
> L_976:
> 	testb %dh,%dh
> 	jnz L_890
> L_977:
> 	movl $L_978,(0+((0*1)+(0*1)))(%ebp)
> 	movl $13,(0+((44*1)+(0*1)))(%ebp)
> 	movl $0,(0+((48*1)+(0*1)))(%ebp)
> 	movl $1,(0+((52*1)+(0*1)))(%ebp)
> 	movl (0+((12*1)+(0*1)))(%ebp),%esi
> 	movl %esi,(0+((56*1)+(0*1)))(%ebp)
> 	addl $44,%ebp
> 	movl $L_979,(0+(-1*4))(%ebp)
> 	jmp x_5
> x86Validate.validate::validate: MOV, srcsize
> /tmp/cckAaGJO.s: Assembler messages:
> /tmp/cckAaGJO.s:2847: Error: suffix or operands invalid for `mov'
> call to system failed with exit status 1:
> gcc -c -o /tmp/fileXFQNfc.o /tmp/fileW2a98p.0.S
> compilation of size failed with -warn-match false -debug false -gc-check limit -representation packed -native true -type-check true
>
> _______________________________________________
> MLton mailing list
> MLton@mlton.org
> http://www.mlton.org/mailman/listinfo/mlton
>