const volatile behaviour change in GCC 7

2016-09-22 Thread Sebastian Huber

Hello,

for RTEMS we use linker sets to initialize the system. The following 
code worked up to GCC 6, but no longer in GCC 7:


typedef void ( *rtems_sysinit_handler )( void );

typedef struct {
  rtems_sysinit_handler handler;
} rtems_sysinit_item;

rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0]
__attribute__((__section__(".rtemsroset." "_Sysinit" ".begin")))
__attribute__((__used__));

rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0]
__attribute__((__section__(".rtemsroset." "_Sysinit" ".end")))
__attribute__((__used__));

void rtems_initialize_executive(void)
{
  const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin;
  const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end;

  while ( cur != end ) {
( *cur->handler )();
++cur;
  }
}

The corresponding GNU ld linker script section is:

.rtemsroset : ALIGN_WITH_INPUT {
KEEP (*(SORT(.rtemsroset.*)))
} > REGION_RODATA AT > REGION_RODATA_LOAD

In GCC 7, the compiler deduces that "cur != end" is always true and 
generates an infinite loop.


Up to GCC 6 the "volatile const" seemed to prevent this optimization. I 
know that this linker set stuff is quite non-standard, but is there a 
way to get this to work again on GCC 7?


The nice thing with the "type volatile const X[0]..." construct is that 
you can generate arbitrary linker sets via it without a need to edit the 
linker command file and with no storage overhead.


--
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail  : sebastian.hu...@embedded-brains.de
PGP : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.



Re: const volatile behaviour change in GCC 7

2016-09-22 Thread Andrew Pinski
On Thu, Sep 22, 2016 at 3:23 PM, Sebastian Huber
 wrote:
> Hello,
>
> for RTEMS we use linker sets to initialize the system. The following code
> worked up to GCC 6, but no longer in GCC 7:
>
> typedef void ( *rtems_sysinit_handler )( void );
>
> typedef struct {
>   rtems_sysinit_handler handler;
> } rtems_sysinit_item;
>
> rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0]
> __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin")))
> __attribute__((__used__));
>
> rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0]
> __attribute__((__section__(".rtemsroset." "_Sysinit" ".end")))
> __attribute__((__used__));
>
> void rtems_initialize_executive(void)
> {
>   const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin;
>   const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end;
>
>   while ( cur != end ) {
> ( *cur->handler )();
> ++cur;
>   }
> }
>
> The corresponding GNU ld linker script section is:
>
> .rtemsroset : ALIGN_WITH_INPUT {
> KEEP (*(SORT(.rtemsroset.*)))
> } > REGION_RODATA AT > REGION_RODATA_LOAD
>
> In GCC 7, the compiler deduces that "cur != end" is always true and
> generates an infinite loop.
>
> Up to GCC 6 the "volatile const" seemed to prevent this optimization. I know
> that this linker set stuff is quite non-standard, but is there a way to get
> this to work again on GCC 7?

Yes do the following (which will work with every GCC version):

#define MAKEGCCNOTKNOWTHEADDRESS(ptr) asm("":"+r"(ptr))

const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin;
const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end;
MAKEGCCNOTKNOWTHEADDRESS(cur);
MAKEGCCNOTKNOWTHEADDRESS(end);

You can think of better names if you want but this is the best way really.

Thanks,
Andrew Pinski


>
> The nice thing with the "type volatile const X[0]..." construct is that you
> can generate arbitrary linker sets via it without a need to edit the linker
> command file and with no storage overhead.
>
> --
> Sebastian Huber, embedded brains GmbH
>
> Address : Dornierstr. 4, D-82178 Puchheim, Germany
> Phone   : +49 89 189 47 41-16
> Fax : +49 89 189 47 41-09
> E-Mail  : sebastian.hu...@embedded-brains.de
> PGP : Public key available on request.
>
> Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
>


gcc 3.4.6 asm charset error

2016-09-22 Thread Paul Edwards

GCC 3.4.6 natively handles different character
sets for source and target. It actually works
fine, writing source code in ASCII targeting
an EBCDIC destination.

