public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* 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

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).