movstrqi/movstrhi inconsistency analysis, with case and patch
Hans-Peter Nilsson
hans-peter.nilsson@axis.com
Mon Jan 19 02:30:00 GMT 1998
[ A slight inconsistency in the use of movstrhi/qi-patterns with large-size
blocks is present in egcs-980115 and gcc-2.8.0-971225. Analysis and patch
follows. The corresponding patch is sent to the gcc2-list. ]
The maximum size used for a move with pattern movstrhi or movstrqi is
inconsistent; in one place the threshold is with
(egcs:expr.c:emit_block_move(); c:a line 1651):
"(unsigned HOST_WIDE_INT) INTVAL (size) <= GET_MODE_MASK (mode)"
and in another (egcs:expr.c:emit_push_insn(); c:a line 2657 and on) it's with:
"(unsigned) INTVAL (size) < (1 << (GET_MODE_BITSIZE (mode) - 1))"
This means that the threshold is at 255 for the first case, and 127 for the
second, if mode == QImode. I guess it's an attempt to deal with the issue
with signedness in the size operand of the movstrM-patterns, but I would
believe that any sign-effect (the direction of the move?) should be taken care
of in the pattern. Or is this an intended "feature" of the pattern?
Anyway, it should rather be consistent.
To see this, the machine must have a movstrhi or movstrqi, and it has to be a
*real* movstr-instruction, not some expansion that "FAIL"s long before
GET_MODE_MASK (mode) bytes.
The ones I found were affected are gmicro, tahoe and vax.
The two different movstr-tests are located in a generic "block copy" function,
and an "argument-pushing" function respectively. This means the effects of
the
difference is seen in the testcase below:
struct foo
{
char array[32768];
} foobar;
void bar (struct foo *baz)
{
*baz = foobar;
}
extern struct foo eck (struct foo);
void ock (void)
{
eck (foobar);
}
which on a vax (--target=vaxv) looks like this (I just ran cc1 with
"-O2 -quiet", I did not care to install it or stuff):
.file "stdin"
gcc2_compiled.:
___gnu_compiled_c:
.text
.align 2
.globl _bar
_bar:
.word 0x0
movc3 $32768,_foobar,*4(ap)
ret
.align 2
.globl _ock
_ock:
.word 0x0
movab -32768(sp),sp
movl sp,r0
movzwl $32768,-(sp)
pushl r0
pushab _foobar
calls $3,_bcopy
calls $0,_eck
addl2 $32768,sp
ret
.comm _foobar,32768
Now, bar() seems pretty straightforward; the block-copy-instruction movc3 is
used. In ock(), suddenly bcopy() is used instead. The following patch uses
the "wider" test, so movc3 is used in argument-passing as well:
Sun Jan 18 20:30:43 1998 Hans-Peter Nilsson <hp@axis.se>
* expr.c (emit_push_insn): Use same max-move-amount for movstrhi
and movstrqi as in emit_block_move ().
*** expr.c.original Sun Jan 18 20:16:20 1998
--- expr.c Sun Jan 18 20:26:39 1998
*************** emit_push_insn (x, mode, type, size, ali
*** 2653,2660 ****
#ifdef HAVE_movstrqi
if (HAVE_movstrqi
&& GET_CODE (size) == CONST_INT
! && ((unsigned) INTVAL (size)
! < (1 << (GET_MODE_BITSIZE (QImode) - 1))))
{
rtx pat = gen_movstrqi (gen_rtx_MEM (BLKmode, temp),
xinner, size, GEN_INT (align));
--- 2653,2660 ----
#ifdef HAVE_movstrqi
if (HAVE_movstrqi
&& GET_CODE (size) == CONST_INT
! && ((unsigned HOST_WIDE_INT) INTVAL (size)
! <= GET_MODE_MASK (QImode)))
{
rtx pat = gen_movstrqi (gen_rtx_MEM (BLKmode, temp),
xinner, size, GEN_INT (align));
*************** emit_push_insn (x, mode, type, size, ali
*** 2668,2675 ****
#ifdef HAVE_movstrhi
if (HAVE_movstrhi
&& GET_CODE (size) == CONST_INT
! && ((unsigned) INTVAL (size)
! < (1 << (GET_MODE_BITSIZE (HImode) - 1))))
{
rtx pat = gen_movstrhi (gen_rtx_MEM (BLKmode, temp),
xinner, size, GEN_INT (align));
--- 2668,2675 ----
#ifdef HAVE_movstrhi
if (HAVE_movstrhi
&& GET_CODE (size) == CONST_INT
! && ((unsigned HOST_WIDE_INT) INTVAL (size)
! <= GET_MODE_MASK (HImode)))
{
rtx pat = gen_movstrhi (gen_rtx_MEM (BLKmode, temp),
xinner, size, GEN_INT (align));
Beware, FUD ahead:
I have a nagging feeling that the reason for making the threshold
twos-complement-immune anywhere is that precisely the Vax considers
the move-amount being twos-complement.
That would require other patches (hopefully contained within the Vax port).
Anybody care to comment?
Best regards,
--
Hans-Peter Nilsson, Axis Communications AB, S - 223 70 LUND, SWEDEN
Hans-Peter.Nilsson@axis.se | http://www.axis.se/ | Tel +46 46191867,191800
Fax +46 46136130 | RFC 1855 compliance implemented; report loss of brain.
More information about the Gcc
mailing list