However, __asm() doesn't seem to be working.
As seen below, it is generating EBCDIC data
in the ASCII assembler output. Those funny
characters are in fact the EBCDIC code for
"ABC" and "DEF".

Anyone know how to fix this?

Thanks. Paul.




C:\scratch\bb99>type test.c
extern int i;

void foo(void)
{
   i = 5;
   __asm("ABC");
   __asm("DEF");
}

C:\scratch\bb99>gccmvs-3_4_6-1_0 -S test.c

C:\scratch\bb99>type test.s
COPY  PDPTOP
CSECT
* Program text area
DS0F
* X-func foo prologue
FOO  PDPPRLG CINDEX=0,FRAME=88,BASER=12,ENTRY=YES
B FEN0
LTORG
FEN0 EQU   *
DROP  12
BALR  12,0
USING *,12
PG0  EQU   *
LR11,1
L 10,=A(PGT0)
* Function foo code
L 2,=V(I)
MVC   0(4,2),=F'5'
┴┬├
─┼╞
* Function foo epilogue
PDPEPIL
* Function foo literal pool
DS0F
LTORG
* Function foo page table
DS0F
PGT0 EQU   *
DCA(PG0)
END

C:\scratch\bb99>



Re: const volatile behaviour change in GCC 7

2016-09-22 Thread Andreas Schwab
On Sep 22 2016, Sebastian Huber  wrote:

> for RTEMS we use linker sets to initialize the system. The following code
> worked up to GCC 6, but no longer in GCC 7:
>
> typedef void ( *rtems_sysinit_handler )( void );
>
> typedef struct {
>   rtems_sysinit_handler handler;
> } rtems_sysinit_item;
>
> rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0]
> __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin")))
> __attribute__((__used__));
>
> rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0]
> __attribute__((__section__(".rtemsroset." "_Sysinit" ".end")))
> __attribute__((__used__));
>
> void rtems_initialize_executive(void)
> {
>   const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin;
>   const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end;
>
>   while ( cur != end ) {
> ( *cur->handler )();
> ++cur;
>   }
> }
>
> The corresponding GNU ld linker script section is:
>
> .rtemsroset : ALIGN_WITH_INPUT {
> KEEP (*(SORT(.rtemsroset.*)))
> } > REGION_RODATA AT > REGION_RODATA_LOAD
>
> In GCC 7, the compiler deduces that "cur != end" is always true and
> generates an infinite loop.
>
> Up to GCC 6 the "volatile const" seemed to prevent this optimization.

These qualifiers do not say anything about the variable cur and end
themselves, only about the values they point to.  As such I don't see
how they can have any influence on the value of "cur != end".

Andreas.

-- 
Andreas Schwab, SUSE Labs, sch...@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


Re: const volatile behaviour change in GCC 7

2016-09-22 Thread Richard Biener
On Thu, Sep 22, 2016 at 9:58 AM, Andreas Schwab  wrote:
> On Sep 22 2016, Sebastian Huber  wrote:
>
>> for RTEMS we use linker sets to initialize the system. The following code
>> worked up to GCC 6, but no longer in GCC 7:
>>
>> typedef void ( *rtems_sysinit_handler )( void );
>>
>> typedef struct {
>>   rtems_sysinit_handler handler;
>> } rtems_sysinit_item;
>>
>> rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0]
>> __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin")))
>> __attribute__((__used__));
>>
>> rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0]
>> __attribute__((__section__(".rtemsroset." "_Sysinit" ".end")))
>> __attribute__((__used__));
>>
>> void rtems_initialize_executive(void)
>> {
>>   const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin;
>>   const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end;
>>
>>   while ( cur != end ) {
>> ( *cur->handler )();
>> ++cur;
>>   }
>> }
>>
>> The corresponding GNU ld linker script section is:
>>
>> .rtemsroset : ALIGN_WITH_INPUT {
>> KEEP (*(SORT(.rtemsroset.*)))
>> } > REGION_RODATA AT > REGION_RODATA_LOAD
>>
>> In GCC 7, the compiler deduces that "cur != end" is always true and
>> generates an infinite loop.
>>
>> Up to GCC 6 the "volatile const" seemed to prevent this optimization.
>
> These qualifiers do not say anything about the variable cur and end
> themselves, only about the values they point to.  As such I don't see
> how they can have any influence on the value of "cur != end".

