This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Trying to work around a 16-bit x86 weirdness
- From: Bernd Jendrissek <berndfoobar at users dot sourceforge dot net>
- To: Richard Henderson <rth at redhat dot com>, gcc at gcc dot gnu dot org
- Cc: dj at redhat dot com
- Date: Tue, 21 Oct 2003 17:24:08 +0200
- Subject: Re: Trying to work around a 16-bit x86 weirdness
- References: <20031020084455.GA19425@prism.co.za> <20031021005037.GE1969@redhat.com>
-----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-----