Well done! That generated sensible code:
L 15,=V(PRINTF)
BALR 14,15
L 3,=F'32880'
AR 3,13
MVC 0(10,3),0(2)
I still have the other knock-on effects from when I did this though:
C:\devel\gcc\gcc\config\i370>cvs diff i370.h
Index: i370.h
===================================================================
RCS file: c:\cvsroot/gcc/gcc/config/i370/i370.h,v
retrieving revision 1.17
diff -r1.17 i370.h
599a600,602
#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
((C) == 'S')
(like the 8 byte move from F'0'). I'll do my own investigation
of that and report that later.
BFN. Paul.
-----Original Message-----
From: Ulrich Weigand
Sent: Thursday, August 18, 2011 11:14 PM
To: Paul Edwards
Cc: gcc@gcc.gnu.org
Subject: Re: i370 port
Paul Edwards wrote:
Hi Ulrich. I put in the following debug:
op0 = find_replacement (&XEXP (in, 0));
op1 = find_replacement (&XEXP (in, 1));
/* Since constraint checking is strict, commutativity won't be
checked, so we need to do that here to avoid spurious failure
if the add instruction is two-address and the second operand
of the add is the same as the reload reg, which is frequently
the case. If the insn would be A = B + A, rearrange it so
it will be A = A + B as constrain_operands expects. */
fprintf(stderr, "REGNO(out) is %d\n", REGNO(out));
fprintf(stderr, " REG in 1 is %d\n", REGNO(XEXP(in,1)));
if (GET_CODE (XEXP (in, 1)) == REG
&& REGNO (out) == REGNO (XEXP (in, 1)))
tem = op0, op0 = op1, op1 = tem;
And it produced this output (for exactly the same code I showed
you previously):
C:\devel\pdos\s370>\devel\gcc\gcc\gccmvs -da -DUSE_MEMMGR -Os -DS390 -S -I
. -I ../pdpclib pdos.c
REGNO(out) is 3
REG in 1 is 32880
REGNO(out) is 2
REG in 1 is 32880
REGNO(out) is 2
REG in 1 is 32880
REGNO(out) is 2
REG in 1 is 112
REGNO(out) is 3
REG in 1 is 32880
REGNO(out) is 4
REG in 1 is 112
REGNO(out) is 2
REG in 1 is 112
which looks to me like it is not seeing a register, only a constant,
so cannot perform a swap.
Oops, there's clearly a bug here. "in" at this point is the original
expression that has not yet been reloaded, so its second operand will
indeed be a constant, not a register. However, reload has already
decided that this constant will end up being replaced by a register,
and that is what the "find_replacement" call is checking.
So at this point in the program, XEXP (in, 1) will be the constant,
but op1 will be the register it is going to be replaced with.
Unfortunately the test whether to swap looks at XEXP (in, 1) -- it
really needs to look at op1 instead.
Can you try changing the lines
if (GET_CODE (XEXP (in, 1)) == REG
&& REGNO (out) == REGNO (XEXP (in, 1)))
to
if (GET_CODE (op1) == REG
&& REGNO (out) == REGNO (op1))
instead?
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
ulrich.weig...@de.ibm.com