Yeah, GCC 7 now optimizes pointer comparisons more aggressively.

OTOH I can't reproduce with a simpler

const int a[0];
const int b[0];
int foo ()
{
  return a != b;
}

unless I add 'static' to the vars at which point earlier GCC optimize this
as well.  Eventually you'll hit undefined behavior during loop analysis
as you are accessing a zero-sized array.  But I don't remember this
changing in GCC 7 either.

Richard.

> Andreas.
>
> --
> Andreas Schwab, SUSE Labs, sch...@suse.de
> GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
> "And now for something completely different."


Re: const volatile behaviour change in GCC 7

2016-09-22 Thread David Brown
On 22/09/16 09:23, Sebastian Huber wrote:
> Hello,
> 
> for RTEMS we use linker sets to initialize the system. The following
> code worked up to GCC 6, but no longer in GCC 7:
> 
> typedef void ( *rtems_sysinit_handler )( void );
> 
> typedef struct {
>   rtems_sysinit_handler handler;
> } rtems_sysinit_item;
> 
> rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0]
> __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin")))
> __attribute__((__used__));
> 
> rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0]
> __attribute__((__section__(".rtemsroset." "_Sysinit" ".end")))
> __attribute__((__used__));
> 
> void rtems_initialize_executive(void)
> {
>   const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin;
>   const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end;
> 
>   while ( cur != end ) {
> ( *cur->handler )();
> ++cur;
>   }
> }
> 

Your trouble is that your two pointers, cur and end, are pointing at
different variables.  Comparing two pointers that are independent (i.e.,
not pointing to parts of the same aggregate object) is undefined - the
compiler can assume that these two external objects could be anywhere in
memory, so there is no way (in pure C) for you to know or care how they
are related.  Therefore it can assume that you will never reach "cur ==
end".

Ideally, you want to tell the compiler that you are dealing with an
array, rather than two independent pointers.  But I am not sure how to
express this without at least a little extra overhead (such as having
the linker generate an "array size" constant that you read along with
the start of the array).  Andrew's MAKEGCCNOTKNOWTHEADDRESS macro will
work, however.

> The corresponding GNU ld linker script section is:
> 
> .rtemsroset : ALIGN_WITH_INPUT {
> KEEP (*(SORT(.rtemsroset.*)))
> } > REGION_RODATA AT > REGION_RODATA_LOAD
> 
> In GCC 7, the compiler deduces that "cur != end" is always true and
> generates an infinite loop.
> 
> Up to GCC 6 the "volatile const" seemed to prevent this optimization. I
> know that this linker set stuff is quite non-standard, but is there a
> way to get this to work again on GCC 7?
> 
> The nice thing with the "type volatile const X[0]..." construct is that
> you can generate arbitrary linker sets via it without a need to edit the
> linker command file and with no storage overhead.
> 



Re: const volatile behaviour change in GCC 7

2016-09-22 Thread Sergey Organov

