* Re: negative indexes
@ 2021-03-14 11:48 Paul Edwards
0 siblings, 0 replies; 6+ messages in thread
From: Paul Edwards @ 2021-03-14 11:48 UTC (permalink / raw)
To: gcc, Richard Biener
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.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: i370 port - 3.4.6 to 4.4 upgrade attempt
@ 2009-11-24 14:05 Ulrich Weigand
2009-11-28 15:14 ` i370 port - music/sp - possible generic gcc problem Paul Edwards
0 siblings, 1 reply; 6+ messages in thread
From: Ulrich Weigand @ 2009-11-24 14:05 UTC (permalink / raw)
To: Paul Edwards; +Cc: Ralf Wildenhues, Ian Lance Taylor, gcc
Paul Edwards wrote:
> So, given the scope below, can someone please explain what
> 4.4 changes are affecting me and what I need to do to overcome
> them? Note that I have never had to do the machine changes
> myself - in the past I simply waiting for Dave Pitts to do the
> upgrade to the new version, and then with a working 370 code
> generator I would make all the changes necessary for MVS.
Most of the things seem just minor changes, e.g. "warning" got
another argument, or target macros were replaced by targetm
callbacks.
I can see one significant change: the GCC middle-end now no
longer supports base-16 floating point at all. The old i370
port was the only user of this feature, and some time after
the port was removed, the middle-end support was removed as
well in order to simplify floating-point handling code.
The s390 port uses IEEE float instead of hex float throughout,
so it is not affected by this change.
> + i370-*-mvspdp)
> + xm_defines='POSIX' # 'FATAL_EXIT_CODE=12'
> + xm_file="i370/xm-mvs.h"
> + tm_file="i370/mvspdp.h i370/i370.h"
> + tmake_file="i370/t-mvs i370/t-i370"
> + c_target_objs="i370-c.o"
> + cxx_target_objs="i370-c.o"
> + ;;
> + s390-*-linux*)
> + tm_file="s390/s390.h dbxelf.h elfos.h svr4.h linux.h s390/linux.h"
> + tmake_file="${tmake_file} t-dfprules s390/t-crtstuff s390/t-linux"
> + ;;
The s390 lines should not be added here.
> ! /* +++ c_lex has gone. however, we don't use it for anything important
> anyway */
> ! #define c_lex(a)
Pragma handlers are now apparently supposed to use "pragma_lex" instead,
which is declared in the c-pragma.h header. See e.g. config/sol2-c.c
for examples of pragma handlers.
> /* We're 370 floating point, not IEEE floating point. */
> memset (real_format_for_mode, 0, sizeof real_format_for_mode);
> ! REAL_MODE_FORMAT (SFmode) = &i370_single_format;
> ! REAL_MODE_FORMAT (DFmode) = &i370_double_format;
This is a problem, see above.
> /* We're 370 floating point, not IEEE floating point. */
> memset (real_format_for_mode, 0, sizeof real_format_for_mode);
> ! /*REAL_MODE_FORMAT (SFmode) = &i370_single_format;
> ! REAL_MODE_FORMAT (DFmode) = &i370_double_format;*/
> ! /* +++ this is wrong */
> ! REAL_MODE_FORMAT (SFmode) = &ibm_extended_format;
> ! REAL_MODE_FORMAT (DFmode) = &ibm_extended_format;
ibm_extended_format is certainly wrong here; that's the
64 + 64 "long double" format used on PowerPC.
> for (note = REG_NOTES (insn); note; note = XEXP(note,1))
> {
> + /* +++ what is reg_label? */
> + /*
> if (REG_LABEL == REG_NOTE_KIND(note))
> {
Instead of REG_LABEL notes, the middle-end now generates two different
kinds of notes, REG_LABEL_TARGET and REG_LABEL_OPERAND.
REG_LABEL_TARGET is used in JUMP_INSNs to refer to a potential target
of this jump. REG_LABEL_OPERAND is used in other insns to denote labels
that are used otherwise, e.g. to load the address into a register.
In the context of this code in i370.c, it would appear you're concerned
about the second type of usage here. This means the REG_LABEL should
probably simply be replaced by REG_LABEL_OPERAND.
> ***************
> *** 1568,1574 ****
> fprintf (f, "* Function %.*s prologue: stack = %ld, args = %d\n",
> nlen, mvs_function_name,
> l,
> ! current_function_outgoing_args_size);
> #endif
current_function_outgoing_args_size must be replaced by crtl->outgoing_args_size
throughout. There was no change in semantics, just where the value is stored.
> fprintf (f, "* Function %.*s prologue: stack = %ld, args = %d\n",
> nlen, mvs_function_name,
> l,
> ! 0 /*cfun->machine->frame_size*/);
> #endif
The cfun->machine->frame_size stuff does not seem correct here; use
crtl->outgoing_args_size.
> + #if 0
> + This unused (in mvspdp) stuff is now poisoned
> /* Macro to define tables used to set the flags. This is a list in braces
> of pairs in braces, each pair being { "NAME", VALUE }
> where VALUE is the bits to set or minus the bits to clear.
> ***************
> *** 99,104 ****
> --- 101,107 ----
> { "pickax", 2, "Experimental i370 PIC"}, \
> { "no-pickax", -2, "Disable experimental i370 PIC"}, \
> { "", TARGET_DEFAULT, 0} }
> + #endif
Command line options are now defined in a .opt file. If you want to
keep those extra options, you should provide a config/i370/i370.opt
file. See any of the other targets for examples.
> + #if 0 /* +++ now poisoned */
> #define PREDICATE_CODES \
> {"r_or_s_operand", { REG, SUBREG, MEM }}, \
> {"s_operand", { MEM }},
> + #endif
Predicates must now be defined in a predicates.md file. Again, see
other targets for examples.
> ! #if 0 /*def TARGET_PDPMAC*/
> ! +++ this variable is now poisoned - check structs still get returned
> ! properly
> #define STRUCT_VALUE_REGNUM 0
> ! #elif 0 /*used to be else*/
> #define STRUCT_VALUE_REGNUM 1
> #endif
If something except the default is needed here, you now have to use the
TARGET_STRUCT_VALUE_RTX targetm callback.
> /* For an arg passed partly in registers and partly in memory, this is the
> number of registers used. For args passed entirely in registers or
> entirely in memory, zero. */
> ! /* +++ now poisoned */
> ! #if 0
> #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
> + #endif
If something except the default is needed here, you now have to use the
TARGET_ARG_PARTIAL_BYTES targetm callback.
> /* This macro definition sets up a default value for `main' to return. */
> ! /* +++ now poisoned */
> ! #if 0
> #define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node)
> ! #endif
This is no longer supported. C99 allows omitting the main return value
by default; in C89 this is not possible any longer.
> /* When a prototype says `char' or `short', really pass an `int'. */
> ! /* +++ now poisoned */
> ! #if 0
> #define PROMOTE_PROTOTYPES 1
> + #endif
If something except the default is needed here, you now have to use the
TARGET_PROMOTE_PROTOTYPES targetm callback.
> - #ifdef TARGET_EBCDIC
> - #define TARGET_ESC 39
> - #define TARGET_BELL 47
> - #define TARGET_BS 22
> - #define TARGET_TAB 5
> - #define TARGET_NEWLINE 21
> - #define TARGET_VT 11
> - #define TARGET_FF 12
> - #define TARGET_CR 13
> - #endif
These are no longer needed now that the parser is charset-aware.
> #define TEXT_SECTION_ASM_OP "* Program text area"
> #define DATA_SECTION_ASM_OP "* Program data area"
> #define INIT_SECTION_ASM_OP "* Program initialization area"
> + /* +++ now poisoned */
> + #if 0
> #define SHARED_SECTION_ASM_OP "* Program shared data"
> + #endif
This is no longer needed; it was used to support -fshared-data
which is no longer present.
Note that I'd expect that with the above obvious issues fixed,
you may well run into additional problems in moving the port
forward ... At some point, it will be necessary to be able
to debug the back-end and resolve problems.
Overall, I still think that adding HLASM support to the s390
back-end would probably be a simpler task ...
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 6+ messages in thread
* i370 port - music/sp - possible generic gcc problem
2009-11-24 14:05 i370 port - 3.4.6 to 4.4 upgrade attempt Ulrich Weigand
@ 2009-11-28 15:14 ` Paul Edwards
2009-11-28 16:03 ` Richard Guenther
0 siblings, 1 reply; 6+ messages in thread
From: Paul Edwards @ 2009-11-28 15:14 UTC (permalink / raw)
To: gcc
I think I have found a bug in gcc, that still exists in gcc 4.4
I found the problem on 3.2.3 though.
While MVS and VM have basically been working fine, when I did
the port to MUSIC/SP I started getting strange compilation failures.
Initializing the stack to NULs made the problem go away, but I
persisted, and instead initialized the stack to x'01' to try to get
consistent failures.
Even with that, and the malloced memory initialized to consistent
garbage, I still didn't get the desired consistency in failures.
But it was consistent enough that I could just run it 6 times and
see if there were any failures.
Anyway, I tracked down the particular malloc() which gave changed
behaviour depending on whether the malloc() did a memory initialization
to NULs or not.
It's this one (showing 3.2.3):
C:\devel\gcc\gcc>cvs diff -l -c15
cvs diff: Diffing .
Index: ggc-page.c
===================================================================
RCS file: c:\cvsroot/gcc/gcc/ggc-page.c,v
retrieving revision 1.1.1.1
diff -c -1 -5 -r1.1.1.1 ggc-page.c
*** ggc-page.c 15 Feb 2006 10:22:25 -0000 1.1.1.1
--- ggc-page.c 28 Nov 2009 14:13:41 -0000
***************
*** 640,670 ****
#ifdef USING_MALLOC_PAGE_GROUPS
else
{
/* Allocate a large block of memory and serve out the aligned
pages therein. This results in much less memory wastage
than the traditional implementation of valloc. */
char *allocation, *a, *enda;
size_t alloc_size, head_slop, tail_slop;
int multiple_pages = (entry_size == G.pagesize);
if (multiple_pages)
alloc_size = GGC_QUIRE_SIZE * G.pagesize;
else
alloc_size = entry_size + G.pagesize - 1;
! allocation = xmalloc (alloc_size);
page = (char *) (((size_t) allocation + G.pagesize - 1)
& -G.pagesize);
head_slop = page - allocation;
if (multiple_pages)
tail_slop = ((size_t) allocation + alloc_size) & (G.pagesize - 1);
else
tail_slop = alloc_size - entry_size - head_slop;
enda = allocation + alloc_size - tail_slop;
/* We allocated N pages, which are likely not aligned, leaving
us with N-1 usable pages. We plan to place the page_group
structure somewhere in the slop. */
if (head_slop >= sizeof (page_group))
group = (page_group *)page - 1;
else
--- 640,670 ----
#ifdef USING_MALLOC_PAGE_GROUPS
else
{
/* Allocate a large block of memory and serve out the aligned
pages therein. This results in much less memory wastage
than the traditional implementation of valloc. */
char *allocation, *a, *enda;
size_t alloc_size, head_slop, tail_slop;
int multiple_pages = (entry_size == G.pagesize);
if (multiple_pages)
alloc_size = GGC_QUIRE_SIZE * G.pagesize;
else
alloc_size = entry_size + G.pagesize - 1;
! allocation = xcalloc (1, alloc_size);
page = (char *) (((size_t) allocation + G.pagesize - 1)
& -G.pagesize);
head_slop = page - allocation;
if (multiple_pages)
tail_slop = ((size_t) allocation + alloc_size) & (G.pagesize - 1);
else
tail_slop = alloc_size - entry_size - head_slop;
enda = allocation + alloc_size - tail_slop;
/* We allocated N pages, which are likely not aligned, leaving
us with N-1 usable pages. We plan to place the page_group
structure somewhere in the slop. */
if (head_slop >= sizeof (page_group))
group = (page_group *)page - 1;
else
I suspect that it has stayed hidden for so long because most people
probably have this mmap_anon:
/* Define if mmap can get us zeroed pages using MAP_ANON(YMOUS). */
#undef HAVE_MMAP_ANON
#ifdef HAVE_MMAP_ANON
# undef HAVE_MMAP_DEV_ZERO
# include <sys/mman.h>
# ifndef MAP_FAILED
# define MAP_FAILED -1
# endif
# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
# define MAP_ANONYMOUS MAP_ANON
# endif
# define USING_MMAP
#endif
#ifndef USING_MMAP
#define USING_MALLOC_PAGE_GROUPS
#endif
Seems pretty clear that zeroed pages are required.
Looking at the code above and below this block, it uses xcalloc
instead.
It will take a couple of days to confirm that this is the last
presumed bug affecting the MUSIC/SP port.
In the meantime, can someone confirm that this code is wrong,
and that xcalloc is definitely required?
I had a look at the gcc4 code, and it is calling XNEWVEC which
is also using xmalloc instead of xcalloc, so I presume it is still
a problem today, under the right circumstances.
It took about a week to track this one down. :-)
One problem I have had for years, even on the MVS port, is that
I need to use -Os to get the exact same register selection on the
PC as the mainframe. -O0 and -O2 get slightly different register
allocations, although all versions of the code are correct. If I'm
lucky, this fix may make that problem go away, but as I said,
it'll take a couple of days before the results are in, as each build
takes about 2 hours (partly because i need to use -Os for
consistency).
Thanks. Paul.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: i370 port - music/sp - possible generic gcc problem
2009-11-28 15:14 ` i370 port - music/sp - possible generic gcc problem Paul Edwards
@ 2009-11-28 16:03 ` Richard Guenther
2021-03-14 5:55 ` negative indexes Paul Edwards
0 siblings, 1 reply; 6+ messages in thread
From: Richard Guenther @ 2009-11-28 16:03 UTC (permalink / raw)
To: Paul Edwards; +Cc: gcc
On Sat, Nov 28, 2009 at 4:13 PM, Paul Edwards <mutazilah@gmail.com> wrote:
> I think I have found a bug in gcc, that still exists in gcc 4.4
>
> I found the problem on 3.2.3 though.
>
> While MVS and VM have basically been working fine, when I did
> the port to MUSIC/SP I started getting strange compilation failures.
>
> Initializing the stack to NULs made the problem go away, but I
> persisted, and instead initialized the stack to x'01' to try to get
> consistent failures.
>
> Even with that, and the malloced memory initialized to consistent
> garbage, I still didn't get the desired consistency in failures.
> But it was consistent enough that I could just run it 6 times and
> see if there were any failures.
>
>
> Anyway, I tracked down the particular malloc() which gave changed
> behaviour depending on whether the malloc() did a memory initialization
> to NULs or not.
Well, GC hands out non-zeroed memory - the callers are responsible
for initializing it. So the fix below is not a fix but papering over an
issue elswhere.
Richard.
> It's this one (showing 3.2.3):
>
> C:\devel\gcc\gcc>cvs diff -l -c15
> cvs diff: Diffing .
> Index: ggc-page.c
> ===================================================================
> RCS file: c:\cvsroot/gcc/gcc/ggc-page.c,v
> retrieving revision 1.1.1.1
> diff -c -1 -5 -r1.1.1.1 ggc-page.c
> *** ggc-page.c 15 Feb 2006 10:22:25 -0000 1.1.1.1
> --- ggc-page.c 28 Nov 2009 14:13:41 -0000
> ***************
> *** 640,670 ****
> #ifdef USING_MALLOC_PAGE_GROUPS
> else
> {
> /* Allocate a large block of memory and serve out the aligned
> pages therein. This results in much less memory wastage
> than the traditional implementation of valloc. */
>
> char *allocation, *a, *enda;
> size_t alloc_size, head_slop, tail_slop;
> int multiple_pages = (entry_size == G.pagesize);
>
> if (multiple_pages)
> alloc_size = GGC_QUIRE_SIZE * G.pagesize;
> else
> alloc_size = entry_size + G.pagesize - 1;
> ! allocation = xmalloc (alloc_size);
>
> page = (char *) (((size_t) allocation + G.pagesize - 1) &
> -G.pagesize);
> head_slop = page - allocation;
> if (multiple_pages)
> tail_slop = ((size_t) allocation + alloc_size) & (G.pagesize - 1);
> else
> tail_slop = alloc_size - entry_size - head_slop;
> enda = allocation + alloc_size - tail_slop;
>
> /* We allocated N pages, which are likely not aligned, leaving
> us with N-1 usable pages. We plan to place the page_group
> structure somewhere in the slop. */
> if (head_slop >= sizeof (page_group))
> group = (page_group *)page - 1;
> else
> --- 640,670 ----
> #ifdef USING_MALLOC_PAGE_GROUPS
> else
> {
> /* Allocate a large block of memory and serve out the aligned
> pages therein. This results in much less memory wastage
> than the traditional implementation of valloc. */
>
> char *allocation, *a, *enda;
> size_t alloc_size, head_slop, tail_slop;
> int multiple_pages = (entry_size == G.pagesize);
>
> if (multiple_pages)
> alloc_size = GGC_QUIRE_SIZE * G.pagesize;
> else
> alloc_size = entry_size + G.pagesize - 1;
> ! allocation = xcalloc (1, alloc_size);
>
> page = (char *) (((size_t) allocation + G.pagesize - 1) &
> -G.pagesize);
> head_slop = page - allocation;
> if (multiple_pages)
> tail_slop = ((size_t) allocation + alloc_size) & (G.pagesize - 1);
> else
> tail_slop = alloc_size - entry_size - head_slop;
> enda = allocation + alloc_size - tail_slop;
>
> /* We allocated N pages, which are likely not aligned, leaving
> us with N-1 usable pages. We plan to place the page_group
> structure somewhere in the slop. */
> if (head_slop >= sizeof (page_group))
> group = (page_group *)page - 1;
> else
>
>
> I suspect that it has stayed hidden for so long because most people
> probably have this mmap_anon:
>
> /* Define if mmap can get us zeroed pages using MAP_ANON(YMOUS). */
> #undef HAVE_MMAP_ANON
>
>
> #ifdef HAVE_MMAP_ANON
> # undef HAVE_MMAP_DEV_ZERO
>
> # include <sys/mman.h>
> # ifndef MAP_FAILED
> # define MAP_FAILED -1
> # endif
> # if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
> # define MAP_ANONYMOUS MAP_ANON
> # endif
> # define USING_MMAP
>
> #endif
>
> #ifndef USING_MMAP
> #define USING_MALLOC_PAGE_GROUPS
> #endif
>
>
> Seems pretty clear that zeroed pages are required.
>
> Looking at the code above and below this block, it uses xcalloc
> instead.
>
> It will take a couple of days to confirm that this is the last
> presumed bug affecting the MUSIC/SP port.
>
> In the meantime, can someone confirm that this code is wrong,
> and that xcalloc is definitely required?
>
> I had a look at the gcc4 code, and it is calling XNEWVEC which
> is also using xmalloc instead of xcalloc, so I presume it is still
> a problem today, under the right circumstances.
>
> It took about a week to track this one down. :-)
>
> One problem I have had for years, even on the MVS port, is that
> I need to use -Os to get the exact same register selection on the
> PC as the mainframe. -O0 and -O2 get slightly different register
> allocations, although all versions of the code are correct. If I'm
> lucky, this fix may make that problem go away, but as I said,
> it'll take a couple of days before the results are in, as each build
> takes about 2 hours (partly because i need to use -Os for
> consistency).
>
> Thanks. Paul.
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* negative indexes
2009-11-28 16:03 ` Richard Guenther
@ 2021-03-14 5:55 ` Paul Edwards
2021-03-14 8:05 ` Richard Biener
0 siblings, 1 reply; 6+ messages in thread
From: Paul Edwards @ 2021-03-14 5:55 UTC (permalink / raw)
To: gcc
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.
Thanks. Paul.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: negative indexes
2021-03-14 5:55 ` negative indexes Paul Edwards
@ 2021-03-14 8:05 ` Richard Biener
2021-03-14 8:12 ` Paul Edwards
0 siblings, 1 reply; 6+ messages in thread
From: Richard Biener @ 2021-03-14 8:05 UTC (permalink / raw)
To: Paul Edwards, Paul Edwards via Gcc, gcc
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.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: negative indexes
2021-03-14 8:05 ` Richard Biener
@ 2021-03-14 8:12 ` Paul Edwards
2021-03-14 13:37 ` Richard Biener
0 siblings, 1 reply; 6+ messages in thread
From: Paul Edwards @ 2021-03-14 8:12 UTC (permalink / raw)
To: gcc, Richard Biener
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.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: negative indexes
2021-03-14 8:12 ` Paul Edwards
@ 2021-03-14 13:37 ` Richard Biener
[not found] ` <755065BE2A0B4B508DD3A262B2A83801@DESKTOP0OKG1VA>
0 siblings, 1 reply; 6+ messages in thread
From: Richard Biener @ 2021-03-14 13:37 UTC (permalink / raw)
To: Paul Edwards, gcc
On March 14, 2021 9:12:01 AM GMT+01:00, Paul Edwards <mutazilah@gmail.com> wrote:
>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.
And that's exactly what I said. Pmode is DImode but ptr_mode is SImode.
>
>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.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-03-15 9:23 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-14 11:48 negative indexes Paul Edwards
-- strict thread matches above, loose matches on Subject: below --
2009-11-24 14:05 i370 port - 3.4.6 to 4.4 upgrade attempt Ulrich Weigand
2009-11-28 15:14 ` i370 port - music/sp - possible generic gcc problem Paul Edwards
2009-11-28 16:03 ` Richard Guenther
2021-03-14 5:55 ` negative indexes Paul Edwards
2021-03-14 8:05 ` Richard Biener
2021-03-14 8:12 ` Paul Edwards
2021-03-14 13:37 ` Richard Biener
[not found] ` <755065BE2A0B4B508DD3A262B2A83801@DESKTOP0OKG1VA>
2021-03-15 9:22 ` Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).