This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Trying to work around a 16-bit x86 weirdness


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Mon, Oct 20, 2003 at 05:50:37PM -0700, Richard Henderson wrote:
> On Mon, Oct 20, 2003 at 10:44:55AM +0200, Bernd Jendrissek wrote:
> > (insn 23 8 24 0 (set (reg:HI bx [25])
> >         (const_int 42000 [0xa410])) -1 (nil)
> 
> This is not a valid HImode constant.  Integer constants are
> sign extended to HOST_WIDE_INT, regardless of the signedness
> of the target type.

Thanks - just enough info to give me the right direction, and little
enough to keep in interesting.

Okay, so I think I have it all (well not quite) figured out.  I've been
predicating my patterns on general_operand, which seems reasonable for
movhi.  But when I look inside, I see this:

int
general_operand (rtx op, enum machine_mode mode)
{
  enum rtx_code code = GET_CODE (op);

  if (mode == VOIDmode)
    mode = GET_MODE (op);

  /* Don't accept CONST_INT or anything similar
     if the caller wants something floating.  */
  if (GET_MODE (op) == VOIDmode && mode != VOIDmode
      && GET_MODE_CLASS (mode) != MODE_INT
      && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
    return 0;

  if (GET_CODE (op) == CONST_INT
      && mode != VOIDmode
      && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
    return 0;

trunc_int_for_mode (42000, HImode) = -23536, which definately does not
equal 42000!

Now considering that I hardly worked on this port since last week, it
seems something in GCC has changed that it now wants to tell me the
meaning of life 1000 times.  Is there any way I can teach it to use
- -23536 instead, if 0xa410 is really what it wants?

Should I add a pattern for
(set (match_operand:HI 0) (match_operand:DI 1)) just so I can catch
these large CONST_INT's?

TIA

P.S. Here's my test program and the resulting assembly, if I predicate
my movhi pattern on nothing:

(Obviously, movhi not caring about its operands is not good either.)

C:

> int x;
> 
> int f(int x, int y)
> {
> 	int retval;
> 
> 	*(int *) 0 = x;
> 
> 	retval = x + y + 2;
> 
> 	return retval;
> }
> 
> void g(void)
> {
> 	f(42, 17);
> }
> 
> int neg(int x)
> {
> 	int foo;
> 
> 	foo = -x;
> 
> 	return foo;
> }
> 
> int s(void)
> {
> 	int fi __attribute__((mode(__word__)));
> 
> 	x = sizeof (fi);
> 
> 	return 0;
> }

assembly:

> 	.code16
> 	.text
> 	.p2align 1
> 	.globl	f
> f:
> 	pushw	%bp
> 	movw	%sp,%bp
> 	movw	4(%bp),%dx
> 	movw	6(%bp),%ax
> 	movw	%dx,0
> 	movw	Don't know how to print
> (plus:HI (plus:HI (reg:HI dx [30])
>               (reg:HI ax [31]))
>           (const_int 2 [0x2]))
> ,%ax
> 	pop	%bp
> 	ret
> 	.p2align 1
> 	.globl	g
> g:
> 	pushw	%bp
> 	movw	%sp,%bp
> 	movw	Don't know how to print
> (plus:HI (reg/f:HI bp)
>           (const_int 42000 [0xa410]))
> ,%bx

Dunno *why* GCC likes 42000 so much...

> 	movw	$42,(%bx)
> 	movw	$17,2(%bx)
> 	movw	Don't know how to print
> (call (mem:QI (symbol_ref:HI ("f") [flags 0x3] <function_decl 0x401f33cc f>) [0 S1 A8])
>           (const_int 4 [0x4]))
> ,%ax
> 	pop	%bp
> 	ret
> 	.p2align 1
> 	.globl	neg
> neg:
> 	pushw	%bp
> 	movw	%sp,%bp
> 	movw	Don't know how to print
> (not:HI (mem/f:HI (plus:HI (reg/f:HI bp)
>                   (const_int 4 [0x4])) [2 x+0 S2 A16]))
> ,%ax
> 	pop	%bp
> 	ret
> 	.p2align 1
> 	.globl	s
> s:
> 	pushw	%bp
> 	movw	%sp,%bp
> 	movw	$2,x
> 	movw	$0,%ax
> 	pop	%bp
> 	ret
> 	.lcomm	x, 2
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE/lU+O/FmLrNfLpjMRAn23AJwNk8bFUxjSPyrcQUOGU73ec74XkwCdHFrW
fO1ge+n+k9HFUDsigWG53Rw=
=SIuj
-----END PGP SIGNATURE-----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]