Sebastian Huber  writes:
> Hello,
>
> for RTEMS we use linker sets to initialize the system. The following
> code worked up to GCC 6, but no longer in GCC 7:
>
> typedef void ( *rtems_sysinit_handler )( void );
>
> typedef struct {
>   rtems_sysinit_handler handler;
> } rtems_sysinit_item;
>
> rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0]
> __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin")))
> __attribute__((__used__));
>
> rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0]
> __attribute__((__section__(".rtemsroset." "_Sysinit" ".end")))
> __attribute__((__used__));
>
> void rtems_initialize_executive(void)
> {
>   const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin;
>   const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end;

You likely have 'volatile' in a wrong place. Try (untested):

rtems_sysinit_item const _Linker_set__Sysinit_begin[0]
__attribute__((__section__(".rtemsroset." "_Sysinit" ".begin")))
__attribute__((__used__));

rtems_sysinit_item const _Linker_set__Sysinit_end[0]
__attribute__((__section__(".rtemsroset." "_Sysinit" ".end")))
__attribute__((__used__));

void rtems_initialize_executive(void)
{
  rtems_sysinit_item const *volatile cur = _Linker_set__Sysinit_begin;
  rtems_sysinit_item const *volatile end = _Linker_set__Sysinit_end;

  while(cur != end) {
cur->handler();
++cur;
  }
}

Alternatively, try (untested, and I removed attributes to make my point
clearer): 

/* Linker-defined symbols */

rtems_sysinit_item const _Linker_set__Sysinit_begin[0]
__attribute__((__section__(".rtemsroset." "_Sysinit" ".begin")))
__attribute__((__used__));

rtems_sysinit_item const _Linker_set__Sysinit_end[0]
__attribute__((__section__(".rtemsroset." "_Sysinit" ".end")))
__attribute__((__used__));

/* Get volatile pointers to the above */
static rtems_sysinit_item const *volatile begin_ = _Linker_set__Sysinit_begin;
static rtems_sysinit_item const *volatile end_   = _Linker_set__Sysinit_end;

void rtems_initialize_executive(void)
{
  rtems_sysinit_item const *cur = begin_;
  rtems_sysinit_item const *end = end_;

  while(cur != end) {
cur->handler();
++cur;
  }
}

HTH

-- Sergey



Re: const volatile behaviour change in GCC 7

2016-09-22 Thread Sebastian Huber



On 22/09/16 14:11, Sergey Organov wrote:

Sebastian Huber  writes:

Hello,

for RTEMS we use linker sets to initialize the system. The following
code worked up to GCC 6, but no longer in GCC 7:

typedef void ( *rtems_sysinit_handler )( void );

typedef struct {
   rtems_sysinit_handler handler;
} rtems_sysinit_item;

rtems_sysinit_item volatile const _Linker_set__Sysinit_begin[0]
__attribute__((__section__(".rtemsroset." "_Sysinit" ".begin")))
__attribute__((__used__));

rtems_sysinit_item volatile const _Linker_set__Sysinit_end[0]
__attribute__((__section__(".rtemsroset." "_Sysinit" ".end")))
__attribute__((__used__));

void rtems_initialize_executive(void)
{
   const volatile rtems_sysinit_item *cur = _Linker_set__Sysinit_begin;
   const volatile rtems_sysinit_item *end = _Linker_set__Sysinit_end;

You likely have 'volatile' in a wrong place. Try (untested):

rtems_sysinit_item const _Linker_set__Sysinit_begin[0]
__attribute__((__section__(".rtemsroset." "_Sysinit" ".begin")))
__attribute__((__used__));

rtems_sysinit_item const _Linker_set__Sysinit_end[0]
__attribute__((__section__(".rtemsroset." "_Sysinit" ".end")))
__attribute__((__used__));

void rtems_initialize_executive(void)
{
   rtems_sysinit_item const *volatile cur = _Linker_set__Sysinit_begin;
   rtems_sysinit_item const *volatile end = _Linker_set__Sysinit_end;

   while(cur != end) {
 cur->handler();
 ++cur;
   }
}


No, I don't want to load/store the pointers from/to memory all the time 
in this loop.




Alternatively, try (untested, and I removed attributes to make my point
clearer):

/* Linker-defined symbols */

rtems_sysinit_item const _Linker_set__Sysinit_begin[0]
__attribute__((__section__(".rtemsroset." "_Sysinit" ".begin")))
__attribute__((__used__));

rtems_sysinit_item const _Linker_set__Sysinit_end[0]
__attribute__((__section__(".rtemsroset." "_Sysinit" ".end")))
__attribute__((__used__));

/* Get volatile pointers to the above */
static rtems_sysinit_item const *volatile begin_ = _Linker_set__Sysinit_begin;
static rtems_sysinit_item const *volatile end_   = _Linker_set__Sysinit_end;

void rtems_initialize_executive(void)
{
   rtems_sysinit_item const *cur = begin_;
   rtems_sysinit_item const *end = end_;

   while(cur != end) {
 cur->handler();
 ++cur;
   }
}




I don't want any storage for these begin/end markers.

--
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail  : sebastian.hu...@embedded-brains.de
PGP : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.



Re: const volatile behaviour change in GCC 7

2016-09-22 Thread Paul.Koning

> On Sep 22, 2016, at 6:17 AM, David Brown  wrote:
> 
> ...
> Your trouble is that your two pointers, cur and end, are pointing at
> different variables.  Comparing two pointers that are independent (i.e.,
> not pointing to parts of the same aggregate object) is undefined - the
> compiler can assume that these two external objects could be anywhere in
> memory, so there is no way (in pure C) for you to know or care how they
> are related.  Therefore it can assume that you will never reach "cur ==
> end".

Would making them intptr_t instead of pointers fix that?

paul



Re: const volatile behaviour change in GCC 7

2016-09-22 Thread David Brown
On 22/09/16 16:57, paul.kon...@dell.com wrote:
> 
>> On Sep 22, 2016, at 6:17 AM, David Brown  wrote:
>>
>> ...
>> Your trouble is that your two pointers, cur and end, are pointing at
>> different variables.  Comparing two pointers that are independent (i.e.,
>> not pointing to parts of the same aggregate object) is undefined - the
>> compiler can assume that these two external objects could be anywhere in
>> memory, so there is no way (in pure C) for you to know or care how they
>> are related.  Therefore it can assume that you will never reach "cur ==
>> end".
> 
> Would making them intptr_t instead of pointers fix that?
> 

With care, yes.  But I think it still relies on gcc not being quite as
smart as it could be.  This seems to generate working code, but the
compier could in theory still apply the same analysis:

void rtems_initialize_executive(void)
{
  uintptr_t cur = (uintptr_t) _Linker_set__Sysinit_begin;
  uintptr_t end = (uintptr_t) _Linker_set__Sysinit_end;

  while ( cur != end ) {
const volatile rtems_sysinit_item *p = (const volatile
rtems_sysinit_item *) cur;
( *p->handler )();
cur += sizeof(p);
  }
}





Re: const volatile behaviour change in GCC 7

2016-09-22 Thread Paul.Koning

> On Sep 22, 2016, at 11:16 AM, David Brown  wrote:
> 
> On 22/09/16 16:57, paul.kon...@dell.com wrote:
>> 
>>> On Sep 22, 2016, at 6:17 AM, David Brown  wrote:
>>> 
>>> ...
>>> Your trouble is that your two pointers, cur and end, are pointing at
>>> different variables.  Comparing two pointers that are independent (i.e.,
>>> not pointing to parts of the same aggregate object) is undefined - the
>>> compiler can assume that these two external objects could be anywhere in
>>> memory, so there is no way (in pure C) for you to know or care how they
>>> are related.  Therefore it can assume that you will never reach "cur ==
>>> end".
>> 
>> Would making them intptr_t instead of pointers fix that?
>> 
> 
> With care, yes.  But I think it still relies on gcc not being quite as
> smart as it could be.  This seems to generate working code, but the
> compier could in theory still apply the same analysis:
> 
> void rtems_initialize_executive(void)
> {
>  uintptr_t cur = (uintptr_t) _Linker_set__Sysinit_begin;
>  uintptr_t end = (uintptr_t) _Linker_set__Sysinit_end;

I would not expect the compiler to apply pointer rules for code like this.  
(u)intptr_t is an integer type; it happens to be one whose width is chosen to 
match the width of pointers on the platform in question, but that doesn't 
change the fact the type is integer.  For example, it is perfectly valid for an 
intptr_t variable to contain values that could not possibly be pointers on a 
given platform.

paul


Re: const volatile behaviour change in GCC 7

2016-09-22 Thread Richard Biener
On September 22, 2016 5:20:56 PM GMT+02:00, paul.kon...@dell.com wrote:
>
>> On Sep 22, 2016, at 11:16 AM, David Brown 
>wrote:
>> 
>> On 22/09/16 16:57, paul.kon...@dell.com wrote:
>>> 
 On Sep 22, 2016, at 6:17 AM, David Brown 
>wrote:
 
 ...
 Your trouble is that your two pointers, cur and end, are pointing
>at
 different variables.  Comparing two pointers that are independent
>(i.e.,
 not pointing to parts of the same aggregate object) is undefined -
>the
 compiler can assume that these two external objects could be
>anywhere in
 memory, so there is no way (in pure C) for you to know or care how
>they
 are related.  Therefore it can assume that you will never reach
>"cur ==
 end".
>>> 
>>> Would making them intptr_t instead of pointers fix that?
>>> 
>> 
>> With care, yes.  But I think it still relies on gcc not being quite
>as
>> smart as it could be.  This seems to generate working code, but the
>> compier could in theory still apply the same analysis:
>> 
>> void rtems_initialize_executive(void)
>> {
>>  uintptr_t cur = (uintptr_t) _Linker_set__Sysinit_begin;
>>  uintptr_t end = (uintptr_t) _Linker_set__Sysinit_end;
>
>I would not expect the compiler to apply pointer rules for code like
>this.  (u)intptr_t is an integer type; it happens to be one whose width
>is chosen to match the width of pointers on the platform in question,
>but that doesn't change the fact the type is integer.  For example, it
>is perfectly valid for an intptr_t variable to contain values that
>could not possibly be pointers on a given platform.

I can't see how it could either.  BTW your testcase contains another fragility, 
the order of two global vars.

Richard.

>   paul




Re: const volatile behaviour change in GCC 7

2016-09-22 Thread Richard Earnshaw (lists)
On 22/09/16 16:20, paul.kon...@dell.com wrote:
> 
>> On Sep 22, 2016, at 11:16 AM, David Brown  wrote:
>>
>> On 22/09/16 16:57, paul.kon...@dell.com wrote:
>>>
 On Sep 22, 2016, at 6:17 AM, David Brown  wrote:

 ...
 Your trouble is that your two pointers, cur and end, are pointing at
 different variables.  Comparing two pointers that are independent (i.e.,
 not pointing to parts of the same aggregate object) is undefined - the
 compiler can assume that these two external objects could be anywhere in
 memory, so there is no way (in pure C) for you to know or care how they
 are related.  Therefore it can assume that you will never reach "cur ==
 end".
>>>
>>> Would making them intptr_t instead of pointers fix that?
>>>
>>
>> With care, yes.  But I think it still relies on gcc not being quite as
>> smart as it could be.  This seems to generate working code, but the
>> compier could in theory still apply the same analysis:
>>
>> void rtems_initialize_executive(void)
>> {
>>  uintptr_t cur = (uintptr_t) _Linker_set__Sysinit_begin;
>>  uintptr_t end = (uintptr_t) _Linker_set__Sysinit_end;
> 
> I would not expect the compiler to apply pointer rules for code like this.  
> (u)intptr_t is an integer type; it happens to be one whose width is chosen to 
> match the width of pointers on the platform in question, but that doesn't 
> change the fact the type is integer.  For example, it is perfectly valid for 
> an intptr_t variable to contain values that could not possibly be pointers on 
> a given platform.
> 
>   paul
> 

It sounds to me as these are the sort of optimizations that should be
disabled when compiling with -ffreestanding.

R.


Re: const volatile behaviour change in GCC 7

2016-09-22 Thread Paul.Koning

> On Sep 22, 2016, at 11:31 AM, Richard Earnshaw (lists) 
>  wrote:
> 
>>> ...
>>> void rtems_initialize_executive(void)
>>> {
>>> uintptr_t cur = (uintptr_t) _Linker_set__Sysinit_begin;
>>> uintptr_t end = (uintptr_t) _Linker_set__Sysinit_end;
>> 
>> I would not expect the compiler to apply pointer rules for code like this.  
>> (u)intptr_t is an integer type; it happens to be one whose width is chosen 
>> to match the width of pointers on the platform in question, but that doesn't 
>> change the fact the type is integer.  For example, it is perfectly valid for 
>> an intptr_t variable to contain values that could not possibly be pointers 
>> on a given platform.
>> 
>>  paul
>> 
> 
> It sounds to me as these are the sort of optimizations that should be
> disabled when compiling with -ffreestanding.

Possibly so.  I dislike workarounds of that form; it seems safer to change the 
C code to rely on properties called out by the standard.  After all, if an 
optimization is permitted, it might at some future time be done, and counting 
on there to be a way to turn off that optimization via a switch, or relying on 
that switch not changing across releases, isn't as safe.

paul



Re: const volatile behaviour change in GCC 7

2016-09-22 Thread Sergey Organov
Sebastian Huber  writes:

> On 22/09/16 14:11, Sergey Organov wrote:
>> Sebastian Huber  writes:
>>> Hello,

[...]

>> Alternatively, try (untested, and I removed attributes to make my point
>> clearer):
>>
>> /* Linker-defined symbols */
>>
>> rtems_sysinit_item const _Linker_set__Sysinit_begin[0]
>> __attribute__((__section__(".rtemsroset." "_Sysinit" ".begin")))
>> __attribute__((__used__));
>>
>> rtems_sysinit_item const _Linker_set__Sysinit_end[0]
>> __attribute__((__section__(".rtemsroset." "_Sysinit" ".end")))
>> __attribute__((__used__));
>>
>> /* Get volatile pointers to the above */
>> static rtems_sysinit_item const *volatile begin_ = 
>> _Linker_set__Sysinit_begin;
>> static rtems_sysinit_item const *volatile end_   = _Linker_set__Sysinit_end;
>>
>> void rtems_initialize_executive(void)
>> {
>>rtems_sysinit_item const *cur = begin_;
>>rtems_sysinit_item const *end = end_;
>>
>>while(cur != end) {
>>  cur->handler();
>>  ++cur;
>>}
>> }
>>
>>
>
> I don't want any storage for these begin/end markers.

Why? 8 more bytes in context of RTEMS? It likely doesn't matter. At all.

-- Sergey



Re: const volatile behaviour change in GCC 7

2016-09-22 Thread David Brown

On 22/09/16 17:30, Richard Biener wrote:

On September 22, 2016 5:20:56 PM GMT+02:00, paul.kon...@dell.com
wrote:



On Sep 22, 2016, at 11:16 AM, David Brown


wrote:


On 22/09/16 16:57, paul.kon...@dell.com wrote:



On Sep 22, 2016, at 6:17 AM, David Brown


wrote:


... Your trouble is that your two pointers, cur and end, are
pointing at different variables. Comparing two pointers that
are independent (i.e., not pointing to parts of the same
aggregate object) is undefined - the compiler can assume that
these two external objects could beanywhere in
memory, so there is no way (in pure C) for you to know or
care how they are related. Therefore it can assume that you
will never reach "cur == end".


Would making them intptr_t instead of pointers fix that?



With care, yes.  But I think it still relies on gcc not being
quite

as

smart as it could be.  This seems to generate working code, but
the compier could in theory still apply the same analysis:

void rtems_initialize_executive(void) { uintptr_t cur =
(uintptr_t) _Linker_set__Sysinit_begin; uintptr_t end =
(uintptr_t) _Linker_set__Sysinit_end;


I would not expect the compiler to apply pointer rules for code
like this.  (u)intptr_t is an integer type; it happens to be one
whose width is chosen to match the width of pointers on the
platform in question, but that doesn't change the fact the type is
integer.  For example, it is perfectly valid for an intptr_t
variable to contain values that could not possibly be pointers on
a given platform.


The compiler /can/ perform such analysis and see the undefined behaviour 
of the code, and use that to optimise away the check for the loop.  It 
is legal to convert (by cast or initialisation) an intptr_t or uintptr_t 
variable to a pointer - but it is /not/ legal to dereference it unless 
the intptr_t or uintptr_t was set from a legal pointer.  Thus when the 
compiler is considering the validity of access through the casted 
uintptr_t variable, it can look back to where the contents of that 
variable came and consider those pointers.  Since the compiler can 
assume that incrementing one pointer repeatedly never matches the other 
pointer (as they point to unrelated objects), the same applies even if 
the values have been cast back and forth through intptr_t variables.


In general, I find that if you can't figure out a simple way to express 
your desires for this sort of thing using fully defined standard C 
behaviour, then complex methods with castings and the like will not be 
entirely correct either.  They might work at the moment - gcc is a smart 
compiler, but it has its limits - but they might not work in the future 
(as the compiler gets better all the time).  Compiler-specific 
workarounds like the assembly macro proposed are often the safest 
methods.  Alternatively, you accept a slight performance hit by using an 
extra "volatile" step to limit the optimisation.  Or you change the 
requirements, by finding a different way to handle it - such as by 
letting the linker figure out the size of the table and including it as 
a readable constant.




I can't see how it could either.  BTW your testcase contains another
fragility, the order of two global vars.



That is, in fact, the crux of the problem - the two linker symbols are 
unrelated, so by the rules of C pointers they are incomparable as are 
all pointers derived from them.




Re: gcc 3.4.6 asm charset error

2016-09-22 Thread Segher Boessenkool
On Thu, Sep 22, 2016 at 05:35:22PM +1000, Paul Edwards wrote:
> GCC 3.4.6 natively handles different character
> sets for source and target. It actually works
> fine, writing source code in ASCII targeting
> an EBCDIC destination.
> 
> However, __asm() doesn't seem to be working.
> As seen below, it is generating EBCDIC data
> in the ASCII assembler output. Those funny
> characters are in fact the EBCDIC code for
> "ABC" and "DEF".
> 
> Anyone know how to fix this?

Does it work better with a GCC version that is less than ten years old?


Segher


gcc-6-20160922 is now available

2016-09-22 Thread gccadmin
Snapshot gcc-6-20160922 is now available on
  ftp://gcc.gnu.org/pub/gcc/snapshots/6-20160922/
and on various mirrors, see http://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 6 SVN branch
with the following options: svn://gcc.gnu.org/svn/gcc/branches/gcc-6-branch 
revision 240383

You'll find:

 gcc-6-20160922.tar.bz2   Complete GCC

  MD5=c0cb1ea933dc6de83a2a026f6478c89e
  SHA1=b112e29bb8ad178c14d39ead01f61b14e81fde51

Diffs from 6-20160915 are available in the diffs/ subdirectory.

When a particular snapshot is ready for public consumption the LATEST-6
link is updated and a message is sent to the gcc list.  Please do not use
a snapshot before it has been announced that way.


Re: gcc 3.4.6 asm charset error

2016-09-22 Thread Paul Edwards

GCC 3.4.6 is the last version of GCC that
supports the i370 target that I use.

Last time I tried adding the i370 target
from GCC 3.4.6 to GCC 4.x I got errors
that I don't know how to fix.

Actually GCC 3.4.6 also has errors which
I don't know how to fix, so I normally
use GCC 3.2.3.

I hope one day someone with the
required technical skills will volunteer
to fix the remaining problems with
GCC on MVS, and i370 will be a target
once again in the latest GCC, but
no-one has volunteered to clean it
up for more than a decade.

BFN. Paul.




-Original Message- 
From: Segher Boessenkool 
Sent: Friday, September 23, 2016 6:21 AM 
To: Paul Edwards 
Cc: gcc@gcc.gnu.org 
Subject: Re: gcc 3.4.6 asm charset error 


On Thu, Sep 22, 2016 at 05:35:22PM +1000, Paul Edwards wrote:

GCC 3.4.6 natively handles different character
sets for source and target. It actually works
fine, writing source code in ASCII targeting
an EBCDIC destination.

However, __asm() doesn't seem to be working.
As seen below, it is generating EBCDIC data
in the ASCII assembler output. Those funny
characters are in fact the EBCDIC code for
"ABC" and "DEF".

Anyone know how to fix this?


Does it work better with a GCC version that is less than ten years old?


Segher