Basically the rule (which can be configurable if
different machines behave differently) should be
(for pure 32-bit code generation):
1. If your machine treats indexes as signed values:
a) If the requested index is between -2 GiB and
+ 2 GiB, fine, do it.
b) If the requested index is greater than 2 GiB,
you will need to do an addition instead.
2. If your machine treats indexes as as unsigned values:
a) If the requested index is less than 0, do a subtraction
instead.
b) Any non-negative value can be used as an index.
Although that logic should only be applied if you have
an environment where you don't get saved by address
wraparound. If you have a machine that for any reason
enforces an attempt to index beyond 4 GiB, or below
0 (instead of just letting the address wrap), then the
compiler needs to respect that.
This applies to all environments, not just i370.
BFN. Paul.
-----Original Message-----
From: Paul Edwards
Sent: Sunday, March 14, 2021 7:12 PM
To: gcc@gcc.gnu.org ; Richard Biener
Subject: Re: negative indexes
Hi Richard. Thanks for your reply, but if I understand
you correctly, you are saying this fix is for situations
where the size of an integer is different from the size
of a pointer?
That is not my issue. The size is the same. Absolutely
everything is 32-bits in the program (long, int, char *,
void *, code addresses).
However, since I am running as AMODE 64, if someone
attempts to do an index by adding two 32-bit registers
together in a single instruction, that reference will
actually take effect, and go up into the 4 GiB to 8 GiB
region.
Is your answer still applicable (I don't really understand
your answer. :-) ).
Thanks. Paul.
-----Original Message-----
From: Richard Biener
Sent: Sunday, March 14, 2021 7:05 PM
To: Paul Edwards ; Paul Edwards via Gcc ; gcc@gcc.gnu.org
Subject: Re: negative indexes
On March 14, 2021 6:55:32 AM GMT+01:00, Paul Edwards via Gcc
<gcc@gcc.gnu.org> wrote:
If I have code like this:
char foo(char *p)
{
return (p[-1]);
}
It generates a negative index, like this:
* Function foo code
L 2,=F'-1'
L 3,0(11)
SLR 15,15
IC 15,0(2,3)
* Function foo epilogue
See that (2,3) - that is adding both R2 + R3.
R3 is a pointer to a location in 4 GiB space.
R2 is now 0xFFFFFFFF
In 64-bit mode, both of those values are added
together and there is no address wrap, so it
accesses memory above the 4 GiB boundary
(between 4 GiB and 8 GiB to be precise)
which I don't have access to.
Is there a way of constraining index registers to positive
values?
I want it to instead generate
ALR 3,2
to add these two values together using 32-bit arithmetic,
causing truncation at 32 bits, then it can do
IC 15,0(3)
(ie no index)
I'm using GCC 3.2.3 using the i370 target if it makes a difference.
You are likely missing a fix that sign extends offsets on Pmode!=ptr_mode
targets. 3.2.3 is really old now ;)
Richard.
Thanks. Paul.