Re: gcc 3.2.3 x64 negative indexes

2024-02-10 Thread Paul Edwards via Gcc
Problem solved.

I didn't have this:

#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")

because I wasn't including x86_64.h.

This is the first time I have attempted to go to 64-bit pointers
so I wasn't aware this even existed.

So here it is doing Win64 ABI:

D:\devel\gcc\gcc>gcc-new -O2 -S foo.c

D:\devel\gcc\gcc>type foo.s
.file   "foo.c"
.text
.p2align 2,,3
.globl foo
foo:
.LFB1:
movsbl  -1(%rcx),%eax
ret
.LFE1:

D:\devel\gcc\gcc>


Thanks for your help.

BFN. Paul.




On Sat, 10 Feb 2024 at 21:41, Paul Edwards  wrote:

> I have it down to a deliberate conversion from signed
> to unsigned:
>
> temp.txt: bbb piss ccc 32 32
> temp.txt: bbb piss ccc2 0 1
> temp.txt: bbb piss ddd -2
> temp.txt: bbb - in convert
> temp.txt: bbb - converting to integer
> temp.txt: bbb y stage1
> temp.txt: bbb y stage2
> temp.txt: bbb y outprec thing, inprec 32, outprec 32
> temp.txt: bbb - in build1
> temp.txt: bbb - build1 code 115
> temp.txt: bbb - build1 - default
> temp.txt: bbb - node is currently -2
> temp.txt: bbb - build1 - setting constant
> temp.txt: bbb in fold
> temp.txt: bbb fold2
> temp.txt: bbb fold2b 115
> temp.txt: bbb fold2d 77 115 61
> temp.txt: bbb fold4
> temp.txt: bbb fold5
> temp.txt: bbb -2 -1
> temp.txt: bbbj 0
> temp.txt: bbb piss eee 4294967294
>
>
> Which then gets preserved, because HOST_WIDE_INT (long) is 64 bits.
>
> And I see no attempt to put it back to a signed value in the below code.
>
> I'm not sure how it is supposed to work.
>
> I'll see if I can get further tomorrow.
>
> Oh, I also switched the code fragment to:
>
> D:\devel\gcc\gcc>type foo.c
> int foo(long *in)
> {
> return in[-2];
> }
>
> So that the multiply by 8 (size of long) is more obvious (in other
> debug output).
>
> BFN. Paul.
>
>
>
>
> /* Return a tree for the sum or difference (RESULTCODE says which)
>of pointer PTROP and integer INTOP.  */
>
> tree
> pointer_int_sum (resultcode, ptrop, intop)
>  enum tree_code resultcode;
>  tree ptrop, intop;
>
>
> ...
>
>   /* Convert the integer argument to a type the same size as sizetype
>  so the multiply won't overflow spuriously.  */
>
>   if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
>   || TREE_UNSIGNED (TREE_TYPE (intop)) != TREE_UNSIGNED (sizetype))
>   {
> printf("bbb piss ccc %d %d\n",
> (int)TYPE_PRECISION (TREE_TYPE (intop)), (int)TYPE_PRECISION (sizetype)
>   );
> printf("bbb piss ccc2 %d %d\n",
>  (int)TREE_UNSIGNED (TREE_TYPE (intop)),
>  (int)TREE_UNSIGNED (sizetype));
> printf("bbb piss ddd %ld\n", (long)TREE_INT_CST_LOW((intop)));
> intop = convert (type_for_size (TYPE_PRECISION (sizetype),
> TREE_UNSIGNED (sizetype)), intop);
> printf("bbb piss eee %ld\n", (long)TREE_INT_CST_LOW((intop)));
>   }
>
>   /* Replace the integer argument with a suitable product by the object
> size.
>  Do this multiplication as signed, then convert to the appropriate
>  pointer type (actually unsigned integral).  */
>
> printf("bbb piss3\n");
>   intop = convert (result_type,
>build_binary_op (MULT_EXPR, intop,
>         convert (TREE_TYPE (intop), size_exp),
> 1));
>
>   /* Create the sum or difference.  */
>
>   result = build (resultcode, result_type, ptrop, intop);
>
> printf("bbb piss4\n");
>   folded = fold (result);
>   if (folded == result)
> TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop);
>   return folded;
> }
>
>
>
> On Sat, 10 Feb 2024 at 05:38, Paul Edwards  wrote:
>
>> Oh - I switched to -2 to make debugging easier:
>>
>> D:\devel\gcc\gcc>type foo.c
>> int foo(char *in)
>> {
>> return in[-2];
>> }
>>
>> D:\devel\gcc\gcc>
>>
>>
>> Note that my flavor of gcc 3.2.3 can be found in gcc-stage*.zip
>> in custom.zip at http://pdos.org
>>
>>
>>
>>
>> On Sat, 10 Feb 2024 at 05:34, Paul Edwards  wrote:
>>
>>> On Wed, 7 Feb 2024 at 23:12, Jakub Jelinek  wrote:
>>> On Wed, Feb 07, 2024 at 11:02:51PM +0800, Paul Edwards via Gcc wrote:
>>>
>>> >> I am using a slightly modified gcc 3.2.3 for x86_64 and for this code:
>>>
>>> > Don't, gcc 3.2.3 is not supported for more than 20 years already.
>>>
>>> And the i370 target hasn't been supported for that long
>>> either

Re: gcc 3.2.3 x64 negative indexes

2024-02-10 Thread Paul Edwards via Gcc
(replying to Joe Monk)

> It appears that this is not an issue that this version of GCC is
> architected to be able to solve.

> The first 64-bit PC processor, the AMD opteron series, was launched on
> April 22, 2003.

> GCC 3.2.3 was released on April 25, 2003.

Jakub has already shown correct x64 code being generated
by gcc 3.2.3. Maybe they used an emulator or something.

And I already have it running myself - with small modifications
for MSABI - on Windows 10 64-bit - for my pdptest test program.

The only thing not working for me at the moment that I know
about is negative indexes. And that is something specific to my
derivative (or more likely the way I built it), not standard gcc 3.2.3.

BFN. Paul.


Re: gcc 3.2.3 x64 negative indexes

2024-02-10 Thread Paul Edwards via Gcc
I have it down to a deliberate conversion from signed
to unsigned:

temp.txt: bbb piss ccc 32 32
temp.txt: bbb piss ccc2 0 1
temp.txt: bbb piss ddd -2
temp.txt: bbb - in convert
temp.txt: bbb - converting to integer
temp.txt: bbb y stage1
temp.txt: bbb y stage2
temp.txt: bbb y outprec thing, inprec 32, outprec 32
temp.txt: bbb - in build1
temp.txt: bbb - build1 code 115
temp.txt: bbb - build1 - default
temp.txt: bbb - node is currently -2
temp.txt: bbb - build1 - setting constant
temp.txt: bbb in fold
temp.txt: bbb fold2
temp.txt: bbb fold2b 115
temp.txt: bbb fold2d 77 115 61
temp.txt: bbb fold4
temp.txt: bbb fold5
temp.txt: bbb -2 -1
temp.txt: bbbj 0
temp.txt: bbb piss eee 4294967294


Which then gets preserved, because HOST_WIDE_INT (long) is 64 bits.

And I see no attempt to put it back to a signed value in the below code.

I'm not sure how it is supposed to work.

I'll see if I can get further tomorrow.

Oh, I also switched the code fragment to:

D:\devel\gcc\gcc>type foo.c
int foo(long *in)
{
return in[-2];
}

So that the multiply by 8 (size of long) is more obvious (in other
debug output).

BFN. Paul.




/* Return a tree for the sum or difference (RESULTCODE says which)
   of pointer PTROP and integer INTOP.  */

tree
pointer_int_sum (resultcode, ptrop, intop)
 enum tree_code resultcode;
 tree ptrop, intop;


...

  /* Convert the integer argument to a type the same size as sizetype
 so the multiply won't overflow spuriously.  */

  if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
  || TREE_UNSIGNED (TREE_TYPE (intop)) != TREE_UNSIGNED (sizetype))
  {
printf("bbb piss ccc %d %d\n",
(int)TYPE_PRECISION (TREE_TYPE (intop)), (int)TYPE_PRECISION (sizetype)
  );
printf("bbb piss ccc2 %d %d\n",
 (int)TREE_UNSIGNED (TREE_TYPE (intop)),
 (int)TREE_UNSIGNED (sizetype));
printf("bbb piss ddd %ld\n", (long)TREE_INT_CST_LOW((intop)));
intop = convert (type_for_size (TYPE_PRECISION (sizetype),
TREE_UNSIGNED (sizetype)), intop);
printf("bbb piss eee %ld\n", (long)TREE_INT_CST_LOW((intop)));
  }

  /* Replace the integer argument with a suitable product by the object
size.
 Do this multiplication as signed, then convert to the appropriate
 pointer type (actually unsigned integral).  */

printf("bbb piss3\n");
  intop = convert (result_type,
   build_binary_op (MULT_EXPR, intop,
convert (TREE_TYPE (intop), size_exp),
1));

  /* Create the sum or difference.  */

  result = build (resultcode, result_type, ptrop, intop);

printf("bbb piss4\n");
  folded = fold (result);
  if (folded == result)
TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop);
  return folded;
}



On Sat, 10 Feb 2024 at 05:38, Paul Edwards  wrote:

> Oh - I switched to -2 to make debugging easier:
>
> D:\devel\gcc\gcc>type foo.c
> int foo(char *in)
> {
> return in[-2];
> }
>
> D:\devel\gcc\gcc>
>
>
> Note that my flavor of gcc 3.2.3 can be found in gcc-stage*.zip
> in custom.zip at http://pdos.org
>
>
>
>
> On Sat, 10 Feb 2024 at 05:34, Paul Edwards  wrote:
>
>> On Wed, 7 Feb 2024 at 23:12, Jakub Jelinek  wrote:
>> On Wed, Feb 07, 2024 at 11:02:51PM +0800, Paul Edwards via Gcc wrote:
>>
>> >> I am using a slightly modified gcc 3.2.3 for x86_64 and for this code:
>>
>> > Don't, gcc 3.2.3 is not supported for more than 20 years already.
>>
>> And the i370 target hasn't been supported for that long
>> either - but that's a target I want too.
>>
>> And nor has any version ever run on MVS 3.8J - but
>> that's an execution platform I want too.
>>
>> And the same goes for PDOS/386 as an execution platform.
>>
>> >> int fff(char *x)
>> >> {
>> >> return (x[-1]);
>> >> }
>> >
>> >> It is generating:
>> >
>> >> .globl fff
>> >> fff:
>> >> .LFB2:
>> >> movl$4294967295, %eax
>> >> movsbl  (%rax,%rcx),%eax
>>
>> > That said, I can't reproduce it and get
>> >movsbl  -1(%rdi),%eax
>> >ret
>> > from 3.2.3.
>>
>> Thanks for that! So one of the "slight modifications"
>> was to switch to Win64 ABI, which is why rcx is being
>> selected instead of rdi. So that bit is expected.
>>
>> So I need to know why I'm not getting -1.
>>
>> Since your email I have been trying to explain that.
>> It is likely a problem with the C library I am using
>> (PDPCLIB) - strtol or something like that.
>>
>> I am using 64-bit longs and I can 

Re: gcc 3.2.3 x64 negative indexes

2024-02-09 Thread Paul Edwards via Gcc
Oh - I switched to -2 to make debugging easier:

D:\devel\gcc\gcc>type foo.c
int foo(char *in)
{
return in[-2];
}

D:\devel\gcc\gcc>


Note that my flavor of gcc 3.2.3 can be found in gcc-stage*.zip
in custom.zip at http://pdos.org




On Sat, 10 Feb 2024 at 05:34, Paul Edwards  wrote:

> On Wed, 7 Feb 2024 at 23:12, Jakub Jelinek  wrote:
> On Wed, Feb 07, 2024 at 11:02:51PM +0800, Paul Edwards via Gcc wrote:
>
> >> I am using a slightly modified gcc 3.2.3 for x86_64 and for this code:
>
> > Don't, gcc 3.2.3 is not supported for more than 20 years already.
>
> And the i370 target hasn't been supported for that long
> either - but that's a target I want too.
>
> And nor has any version ever run on MVS 3.8J - but
> that's an execution platform I want too.
>
> And the same goes for PDOS/386 as an execution platform.
>
> >> int fff(char *x)
> >> {
> >> return (x[-1]);
> >> }
> >
> >> It is generating:
> >
> >> .globl fff
> >> fff:
> >> .LFB2:
> >> movl$4294967295, %eax
> >> movsbl  (%rax,%rcx),%eax
>
> > That said, I can't reproduce it and get
> >movsbl  -1(%rdi),%eax
> >ret
> > from 3.2.3.
>
> Thanks for that! So one of the "slight modifications"
> was to switch to Win64 ABI, which is why rcx is being
> selected instead of rdi. So that bit is expected.
>
> So I need to know why I'm not getting -1.
>
> Since your email I have been trying to explain that.
> It is likely a problem with the C library I am using
> (PDPCLIB) - strtol or something like that.
>
> I am using 64-bit longs and I can see that that large
> value (-1 as unsigned 32-bit) is being stored in the
> 64-bit field and being preserved.
>
> So far I have tracked it down to happening in the
> early stages. fold() is called and I can see that it
> is initially good for something, and bad later.
>
> I'm still working on it.
>
> BFN. Paul.
>
>
> fold-const.c
>
> tree
> fold (expr)
>  tree expr;
> {
>   tree t = expr;
>   tree t1 = NULL_TREE;
>   tree tem;
>   tree type = TREE_TYPE (expr);
>   tree arg0 = NULL_TREE, arg1 = NULL_TREE;
>   enum tree_code code = TREE_CODE (t);
>   int kind = TREE_CODE_CLASS (code);
>   int invert;
>   /* WINS will be nonzero when the switch is done
>  if all operands are constant.  */
>   int wins = 1;
>
> printf("bbb in fold\n");
>   /* Don't try to process an RTL_EXPR since its operands aren't trees.
>  Likewise for a SAVE_EXPR that's already been evaluated.  */
>   if (code == RTL_EXPR || (code == SAVE_EXPR && SAVE_EXPR_RTL (t) != 0))
> return t;
>
>   /* Return right away if a constant.  */
>   if (kind == 'c')
> return t;
>
> printf("bbb fold2\n");
> printf("bbb fold2b %d\n", (int)TREE_CODE(t));
> if (TREE_CODE (t) == INTEGER_CST)
> {
> printf("bbb fold2c is %ld\n",
>(long)TREE_INT_CST_LOW (t));
> }
>
>
> ...
>
>
>   /* If this is a commutative operation, and ARG0 is a constant, move it
>  to ARG1 to reduce the number of tests below.  */
>   if ((code == PLUS_EXPR || code == MULT_EXPR || code == MIN_EXPR
>|| code == MAX_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR
>|| code == BIT_AND_EXPR)
>   && (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == REAL_CST))
> {
> printf("bbb fold3\n");
> printf("bbb fold3b is %ld\n",
>(long)TREE_INT_CST_LOW (arg0));
>
>   tem = arg0; arg0 = arg1; arg1 = tem;
>
>   tem = TREE_OPERAND (t, 0); TREE_OPERAND (t, 0) = TREE_OPERAND (t, 1);
>   TREE_OPERAND (t, 1) = tem;
> }
>
> printf("bbb fold4\n");
>
>
>
> temp.txt: bbb fold2
> temp.txt: bbb fold2b 77
> temp.txt: bbb fold4
> temp.txt: bbb fold5
> temp.txt: bbb -2 -1
> temp.txt: bbbj 0
> temp.txt: bbbs1
> temp.txt: bbbs2
> temp.txt: bbbs9
> temp.txt: bbbq
> temp.txt: bbb in fold
> temp.txt: bbb fold2
> temp.txt: bbb fold2b 115
> temp.txt: bbb fold4
> temp.txt: bbb fold5
> temp.txt: bbb -2 -1
> temp.txt: bbbj 0
> temp.txt: bbb in fold
> temp.txt: bbb fold2
> temp.txt: bbb fold2b 115
> temp.txt: bbb fold4
> temp.txt: bbb fold5
> temp.txt: bbb 1 0
> temp.txt: bbbj 0
> temp.txt: bbbq
> temp.txt: bbb about to do build
> temp.txt: bbbo
> temp.txt: bbb done build
> temp.txt: bbb in fold
> temp.txt: bbb fold2
> temp.txt: bbb fold2b 61
> temp.txt: bbb fold3
> temp.txt: bbb fold3b is 4294967294
> temp.txt: bbb fold4
> temp.txt: bbb fold5
> temp.txt: bbb 4294967294 0
>
>


Re: gcc 3.2.3 x64 negative indexes

2024-02-09 Thread Paul Edwards via Gcc
On Wed, 7 Feb 2024 at 23:12, Jakub Jelinek  wrote:
On Wed, Feb 07, 2024 at 11:02:51PM +0800, Paul Edwards via Gcc wrote:

>> I am using a slightly modified gcc 3.2.3 for x86_64 and for this code:

> Don't, gcc 3.2.3 is not supported for more than 20 years already.

And the i370 target hasn't been supported for that long
either - but that's a target I want too.

And nor has any version ever run on MVS 3.8J - but
that's an execution platform I want too.

And the same goes for PDOS/386 as an execution platform.

>> int fff(char *x)
>> {
>> return (x[-1]);
>> }
>
>> It is generating:
>
>> .globl fff
>> fff:
>> .LFB2:
>> movl$4294967295, %eax
>> movsbl  (%rax,%rcx),%eax

> That said, I can't reproduce it and get
>movsbl  -1(%rdi),%eax
>ret
> from 3.2.3.

Thanks for that! So one of the "slight modifications"
was to switch to Win64 ABI, which is why rcx is being
selected instead of rdi. So that bit is expected.

So I need to know why I'm not getting -1.

Since your email I have been trying to explain that.
It is likely a problem with the C library I am using
(PDPCLIB) - strtol or something like that.

I am using 64-bit longs and I can see that that large
value (-1 as unsigned 32-bit) is being stored in the
64-bit field and being preserved.

So far I have tracked it down to happening in the
early stages. fold() is called and I can see that it
is initially good for something, and bad later.

I'm still working on it.

BFN. Paul.


fold-const.c

tree
fold (expr)
 tree expr;
{
  tree t = expr;
  tree t1 = NULL_TREE;
  tree tem;
  tree type = TREE_TYPE (expr);
  tree arg0 = NULL_TREE, arg1 = NULL_TREE;
  enum tree_code code = TREE_CODE (t);
  int kind = TREE_CODE_CLASS (code);
  int invert;
  /* WINS will be nonzero when the switch is done
 if all operands are constant.  */
  int wins = 1;

printf("bbb in fold\n");
  /* Don't try to process an RTL_EXPR since its operands aren't trees.
 Likewise for a SAVE_EXPR that's already been evaluated.  */
  if (code == RTL_EXPR || (code == SAVE_EXPR && SAVE_EXPR_RTL (t) != 0))
return t;

  /* Return right away if a constant.  */
  if (kind == 'c')
return t;

printf("bbb fold2\n");
printf("bbb fold2b %d\n", (int)TREE_CODE(t));
if (TREE_CODE (t) == INTEGER_CST)
{
printf("bbb fold2c is %ld\n",
   (long)TREE_INT_CST_LOW (t));
}


...


  /* If this is a commutative operation, and ARG0 is a constant, move it
 to ARG1 to reduce the number of tests below.  */
  if ((code == PLUS_EXPR || code == MULT_EXPR || code == MIN_EXPR
   || code == MAX_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR
   || code == BIT_AND_EXPR)
  && (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == REAL_CST))
{
printf("bbb fold3\n");
printf("bbb fold3b is %ld\n",
   (long)TREE_INT_CST_LOW (arg0));

  tem = arg0; arg0 = arg1; arg1 = tem;

  tem = TREE_OPERAND (t, 0); TREE_OPERAND (t, 0) = TREE_OPERAND (t, 1);
  TREE_OPERAND (t, 1) = tem;
}

printf("bbb fold4\n");



temp.txt: bbb fold2
temp.txt: bbb fold2b 77
temp.txt: bbb fold4
temp.txt: bbb fold5
temp.txt: bbb -2 -1
temp.txt: bbbj 0
temp.txt: bbbs1
temp.txt: bbbs2
temp.txt: bbbs9
temp.txt: bbbq
temp.txt: bbb in fold
temp.txt: bbb fold2
temp.txt: bbb fold2b 115
temp.txt: bbb fold4
temp.txt: bbb fold5
temp.txt: bbb -2 -1
temp.txt: bbbj 0
temp.txt: bbb in fold
temp.txt: bbb fold2
temp.txt: bbb fold2b 115
temp.txt: bbb fold4
temp.txt: bbb fold5
temp.txt: bbb 1 0
temp.txt: bbbj 0
temp.txt: bbbq
temp.txt: bbb about to do build
temp.txt: bbbo
temp.txt: bbb done build
temp.txt: bbb in fold
temp.txt: bbb fold2
temp.txt: bbb fold2b 61
temp.txt: bbb fold3
temp.txt: bbb fold3b is 4294967294
temp.txt: bbb fold4
temp.txt: bbb fold5
temp.txt: bbb 4294967294 0


gcc 3.2.3 x64 negative indexes

2024-02-07 Thread Paul Edwards via Gcc
Hi.

I am using a slightly modified gcc 3.2.3 for x86_64 and for this code:

int fff(char *x)
{
return (x[-1]);
}


It is generating:

.globl fff
fff:
.LFB2:
movl$4294967295, %eax
movsbl  (%rax,%rcx),%eax
ret


My understanding is that that move of -1 into eax
does NOT sign-extend, and thus results in a very
high index, which causes a crash.

I may have stuffed something up myself.

Anyone know which code governs this behavior?

Thanks. Paul.


gcc 3.2.3 splay tree issue

2024-02-05 Thread Paul Edwards via Gcc
I normally use gcc 3.2.3 to build executables that
work with msvcrt.dll, which has 32-bit int, long and ptr.

I tried changing long to 64 bits and the new compiler
encountered the following issue when attempting to
build itself. Documented and fixed below, unless
someone has a better fix. Note that I maintain this
version to support the i370 target, and I spent a lot
of effort making this source code C90-compliant
(instead of being riddled with Posix dependencies),
so don't bother asking "why don't you update to a
version of gcc that isn't even written in C, and has no
aim to be C90-compliant?".

BFN. Paul.



Index: gcc/c-lex.c
===
RCS file: \cvsroot/gcc/gcc/c-lex.c,v
retrieving revision 1.9
diff -c -r1.9 c-lex.c
*** gcc/c-lex.c 23 Nov 2022 10:03:57 - 1.9
--- gcc/c-lex.c 6 Feb 2024 00:22:30 -
***
*** 108,114 
struct c_fileinfo *toplevel;

/* Set up filename timing.  Must happen before cpp_read_main_file.  */
!   file_info_tree = splay_tree_new ((splay_tree_compare_fn)strcmp,
0,
(splay_tree_delete_value_fn)free);
toplevel = get_fileinfo ("");
--- 108,114 
struct c_fileinfo *toplevel;

/* Set up filename timing.  Must happen before cpp_read_main_file.  */
!   file_info_tree = splay_tree_new (splay_tree_compare_strings,
0,
(splay_tree_delete_value_fn)free);
toplevel = get_fileinfo ("");
Index: gcc/cppfiles.c
===
RCS file: \cvsroot/gcc/gcc/cppfiles.c,v
retrieving revision 1.24
diff -c -r1.24 cppfiles.c
*** gcc/cppfiles.c 8 Nov 2022 03:07:45 - 1.24
--- gcc/cppfiles.c 6 Feb 2024 00:24:03 -
***
*** 150,156 
   cpp_reader *pfile;
  {
pfile->all_include_files
! = splay_tree_new ((splay_tree_compare_fn) strcmp,
   (splay_tree_delete_key_fn) free,
   destroy_node);
  }
--- 150,156 
   cpp_reader *pfile;
  {
pfile->all_include_files
! = splay_tree_new (splay_tree_compare_strings,
   (splay_tree_delete_key_fn) free,
   destroy_node);
  }
Index: include/splay-tree.h
===
RCS file: \cvsroot/gcc/include/splay-tree.h,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 splay-tree.h
*** include/splay-tree.h 15 Feb 2006 10:23:44 - 1.1.1.1
--- include/splay-tree.h 6 Feb 2024 00:21:02 -
***
*** 40,47 
--- 40,61 
 these types, if necessary.  These types should be sufficiently wide
 that any pointer or scalar can be cast to these types, and then
 cast back, without loss of precision.  */
+
+ /* _cpp_init_includes() in cppfiles.c and init_c_lex in c-lex.c
+are setting the comparison function to strcmp, which takes pointers,
+and in a 32-bit pointer and 64-bit long environment, the second
+pointer to strcmp ends up as NULL. Rather than kludging here to make
+pointer size match some integer size (assuming that is even possible),
+I instead created another comparison function
+(splay_tree_compare_strings). This issue appears to still exist in
+gcc 3.4.6 */
+ #if 0 /* !defined(__64BIT__) && defined(__LONG64__) */
+ typedef unsigned int splay_tree_key;
+ typedef unsigned int splay_tree_value;
+ #else
  typedef unsigned long int splay_tree_key;
  typedef unsigned long int splay_tree_value;
+ #endif

  /* Forward declaration for a node in the tree.  */
  typedef struct splay_tree_node_s *splay_tree_node;
***
*** 146,151 
--- 160,167 
  splay_tree_key));
  extern int splay_tree_compare_pointers  PARAMS((splay_tree_key,
  splay_tree_key));
+ extern int splay_tree_compare_strings   PARAMS((splay_tree_key,
+ splay_tree_key));

  #ifdef __cplusplus
  }
Index: libiberty/splay-tree.c
===
RCS file: \cvsroot/gcc/libiberty/splay-tree.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 splay-tree.c
*** libiberty/splay-tree.c 15 Feb 2006 10:23:47 - 1.1.1.1
--- libiberty/splay-tree.c 6 Feb 2024 00:28:03 -
***
*** 33,38 
--- 33,39 
  #endif

  #include 
+ #include 

  #include "libiberty.h"
  #include "splay-tree.h"
***
*** 557,559 
--- 558,570 
else
  return 0;
  }
+
+ /* Splay-tree comparison function, treating the keys as strings.  */
+
+ int
+ splay_tree_compare_strings (k1, k2)
+  splay_tree_key k1;
+  splay_tree_key k2;
+ {
+   return (strcmp((char *)k1, (char *)k2));
+ }


x64 MSABI gcc 3.2.3

2023-08-25 Thread Paul Edwards via Gcc
I have a slightly modified gcc 3.2.3.

Source is available in gcc-stage* in custom.zip at http://pdos.org

Executables are available in customb.zip but everything that
is really needed is in pdos.zip

gccdos.txt has instructions to run windows.mak which
produces the gccx64.exe that I use, but has these warnings
on the way:

C:\devel\gcc\gcc>pdmake -f windows.mak

gccwin -DTARGET_64BIT_DEFAULT -DMSABI -fno-common -O2 -S -D__WIN32__
-D__NOBIVA__ -DI386 -DHAVE_CONFIG_H -DIN_GCC -DPUREISO -I
../../pdos/pdpclib -I ../../pdos/src -I . -I config/i386 -I config -I
../include -o combine.s combine.c
combine.c: In function `try_combine':
combine.c:1682: warning: left shift count >= width of type
combine.c:1684: warning: left shift count >= width of type
combine.c:1694: warning: left shift count >= width of type
combine.c:1694: warning: left shift count >= width of type
combine.c:1696: warning: left shift count >= width of type
pdas --oformat coff -o combine.o combine.s

If I do pdmake -f makefile.te6 in c:\devel\pdos\pdpclib I do get
a valid 64-bit EFI executable.

But a more complex program gives:

C:\devel\pdos\pdpclib>pdmake -f makefile.eb6
rm -f *.o
rm -f pdptest.efi
gccx64 -S -O2 -mno-red-zone -D__64BIT__ -D__EFI__ -D__EFIBIOS__ -U__WIN32__
-I. -fno-builtin -fno-common -ansi -o pdptest.s pdptest.c
pdptest.c: In function `main':
pdptest.c:189: insn does not satisfy its constraints:
compilation terminated.
[pdptest.o] Error 1: Operation not permitted

C:\devel\pdos\pdpclib>


When I switch from mingw64 to gccx64:

C:\devel\pdos\pdpclib>git diff .
diff --git a/pdpclib/makefile.eb6 b/pdpclib/makefile.eb6
index 19fe84e4..98b02da0 100644
--- a/pdpclib/makefile.eb6
+++ b/pdpclib/makefile.eb6
@@ -1,14 +1,15 @@
 # This builds EFI executables for x86_64
 # We put no-builtin to stop the optimizer from making memset call memset

-CC=x86_64-w64-mingw32-gcc
+#CC=x86_64-w64-mingw32-gcc
+CC=gccx64
 #AR=x86_64-w64-mingw32-ar
 AR=ar
 #LD=x86_64-w64-mingw32-ld
 LD=pdld --no-insert-timestamp
 #AS=x86_64-w64-mingw32-as
 AS=pdas --64 --oformat coff
-COPTS=-S -O2 -mno-red-zone -D__64BIT__ -D__EFI__ -D__EFIBIOS__ -U__WIN32__
-I. -fno-builtin -fno-common -ansi -Wno-builtin-declaration-mismatch
+COPTS=-S -O2 -mno-red-zone -D__64BIT__ -D__EFI__ -D__EFIBIOS__ -U__WIN32__
-I. -fno-builtin -fno-common -ansi

 TARGET=pdptest.efi
 OBJS=efistart.o stdio.o string.o stdlib.o start.o time.o errno.o \

C:\devel\pdos\pdpclib>


Anyone interested in helping out with this?

Note that this (3.2.3) is the only version of gcc that runs
on PDOS/386 and it took a lot of effort to even do that.

Note that 3.2.3 normally wouldn't do the MSABI, but my
slightly modified version does:

#ifdef MSABI
static int const x86_64_int_parameter_registers[6] = {2 /*RCX*/, 1 /*RDX*/,
8 /*R8*/, 9 /*R9*/,
/* the following 2 need to
be deleted */
FIRST_REX_INT_REG + 2 /*R10 */,
FIRST_REX_INT_REG + 3 /*R11 */};
#else
static int const x86_64_int_parameter_registers[6] = {5 /*RDI*/, 4 /*RSI*/,
1 /*RDX*/, 2 /*RCX*/,
FIRST_REX_INT_REG /*R8 */,
FIRST_REX_INT_REG + 1 /*R9 */};
#endif

My version (like standard 3.2.3) has 64-bit long, which is not
what Windows uses, but I am likely to stick with 64-bit long
regardless.

Thanks. Paul.


Re: s390 port

2023-01-29 Thread Paul Edwards via Gcc
Hi Joe.

They aren't 24 or 31 bit addresses.

All that code I showed was running in AM64. The very
first thing that z/PDOS does when it IPLs is activate
z/Arch mode and enable AM64. That's about 10
assembler instructions and then it's pure 64-bit for
eternity.

Only the lower 32 bits of the 64-bit registers are actually
populated though, because at least at the application
level I am using pure S/370 instructions (from a machine
definition in 1989). Even in the OS (z/PDOS) it's almost
all GCC-generated code, ie S/370 instructions also. All
32-bit registers. All 32-bit clean.

That is why the code ... WORKS.

As opposed to your irrelevant quoting from the POP,
which is ... irrelevant.

BFN. Paul.



On Sun, 29 Jan 2023 at 21:08, Joe Monk  wrote:

> "A 24-bit or 31-bit virtual address is expanded to 64 bits by appending
> 40 or 33 zeros, respectively, on the left before it is translated by means
> of the DAT process, and a 24-bit or 31-bit real address is similarly
> expanded to 64 bits before it is transformed by prefixing. A 24-bit or
> 31-bit absolute address is expanded to 64 bits before main storage is
> accessed." IBM z/Arch POO page 3-6.
>
> I dont see 32 bits anywhere in that process. Unless and until IBM changes
> the architecture definition to include 32 bits in address sizes, there is
> no need for a -m32 switch.
>
> Joe
>
> On Sat, Jan 28, 2023 at 12:51 PM Paul Edwards  wrote:
>
>> Hi Joe.
>>
>> Sorry for the delay (1 year and 4 months) in responding
>> to this. There's a long and sad story as to what caused
>> the delay, but we're here now.
>>
>> First of all, Hercules is a very important target. Even
>> if gcc -m31 only allowed writing above 2 GiB on Hercules,
>> that would still be an extremely important result, and
>> justify changing the option to -m32, which is what it
>> inherently is. Just because some arbitrary hardware
>> masks bits at 24, or 31, or 32, or fails to even do a
>> wrap at 64, doesn't alter the inherent fact that GCC
>> is using 32-bit registers. Not 64. Not 31. Not 24.
>>
>> They are general purpose registers being used, so both
>> address and data registers are 32 bits.
>>
>> If you have poorly-written assembler that only works if
>> addresses are being masked to 24 bits, then there would
>> be some justification in referring to that as a 24-bit
>> program.
>>
>> If you have poorly-written assembler that only works if
>> addresses are being masked to 31 bits, then there would
>> be some justification in referring to that as a 31-bit
>> program.
>>
>> But if you have a program that works in both of those
>> AMODEs, ie what IBM calls "AMODE ANY", it would be a
>> bit odd to call it an ANY-bit program, but that would
>> be the exact name you need if you want to continue
>> along that path. And an ANY-including-32-bit program
>> if it also capable of running as AM32 on any real,
>> emulated, or theoretical environment.
>>
>> If you have a poorly-written operating system (like z/OS),
>> that doesn't provide address masking (via DAT) to 32 bits
>> for 32-bit programs, so your only option is to run them
>> as AM31, where negative indexes work, or only run programs
>> that don't use negative indexes (and ensure that the
>> high 32 bits of 64 bit registers are 0), then there would
>> be justification in calling this an AM64-intolerant
>> program or AM64-tolerant program, respectively.
>>
>> z/OS has an additional problem that even in AM64, and
>> even with an AM64-tolerant 32-bit program, there is no
>> way to request memory in the 2 GiB - 4 GiB region other
>> than via crapshoot (use_2g_to_32g or whatever), and
>> even if you win the crapshoot, you can't have a nice
>> display of the 2 GiB boundary being crossed in a single
>> instruction. You could if you switched to supervisor
>> mode/key zero and didn't mind clobbering what was already
>> there, but you would probably still need to switch DAT off.
>> And then because you don't know what damage you have
>> done, you would need to freeze the system and re-IPL.
>>
>> Instead of attempting that, what I did was use a
>> properly-written OS, z/PDOS, that uses DAT (virtual
>> memory) to map the 4 GiB to 8 GiB region to 0 to 4 GiB,
>> so that even in AM64, you effectively get AM32. This is
>> the proper way to handle memory when you run 32-bit
>> programs on a 64-bit system. 32 and 64-bit programs
>> can run transparently with no mode switching required.
>> The 4 GiB to 8 GiB virtual storage region is effectively
>> dead

s390 port

2023-01-28 Thread Paul Edwards via Gcc
gle MVC instruction:

 MVC   0(4,2),0(3)

Note that MVC is an instruction that has been available
since the S/360 (in the 1960s). I am actually using the
i370 target of GCC 3.2.3 for this test, but the principle
is the same for s390 (as opposed to s390x) on the latest
GCC. Both are 32-bit.

Note that the i370 target was written by Jan Stein in 1989
when he worked at Amdahl, long before AM64 existed.

It only used S/370 instructions, so runs on anything from
a S/370 up (thanks to upward compatibility).

That MVC instruction works perfectly fine on z/Arch, as it
does on S/370.

Other instructions generated by GCC, such as BALR, have
changed behavior slightly as they went from AM24 on S/370
to AM31 on S/370 XA, and AM64 on z/Arch (and for that
matter, AM32 on S/380 under Hercules/380, or I assume
AM32 on a 360/67).

The behavior changed in an upwardly-compatible way, so long
as the program was written in a reasonable manner - ie to
not be deliberately dependent on that AM24 or AM31 specific
behavior. The code GCC generates has indeed been written
in that "reasonable manner".

Other instructions, such as BXLE, that, for certain use
cases, break down at the top end of the lower half of the
32-bit address space, just as BXLEG breaks down at the
top end of the lower half of the 64-bit address space, are
not generated by GCC at all, so are not relevant.

Bottom line - GCC generates 32-bit clean code, and as such,
the option should be -m32, not -m31, not -m24, not -mANY.
Keeping -m31 for compatibility reasons is obviously fine,
as would be adding -m24. But both of those things obscure
the fact that this is 32-bit clean code.

Here is the rest of the context of the generated code:

 MVC   88(4,13),=A(@@LC33)
 LA1,88(,13)
 L 15,=A(@@7)
 BALR  14,15
 L 3,=A(@@LC34)
 L 2,=F'2147483646'
 MVC   0(4,2),0(3)
 MVC   88(4,13),=A(@@LC35)
 LA1,88(,13)
 L 15,=A(@@7)
 BALR  14,15


@@LC32   EQU   *
 DCC'MEMTEST'
 DCX'0'
@@LC33   EQU   *
 DCC'writing 4 bytes to address X''7FFE'''
 DCX'15'
 DCX'0'
@@LC34   EQU   *
 DCX'1'
 DCX'2'
 DCX'3'
 DCX'4'
 DCX'0'
@@LC35   EQU   *
 DCC'done!'
 DCX'15'
 DCX'0'

As you can see from the photo of the real 3270 terminal,
that MVC instruction has successfully straddled the
2 GiB mark, even in a single instruction.

As you can see from the photo in the second link above,
the memory at location 0 is different (still contains
the IPL PSW!) from the memory at location x'8000'.

Do you have any further objections, other than a logical
fallacy such as argumentum ad populum or argumentum ad
baculum, to oppose gcc having -m32 as an option for the
S/390 target, or if the i370 code is added back in, for
that too, given that that is the correct technical nature
of the GCC-generated code?

Thanks. Paul.




"Simply switching off optimization made the negative
indexes go away, allowing more than 2 GiB to be
addressed in standard z/Arch, with "-m31".

Prove it on real hardware, not hercules. Hercules doesnt count.

Joe

On Wed, Sep 29, 2021 at 7:09 PM Paul Edwards via Gcc 
wrote:

>* We have fait accompli now:
*>>* https://gcc.gnu.org/pipermail/gcc/2021-September/237456.html
<https://gcc.gnu.org/pipermail/gcc/2021-September/237456.html>
*>>* Simply switching off optimization made the negative
*>* indexes go away, allowing more than 2 GiB to be
*>* addressed in standard z/Arch, with "-m31".
*>>* The above request is to add "-m32" as an alias for
*>* "-m31", but I would like to add as a request for it to
*>* work with optimization on.
*>>* BFN. Paul.
*>>>>>* -Original Message-
*>* From: Paul Edwards
*>* Sent: Friday, September 3, 2021 11:12 PM
*>* To: Jakub Jelinek
*>* Cc: Ulrich Weigand ; gcc@gcc.gnu.org  ; Ulrich Weigand
*>* Subject: Re: s390 port
*>>* >> > This is not in one single place, but spread throughout the
*>* >> > compiler, both common code and back-end.  I do not think it will
*>* >> > be possible to get the compiler to generate correct code if
*>* >> > you do not specify the address size correctly.
*>>* >> 1. Is there any way to put a constraint on index
*>* >> registers, to say that a particular machine can
*>* >> only index in the range of –512 to +512 or some
*>* >> other arbitrary set? If so, I can do 0 to 2 GiB.
*>>* >> 2. Is there a way of saying a machine doesn’t
*>* >> support indexing at all?
*>>*

Re: s390 port

2022-12-19 Thread Paul Edwards via Gcc
On Fri, 3 Sept 2021 at 20:12, Ulrich Weigand 
wrote:

> "Paul Edwards"  wrote on 03.09.2021 13:35:10:
> > >  Specifically, if you try to run AMODE64 with Pmode equals
> > >  SImode, the compiler will not be aware that the hardware
> > >  uses the high 32 bits of base and index registers, and
> > >  will not necessarily keep them zero.
> > The compiler naturally keeps them zero. The
> > instructions that are used to load registers
> > do not pollute the high-order 32 bits.
>
> While this is true for most instructions, the compiler will not
> restrict itself to using only those.  (As just one obvious
> example, the compiler may use "lay" with a negative displacement,
> which will set the high bits of a GPR in AMODE64.)
>
> (And, b.t.w. not the -m31 DImode, which is a pair of 32-bit
> GPRs, but rather the -m64 DImode, which is a single 64-bit GPR.)
>

Hi all.

Turns out I have been asking the wrong question for several years.

I was going to generate a peephole (an idea from the author of
UDOS, now KinnowOS) to detect when a negative index was
being used, and force an addition instead of an index, when I
realized that it wasn't just literals that could use a negative
value.

That is when I realized that negative numbers were perfectly
valid/normal for indexing, and that it is the OS/hardware that
needs to adapt to this reality when transitioning from 32-bit
hardware to 64-bit hardware.

As such, I have updated z/PDOS-32 to use DAT to map the
4 GiB to 8 GiB region to 0 to 4 GiB, so that negative indexing
works fine.

You can download this from http://pdos.org (down the bottom).

So would it be possible now to update gcc to make -m32 and
-m31 and -m24 all work, as they all generate the exact same
code, regrardless of whether you are running as AM24 on
S/370, AM31 on S/390 or AM32 on Hercules/380 or AM64
with DAT set appropriately on z/Arch.

Thanks. Paul.


constraining index register

2021-10-14 Thread Paul Edwards via Gcc
Hi.

In certain places, the i370 target of GCC 3.2.3 will use a
base + index + displacement operand.

How can I add a constraint to say that the index must be
between 0 and 0x7fff?

I want to stop 0x from being generated when I have:

char *p

p[-1];

Thanks. Paul.

--
This email has been checked for viruses by AVG.
https://www.avg.com


Re: S390 should change the meaning of -m31

2021-10-08 Thread Paul Edwards via Gcc

Hi Michael.

I have sort of (I used the i370 target of GCC 3.2.3 instead
of the s390 target) reproduced Jesus's work with z/PDOS
which can be obtained from here:

http://www.pdos.org/zpdos.zip

You can see that with standard Hercules 3.13:

18:02:24 Hercules Version 3.13
18:02:24 (c)Copyright 1999-2015 by Roger Bowler, Jan Jaeger, and others
18:02:24 Built on Sep 28 2017 at 01:35:43
18:02:24 Build information:
18:02:24   Windows (MSVC) build for AMD64

This memcpy:

memcpy((char *)0x7ffe, "\x01\x02\x03\x04", 4);

straddles the 2 GiB bar, and the memory is distinct from
low memory:

18:03:05 r 7ff0
18:03:05 R:7FF0:K:06=   0102 

18:03:05 R:8000:K:06=0304    

18:03:05 R:8010:K:06=    

18:03:05 R:8020:K:06=    



18:03:13 r 
18:03:13 R::K:06=000C 80002000   

18:03:13 R:0010:K:06=0071D4B0    
..M.
18:03:13 R:0020:K:06=000C0001 8050327A   
.&.:
18:03:13 R:0030:K:06=    




BFN. Paul.




-Original Message- 
From: Paul Edwards

Sent: Friday, October 1, 2021 8:01 AM
To: gcc@gcc.gnu.org
Cc: m...@suse.de ; jesusantonio30122...@gmail.com
Subject: S390 should change the meaning of -m31

Hi Michael.

Thanks for picking up this issue. I have been working
with Jesus on this.


m31 is semantically the same as the m32 option.


The m31 option allows for 32 bit addressing and that is confusing since 
the m31 option in S390 would mean 2 GiB space addressing


Indeed that's exactly what it means, and what it's supposed to mean.  On 
s390, in AMODE(31) the toplevel bit of an (32bit) address is either 
ignored or an indicator to switch back to 24bit addresses from the s360 
times.  Either way that leaves 31 bits to generate the virtual address. On 
s390 you indeed have a 2GB address space, not more.


He is using z/Arch and AM64.

But building with -m31.


Code used:

volatile uint64_t *gib_test = (volatile uint64_t *)0x7FFF;
memset(gib_test, 1, 4096);


Hercules dump:

r 0x7FFF-0x81FF
R:7FFF:K:06=01 .


I'm not sure what you believe to have demonstrated here.  The (virtual or 
physical) address 0x7FFF is either (in AMODE(24)) equivalent to 
0x00ff or to 0x (in AMODE(31)), either way, the top byte of 
the addressable range ...


I don't think that's what Hercules does for a real
memory display - it will instead say out of range.
But it doesn't matter, because we're using
64-bit Hercules with 4 GiB of memory and it doesn't
matter what the AMODE happens to be at any moment
in time, what is important is what is in that 4 GiB of
memory.

The -mXX options are supposed to reflect the address space's size, not the 
size of the general purpose registers.  An option that reflect AMODE(24) 
would also be called -m24, despite the registers still being 32bit in 
size.


The code generated by -m24 would be identical to
code generated by -m31 which would be identical to
code generated by -m32.

Why can't we just have a normal -m32 and accept -m31
and maybe -m24 too, and flag them as "obsolete"?

Thanks. Paul. 



S390 should change the meaning of -m31

2021-09-30 Thread Paul Edwards via Gcc

Hi Michael.

Thanks for picking up this issue. I have been working
with Jesus on this.


m31 is semantically the same as the m32 option.


The m31 option allows for 32 bit addressing and that is confusing since 
the m31 option in S390 would mean 2 GiB space addressing


Indeed that's exactly what it means, and what it's supposed to mean.  On 
s390, in AMODE(31) the toplevel bit of an (32bit) address is either 
ignored or an indicator to switch back to 24bit addresses from the s360 
times.  Either way that leaves 31 bits to generate the virtual address. 
On s390 you indeed have a 2GB address space, not more.


He is using z/Arch and AM64.

But building with -m31.


Code used:

volatile uint64_t *gib_test = (volatile uint64_t *)0x7FFF;
memset(gib_test, 1, 4096);


Hercules dump:

r 0x7FFF-0x81FF
R:7FFF:K:06=01 .


I'm not sure what you believe to have demonstrated here.  The (virtual or 
physical) address 0x7FFF is either (in AMODE(24)) equivalent to 
0x00ff or to 0x (in AMODE(31)), either way, the top byte of 
the addressable range ...


I don't think that's what Hercules does for a real
memory display - it will instead say out of range.
But it doesn't matter, because we're using
64-bit Hercules with 4 GiB of memory and it doesn't
matter what the AMODE happens to be at any moment
in time, what is important is what is in that 4 GiB of
memory.

The -mXX options are supposed to reflect the address space's size, not the 
size of the general purpose registers.  An option that reflect AMODE(24) 
would also be called -m24, despite the registers still being 32bit in 
size.


The code generated by -m24 would be identical to
code generated by -m31 which would be identical to
code generated by -m32.

Why can't we just have a normal -m32 and accept -m31
and maybe -m24 too, and flag them as "obsolete"?

Thanks. Paul.



Re: s390 port

2021-09-30 Thread Paul Edwards via Gcc

Simply switching off optimization made the negative
indexes go away, allowing more than 2 GiB to be
addressed in standard z/Arch, with "-m31".



Prove it on real hardware, not hercules. Hercules doesnt count.


Real mainframe hardware is not easily accessible.
Hercules is the most convenient way people have
of accessing a mainframe. Do you have any reason
to suggest that Hercules doesn't emulate real
hardware in this respect?

BFN. Paul.



Re: s390 port

2021-09-29 Thread Paul Edwards via Gcc

We have fait accompli now:

https://gcc.gnu.org/pipermail/gcc/2021-September/237456.html

Simply switching off optimization made the negative
indexes go away, allowing more than 2 GiB to be
addressed in standard z/Arch, with "-m31".

The above request is to add "-m32" as an alias for
"-m31", but I would like to add as a request for it to
work with optimization on.

BFN. Paul.




-Original Message- 
From: Paul Edwards

Sent: Friday, September 3, 2021 11:12 PM
To: Jakub Jelinek
Cc: Ulrich Weigand ; gcc@gcc.gnu.org ; Ulrich Weigand
Subject: Re: s390 port


> This is not in one single place, but spread throughout the
> compiler, both common code and back-end.  I do not think it will
> be possible to get the compiler to generate correct code if
> you do not specify the address size correctly.



1. Is there any way to put a constraint on index
registers, to say that a particular machine can
only index in the range of –512 to +512 or some
other arbitrary set? If so, I can do 0 to 2 GiB.



2. Is there a way of saying a machine doesn’t
support indexing at all?


There is a way to do that, but it isn't about changing a single or a 
couple

of spots, one needs to change a lot of *.md patterns, a lot of macros,
target hooks and as Ulrich said, most important is to use the right Pmode
which can differ from ptr_mode provided one e.g. defines ptr_extend 
pattern

etc.


Pardon? All that is required just to put a constraint
on an index register? If a range of a machine is
limited to -512 to +512, it shouldn't be necessary
to change md patterns etc etc.

Just look at the amount of work needed for the x32 or aarch64 ilp32 
support,


That's different. That's because Intel stuffed up.
IBM didn't. IBM came within an ace of a perfect
architecture. It's as if Intel had created an x32
instead of an 80386 in 1986.

IBM got it almost right in the 1960s.

and not just work spent one time on adding that support, but the 
continuous

amount of work on maintaining it.  The initial work is certainly a few
weeks if not months of work,


I've been trying to figure out how to lift the 31-bit
restriction on mainframes since around 1987.

If I have to pay someone for 2 month of work, at
this stage, I'm willing to do that, but:

1. I would like it done on GCC 3.2.3 plus maybe
GCC 3.4.6.

2. How much will it cost in US$?


then there needs to be somebody who regularly
tests gcc trunk and branches in such configuration so that it doesn't
bitrot, and not just that but somebody who actually fixes bugs in it.


I'll take responsibility for giving the GCC 3.X.X
releases the TLC they deserve. And I'll encourage
my daughter to maintain them after I've kicked
the bucket.


If something doesn't fit into 2GB of address space,
isn't it likely it won't fit into 4GB of address space
in a year or two?


Nope. 2 GiB is already a shitload of memory. It only
takes something like 23 MB for GCC 3.2.3 to recompile
itself, and I think 60 MB for GCC 3.4.6 to recompile
itself. That's the heaviest real workload I do. A 4 GiB
limitation instead of 2 GiB makes it just that much
less likely I'll ever hit a real limit.

Someone told me that the only non-scientific application
they knew of that came close to hitting the 2 GiB limit
was IBM's C compiler. I doubt that IBM's C compiler
technology is evolving at such a rate that it only takes
1-2 years for them to subsequently hit 4 GiB. Quite
apart from the fact that I don't really trust that even
IBM C is hitting a 2 GiB limit for what GCC can do in
23 MiB. But it could be true - I'm not familiar with
compiler internals.

BFN. Paul. 



Re: s390 port

2021-09-07 Thread Paul Edwards via Gcc
Hi Joe.

Thanks for your comments.

> It is unclear how this would even work. 

> For instance, the LA instruction clears the top bit.

In AM64, LA does not clear any bits.

> Also, instructions like LPR, LNR,

These operate on data registers, not addresses,
and will continue to work unchanged.

> BXLE, BXH all treat the value in the register as signed,
> so the top bit is not available.

These are already a problem if you are putting
addresses in them and it is approaching the 2 GiB
mark. The POP has a special mention of that.

Fun fact: The z/Arch POP has the same problem with
the G version of those instructions, when it hits the
63-bit mark, but the POP incorrectly states that the
problem occurs near the 64-bit mark. I reported the
problem with the POP but nothing seems to have
been done.

The solution is to drop these instructions from the
repertoire. C-generated assembler for both i370 and
s390 targets does not use these.

BFN. Paul.


Re: s390 port

2021-09-03 Thread Paul Edwards via Gcc

> This is not in one single place, but spread throughout the
> compiler, both common code and back-end.  I do not think it will
> be possible to get the compiler to generate correct code if
> you do not specify the address size correctly.



1. Is there any way to put a constraint on index
registers, to say that a particular machine can
only index in the range of –512 to +512 or some
other arbitrary set? If so, I can do 0 to 2 GiB.



2. Is there a way of saying a machine doesn’t
support indexing at all?


There is a way to do that, but it isn't about changing a single or a 
couple

of spots, one needs to change a lot of *.md patterns, a lot of macros,
target hooks and as Ulrich said, most important is to use the right Pmode
which can differ from ptr_mode provided one e.g. defines ptr_extend 
pattern

etc.


Pardon? All that is required just to put a constraint
on an index register? If a range of a machine is
limited to -512 to +512, it shouldn't be necessary
to change md patterns etc etc.

Just look at the amount of work needed for the x32 or aarch64 ilp32 
support,


That's different. That's because Intel stuffed up.
IBM didn't. IBM came within an ace of a perfect
architecture. It's as if Intel had created an x32
instead of an 80386 in 1986.

IBM got it almost right in the 1960s.

and not just work spent one time on adding that support, but the 
continuous

amount of work on maintaining it.  The initial work is certainly a few
weeks if not months of work,


I've been trying to figure out how to lift the 31-bit
restriction on mainframes since around 1987.

If I have to pay someone for 2 month of work, at
this stage, I'm willing to do that, but:

1. I would like it done on GCC 3.2.3 plus maybe
GCC 3.4.6.

2. How much will it cost in US$?


then there needs to be somebody who regularly
tests gcc trunk and branches in such configuration so that it doesn't
bitrot, and not just that but somebody who actually fixes bugs in it.


I'll take responsibility for giving the GCC 3.X.X
releases the TLC they deserve. And I'll encourage
my daughter to maintain them after I've kicked
the bucket.


If something doesn't fit into 2GB of address space,
isn't it likely it won't fit into 4GB of address space
in a year or two?


Nope. 2 GiB is already a shitload of memory. It only
takes something like 23 MB for GCC 3.2.3 to recompile
itself, and I think 60 MB for GCC 3.4.6 to recompile
itself. That's the heaviest real workload I do. A 4 GiB
limitation instead of 2 GiB makes it just that much
less likely I'll ever hit a real limit.

Someone told me that the only non-scientific application
they knew of that came close to hitting the 2 GiB limit
was IBM's C compiler. I doubt that IBM's C compiler
technology is evolving at such a rate that it only takes
1-2 years for them to subsequently hit 4 GiB. Quite
apart from the fact that I don't really trust that even
IBM C is hitting a 2 GiB limit for what GCC can do in
23 MiB. But it could be true - I'm not familiar with
compiler internals.

BFN. Paul.



Re: s390 port

2021-09-03 Thread Paul Edwards via Gcc
>> >  Also, the compiler
>> >  will assume the base + index (+ displacement) arithmetic
>> >  will operate in 32 bits -- I'm pretty sure this is
>> >  actually the root cause of your "negative index" problem.

>> Where is this logic please? Can I do a #if 0 or similar
>> to disable it?

> This is not in one single place, but spread throughout the
> compiler, both common code and back-end.  I do not think it will
> be possible to get the compiler to generate correct code if
> you do not specify the address size correctly.
1. Is there any way to put a constraint on index
registers, to say that a particular machine can
only index in the range of –512 to +512 or some
other arbitrary set? If so, I can do 0 to 2 GiB.
2. Is there a way of saying a machine doesn’t
support indexing at all?
>> > If you want to go for an "x32" like mode, I think this
>> > is wrong approach.  The right approach would be to
>> > start from "-m64", and simply modify the pointer size
>> > to be 32 bits.
>> > This would work by setting POINTER_SIZE to 32, while
>> > leaving everything else like for -m64.
>  
>> That will generate 64-bit z/Arch instructions.
>> I wish to generate ESA/390 instructions.

> Why? AMODE64 exists only in z/Arch, so of course there
> will be z/Arch instructions available ...

For the same reason people constructed Babbage’s
invention, I wish to demonstrate the minor changes
that would have been required to the S/360 so that
we would never have arrived at a 31-bit black hole,
and we could have in fact had the perfect 32-bit
machine. Almost identical to the 31-bit machine.
A S/360+, a S/370+ and a S/390+. 

>> > We've thought about implementing this mode for Linux,
>> > but decided not to do it, since it would only provide
>> > marginal performance improvements, and has the drawback
>> > of being another new ABI that would be incompatible to
>> > the whole existing software ecosystem.
>> Shouldn’t the end user be able to decide this
>> for themselves?

> It's open source, of course everybode can decide what they
> want to work on themselves.  But we decide what we spend
> our own time on based on we think is useful ...

Sure.

>> No-one at all is interested in 32-bit mainframes?

> Not any more, at least not in Linux.  Linux is pretty much
> 64-bit only at this point.

I think z/OS is pretty much still 31-bit only,
as far as apps are concerned, right? I’d like to
bump that up to 32-bit.

BFN. Paul.


Re: s390 port

2021-09-03 Thread Paul Edwards via Gcc
> - AMODE64 means the native address size is 64 bits.  This
>  implies that Pmode has to be DImode, since Pmode tells
>  the compiler what the native address size is.

>  Specifically, if you try to run AMODE64 with Pmode equals
>  SImode, the compiler will not be aware that the hardware
>  uses the high 32 bits of base and index registers, and
>  will not necessarily keep them zero.

The compiler naturally keeps them zero. The

instructions that are used to load registers

do not pollute the high-order 32 bits.



>  Also, the compiler
>  will assume the base + index (+ displacement) arithmetic
>  will operate in 32 bits -- I'm pretty sure this is
>  actually the root cause of your "negative index" problem.


Where is this logic please? Can I do a #if 0 or similar

to disable it?


> Note that even if Pmode == DImode, you can still use 32-bit
> *pointer* sizes.  This is exactly what e.g. the Intel x32
> mode does (as was mentioned by Andreas).


I’m happy to try the approach from BOTH directions

and see which one hits “-m32” first.


>> I’d like to approach the problem from the other
>> direction – what modifications are required to
>> be made to “-m31” so that it does “-m32” instead?
>> I’m happy to simply retire “-m31”, but I don’t care
>> if both exist.

> If you want to go for an "x32" like mode, I think this
> is wrong approach.  The right approach would be to
> start from "-m64", and simply modify the pointer size
> to be 32 bits.


> This would work by setting POINTER_SIZE to 32, while
> leaving everything else like for -m64.



That will generate 64-bit z/Arch instructions.

I wish to generate ESA/390 instructions.



> I'm sure there
> will be a few other places that need adaptation, but
> it should be pretty straightforward.

No, modifying GCC is beyond my ability. I

need 20 lines of code from someone who is

familiar with the system.



>  You can also
> check the Intel back-end where they're using the
> TARGET_X32 macro.


See above about beyond my ability.

> We've thought about implementing this mode for Linux,
> but decided not to do it, since it would only provide
> marginal performance improvements, and has the drawback
> of being another new ABI that would be incompatible to
> the whole existing software ecosystem.


Shouldn’t the end user be able to decide this

for themselves? No-one at all is interested in

32-bit mainframes?


> (The latter point may not be an issue for you if you're
> looking into a completely new OS anyway.)


Correct.

Thanks. Paul.


Re: s390 port

2021-09-02 Thread Paul Edwards via Gcc
Hi Ulrich. Thanks for your detailed reply.
>> > Therefore again my question, what is the actual goal
>> > you want to achieve?   I'm still not sure I understand
>> > that ...

>> I would like to know what is required to implement
>> “-m32” in the S/390 target. I realize that z/Arch
>> doesn’t have a specific AM32, but I don’t need a
>> specific AM32. What would actually happen if you
>> coded a “-m32” and then ran it in an AM64
>> environment?

> That depends on what that would actually do.  I'm still not
> quite sure what the actual requirements are.

> Is this about supporting a 4GB address space instead
> of a 2GB space?
Yes, correct.
> (I'm not aware of that being used anywhere currently.)
I’m about to use it. I just need to get past
the problem with negative indexes being used,
and I need your help.

> Is it about supporting a 32-bit pointer type in an
> otherwise AM64 environment?  (This is already used
> by the TPF target, but the 32-bit pointer will still
> refer to a 2GB address space.)

Yes, all pointers will be 32-bit – a normal 32-bit system.

> Is it something else?

Nope, you got it.

> In either case, what is the actual benefit of that mode?
> (I.e. what benefit would justify the effort to implement it?)

The “legacy” environment of z/Linux etc would be 32-bit
instead of 31-bit. IBM’s reputation will be restored. IBM
will have the best architecture on the planet. Better than
x64 because no mode switch is required shifting between
32-bit and 64-bit applications. All run as AM64 = AM-infinity.

>> >> Also, I just realized – if GCC is using LA for maths
>> >> for 32-bit registers, then values will be limited to
>> >> 2 GiB instead of 4 GiB for unsigned, but that is not
>> >> the case.
> 
>> > That's why GCC makes sure to only use the instruction
>> > when a 31-bit addition is wanted.  This can be the
>> > case either when GCC can prove that the involved
>> > operands are pointer values (which are by definition
>> > restricted to 31-bit values in -m31 mode)
>  
>> The compiler doesn’t create a restriction there.
>> It just generates a simple LA and it works
>> differently depending on whether it is AM24/31/64.

> It is the other way around.  The compiler knows
> exactly how the LA instruction behaves in hardware,
> and will use the instruction whenever that behavior
> matches the semantics of (a part of) the program.
> Since the behavior of the instruction differs based
> on the addressing mode, the compiler will have to
> know which mode the executable will be running in.

The i370 port produces code that works in AM24, AM31,
AM32 and AM64 (except for negative indexes). I’m surprised
the s390 port doesn’t too. As far as I can remember from
using IBM C, it supports execution in any AMODE too.

> Currently, the -m31/-m64 switch basically changes several
> things (at the same time)
> - the assumption on which AM the executable will run in 
> - the (used) size of a general-purpose register
> - the (default) size of a pointer type
> - ABI (function calling convention) details

> In theory, it would be possible to split this apart
> into distinct features, so that it would be possible
> to implement a mode where you can have code that uses
> 32-bit pointers but is running in AM64 (which would
> then support a 4 GB address space).

> Is this what you mean by an "-m32" mode?

Yes, correct.

> Basically, this would involve looking at all uses of
> the TARGET_64BIT macro in the back-end and determine
> which of them actually depend on which of the above
> features, and disentangle it accordingly.

> I guess that would be possible, but it requires a
> nontrivial effort.

I’d like to approach the problem from the other
direction – what modifications are required to
be made to “-m31” so that it does “-m32” instead?
I’m happy to simply retire “-m31”, but I don’t care
if both exist.

If “-m31” is retired, and made an alias for “-m32”,
my guess is that 20 lines of code need to be changed.

The most important thing is to stop generating
negative indexes.

ie if you have “char *p” and you go p[-1] I don’t
want 0x generated as an index. I instead
want a subtraction done.

I was under the impression that this was governed
by the Pmode – whether it was set to DImode or
SImode. But I tried forcing Pmode to DImode, even
for “–m31”, but it gave an internal error, which I
showed you already.

What am I missing?

Thanks. Paul.


Re: s390 port

2021-09-02 Thread Paul Edwards via Gcc
Hi Ulrich.

Thanks a lot for your reply.

Could you give me an example of an instruction
generated by –m31 that is not expected to work
on an AM64 system?

E.g. the 32-bit

LR R2,R3

will definitely work on AM64.

So what specifically won’t work? How many different
things won’t work?

Thanks. Paul.




From: Ulrich Weigand 
Sent: Friday, September 3, 2021 12:34 AM
To: Paul Edwards 
Cc: gcc@gcc.gnu.org ; Ulrich Weigand 
Subject: Re: s390 port

Hi Paul,

"Paul Edwards"  wrote on 02.09.2021 10:15:44:

> We got the IPL process in place on ESA/390, and then
> I decided that the next thing to do would be to switch
> to z/Arch so that we could get rid of the AMODE 31
> architectural limit on 32-bit programs.
> 
> It all worked fine, and we were able to use GCC 11 to
> target S/390 and use the -m31 to generate 32-bit code,
> run it under z/Arch as AM64, sort of making it the
> equivalent of AM32. Really it is the equivalent of
> AM-infinity, and there's the rub - GCC 11 is generating
> negative indexes, which cause memory above 4 GiB
> to be accessed (instead of wrapping at 2/4 GiB), which
> of course fails.

Can you elaborate what exactly your goals are?  The point
of the -m31 vs. -m64 option is exactly to match the
AMODE 31 vs. AMODE 64 hardware distinction, so trying to
run -m31 code in AMODE 64 is not supposed to work.

Bye,
Ulrich





Re: s390 port

2021-09-02 Thread Paul Edwards via Gcc
>> I just checked my copy of s390.md and I don’t see
>> LA being used for arithmetic.

> This would be the "*la_31" and "*la_31_and" patterns.
Sorry, I did a grep for “LA”, forgetting that
s390.md doesn’t use uppercase instructions.

> (Note that the addition is implicit in the use of
> the "address_operand" constraint.)

If it is an address we are talking about, then that LA
instruction is going to work perfectly fine in AM24,
AM31 and AM64, and in the AM64 case it is going
to be the equivalent of AM32, so maybe the s390
port could have a “-m32” option for use when
running 32-bit applications as AM64?

>> If your copy of s390.md is using LA for arithmetic
>> then would it be possible to have an option to
>> use a normal mathematics instruction instead of
>> LA?

> LA was just an example.  It doesn't usually make sense
> to reason on an "use instruction X" basis, that's not
> how compiler optimizations work.  You rather start with
> a set of semantic invariants and then make sure those
> are preserved through all transformations.

Ok, that’s above my head.

> Therefore again my question, what is the actual goal
> you want to achieve?   I'm still not sure I understand
> that ...

I would like to know what is required to implement
“-m32” in the S/390 target. I realize that z/Arch
doesn’t have a specific AM32, but I don’t need a
specific AM32. What would actually happen if you
coded a “-m32” and then ran it in an AM64
environment?

My experiments show “with one single problem
discovered so far, actually –m31 and –m32 are
identical and work fine under AM64”.

>> Also, I just realized – if GCC is using LA for maths
>> for 32-bit registers, then values will be limited to
>> 2 GiB instead of 4 GiB for unsigned, but that is not
>> the case.

> That's why GCC makes sure to only use the instruction
> when a 31-bit addition is wanted.  This can be the
> case either when GCC can prove that the involved
> operands are pointer values (which are by definition
> restricted to 31-bit values in -m31 mode)

The compiler doesn’t create a restriction there.
It just generates a simple LA and it works
differently depending on whether it is AM24/31/64.

> or when
> there is an explict 31-bit addition (using e.g. an
> & 0x7fff) in the source code.

Ok, thankyou, this is what I needed to know.
I believe I would like to have a –m32 that
drops this test. I don’t want GCC to assume
that such an AND instruction can be implemented
with the use of the “LA” instruction. I want
to see an explicit “N” instruction used. Can
I have this as part of “-m32”?

Thanks. Paul.


Re: s390 port

2021-09-02 Thread Paul Edwards via Gcc
Hi Ulrich.

I just checked my copy of s390.md and I don’t see
LA being used for arithmetic.

If your copy of s390.md is using LA for arithmetic
then would it be possible to have an option to
use a normal mathematics instruction instead of
LA?

Do you have any more examples besides LA being
used for maths instead of a proper maths instruction?

Also, I just realized – if GCC is using LA for maths
for 32-bit registers, then values will be limited to
2 GiB instead of 4 GiB for unsigned, but that is not
the case.

BFN. Paul.




From: Ulrich Weigand 
Sent: Friday, September 3, 2021 12:53 AM
To: Paul Edwards 
Cc: gcc@gcc.gnu.org ; Ulrich Weigand 
Subject: Re: s390 port

"Paul Edwards"  wrote on 02.09.2021 16:50:35:

> Could you give me an example of an instruction
> generated by –m31 that is not expected to work
> on an AM64 system?

Well, everything related to address computation, of course.

For example, GCC may use LA on -m31 to implement a
31-bit addition, while it may use LA on -m64 to
implement a 64-bit addition.

Bye,
Ulrich





Re: s390 port

2021-09-02 Thread Paul Edwards via Gcc

Hi Ulrich.

Below is the output as text.

Thanks. Paul.



make  all-recursive
make[1]: Entering directory '/home/robertapengelly/Desktop/UDOS'
Making all in kernel
make[2]: Entering directory '/home/robertapengelly/Desktop/UDOS/kernel'
depbase=`echo irq.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
s390-linux-gcc -DHAVE_CONFIG_H -I. -I.. -ffreestanding -fno-stack-protector 
-pipe -Wall -Wextra -pedantic -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings 
-Wstrict-prototypes -Wmissing-declarations -Wdouble-promotion -Wredundant-decls 
-Wnested-externs -Winline -Wconversion -fexec-charset=IBM-1047 -O2 -m31 -g  
-MT irq.o -MD -MP -MF $depbase.Tpo -c -o irq.o irq.c &&\

mv -f $depbase.Tpo $depbase.Po
during RTL pass: reload
In file included from irq.c:3:
./panic.h: In function ‘kpanic’:
./panic.h:21:1: internal compiler error: maximum number of generated reload 
insns per insn achieved (90)

  21 | }
 | ^
0xce67fc lra_constraints(bool)
   ../../gcc/gcc/lra-constraints.c:5091
0xcd2fa2 lra(_IO_FILE*)
   ../../gcc/gcc/lra.c:2336
0xc8a2f9 do_reload
   ../../gcc/gcc/ira.c:5932
0xc8a2f9 execute
   ../../gcc/gcc/ira.c:6118
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
make[2]: *** [Makefile:418: irq.o] Error 1
make[2]: Leaving directory '/home/robertapengelly/Desktop/UDOS/kernel'
make[1]: *** [Makefile:406: all-recursive] Error 1
make[1]: Leaving directory '/home/robertapengelly/Desktop/UDOS'
make: *** [Makefile:326: all] Error 2




-Original Message- 
From: Paul Edwards

Sent: Thursday, September 2, 2021 6:15 PM
To: Ulrich Weigand
Cc: gcc@gcc.gnu.org
Subject: s390 port

Hi Ulrich.

Sorry for the necro - things happen slowly Down Under. :-)

Anyway, I am helping someone with their public domain
project, UDOS - https://github.com/udos-project/udos

(just a hobby, won't be big and professional like Linux)

We got the IPL process in place on ESA/390, and then
I decided that the next thing to do would be to switch
to z/Arch so that we could get rid of the AMODE 31
architectural limit on 32-bit programs.

It all worked fine, and we were able to use GCC 11 to
target S/390 and use the -m31 to generate 32-bit code,
run it under z/Arch as AM64, sort of making it the
equivalent of AM32. Really it is the equivalent of
AM-infinity, and there's the rub - GCC 11 is generating
negative indexes, which cause memory above 4 GiB
to be accessed (instead of wrapping at 2/4 GiB), which
of course fails.

Do you have any idea how to stop the S/390 target
from generating negative indexes? I thought the
solution might be to change the Pmode to DImode
even for non-TARGET64, but as you can see here:

http://www.pdos.org/gccfail.png

we got an internal compile error - maximum number
of generated reload insns per insn achieved (90).

I then tried changing the other SImode reference
(CASE_VECTOR_MODE) to DImode too, but that gave
the same internal error.

Here is what the failure looks like (see the large R4):

01:28:27 PSW=00042001 8000 5870 INST=A73A0001 AHI   3,1
add_halfword_immediate
01:28:27 R0=01FD R1=00E2 R2=0009E579
R3=80B2
01:28:27 R4=F000 R5=0001E5C8 R6=7FFF
R7=2000
01:28:27 R8=201F R9= RA=80B0
RB=80B2
01:28:27 RC=0009E580 RD=8138 RE=7B4C
RF=0001E4E4
01:28:27 PSW=00042001 8000 5874 INST=42142FFF STC
1,4095(4,2)store_character
01:28:27 R:00010009E578: Translation exception 0005
01:28:27 R0=01FD R1=00E2 R2=0009E579
R3=80B3
01:28:27 R4=F000 R5=0001E5C8 R6=7FFF
R7=2000
01:28:27 R8=201F R9= RA=80B0
RB=80B2
01:28:27 RC=0009E580 RD=8138 RE=7B4C
RF=0001E4E4
01:28:27 HHCCP014I CPU: Addressing exception CODE=0005 ILC=4
01:28:27 PSW=00042001 8000 5878 INST=42142FFF STC
1,4095(4,2)store_character
01:28:27 R:00010009E578: Translation exception 0005
01:28:27 R0=01FD R1=00E2 R2=0009E579
R3=80B3
01:28:27 R4=F000 R5=0001E5C8 R6=7FFF
R7=2000
01:28:27 R8=201F R9= RA=80B0
RB=80B2
01:28:27 RC=0009E580 RD=8138 RE=7B4C
RF=0001E4E4
01:28:27 HHCCP043I Wait state PSW loaded: PSW=00060001 8000
0444
01:28:40 quit
01:28:40 HHCIN900I Begin Hercules shutdown

Any idea what we can do?

Thanks. Paul.




-Original Message- 
From: Ulrich Weigand

Sent: Saturday, June 6, 2009 1:20 AM
To: Pau

s390 port

2021-09-02 Thread Paul Edwards via Gcc

Hi Ulrich.

Sorry for the necro - things happen slowly Down Under. :-)

Anyway, I am helping someone with their public domain
project, UDOS - https://github.com/udos-project/udos

(just a hobby, won't be big and professional like Linux)

We got the IPL process in place on ESA/390, and then
I decided that the next thing to do would be to switch
to z/Arch so that we could get rid of the AMODE 31
architectural limit on 32-bit programs.

It all worked fine, and we were able to use GCC 11 to
target S/390 and use the -m31 to generate 32-bit code,
run it under z/Arch as AM64, sort of making it the
equivalent of AM32. Really it is the equivalent of
AM-infinity, and there's the rub - GCC 11 is generating
negative indexes, which cause memory above 4 GiB
to be accessed (instead of wrapping at 2/4 GiB), which
of course fails.

Do you have any idea how to stop the S/390 target
from generating negative indexes? I thought the
solution might be to change the Pmode to DImode
even for non-TARGET64, but as you can see here:

http://www.pdos.org/gccfail.png

we got an internal compile error - maximum number
of generated reload insns per insn achieved (90).

I then tried changing the other SImode reference
(CASE_VECTOR_MODE) to DImode too, but that gave
the same internal error.

Here is what the failure looks like (see the large R4):

01:28:27 PSW=00042001 8000 5870 INST=A73A0001 AHI   3,1 
add_halfword_immediate
01:28:27 R0=01FD R1=00E2 R2=0009E579 
R3=80B2
01:28:27 R4=F000 R5=0001E5C8 R6=7FFF 
R7=2000
01:28:27 R8=201F R9= RA=80B0 
RB=80B2
01:28:27 RC=0009E580 RD=8138 RE=7B4C 
RF=0001E4E4
01:28:27 PSW=00042001 8000 5874 INST=42142FFF STC 
1,4095(4,2)store_character

01:28:27 R:00010009E578: Translation exception 0005
01:28:27 R0=01FD R1=00E2 R2=0009E579 
R3=80B3
01:28:27 R4=F000 R5=0001E5C8 R6=7FFF 
R7=2000
01:28:27 R8=201F R9= RA=80B0 
RB=80B2
01:28:27 RC=0009E580 RD=8138 RE=7B4C 
RF=0001E4E4

01:28:27 HHCCP014I CPU: Addressing exception CODE=0005 ILC=4
01:28:27 PSW=00042001 8000 5878 INST=42142FFF STC 
1,4095(4,2)store_character

01:28:27 R:00010009E578: Translation exception 0005
01:28:27 R0=01FD R1=00E2 R2=0009E579 
R3=80B3
01:28:27 R4=F000 R5=0001E5C8 R6=7FFF 
R7=2000
01:28:27 R8=201F R9= RA=80B0 
RB=80B2
01:28:27 RC=0009E580 RD=8138 RE=7B4C 
RF=0001E4E4
01:28:27 HHCCP043I Wait state PSW loaded: PSW=00060001 8000 
0444

01:28:40 quit
01:28:40 HHCIN900I Begin Hercules shutdown

Any idea what we can do?

Thanks. Paul.




-Original Message- 
From: Ulrich Weigand

Sent: Saturday, June 6, 2009 1:20 AM
To: Paul Edwards
Cc: gcc@gcc.gnu.org
Subject: Re: i370 port

Paul Edwards wrote:


In addition, that code has been ported to GCC 3.4.6, which is now
working as a cross-compiler at least.  It's still some months away
from working natively though.  It takes a lot of effort to convert
the Posix-expecting GCC compiler into C90 compliance.  This has
been done though, in a way that has minimal code changes to the
GCC mainline.


You're referring to building GCC for a non-Posix *host*, right?
I assume those changes are not (primarily) in the back-end, but
throughout GCC common code?


Yes, I'm aware that there is an S/390 port, but it isn't EBCDIC, isn't
HLASM, isn't 370, isn't C90, isn't MVS.  It may well be possible to
change all those things, and I suspect that in a few years from now
I may be sending another message asking what I need to do to get
all my changes to the s390 target into the s390 target.  At that time,
I suspect there will be a lot of objection to "polluting" the s390 target
with all those "unnecessary" things.


Actually, I would really like to see the s390 target optionally support
the MVS ABI and HLASM assembler format, so I wouldn't have any objection
to patches that add these features ...

I understand current GCC supports various source and target character
sets a lot better out of the box, so it may be EBCDIC isn't even an
issue any more.   If there are other problems related to MVS host
support, I suppose those would need to be fixed in common code anyway,
no matter whether the s390 or i370 back-ends are used.

The only point in your list I'm sceptical about is 370 architecture
support -- I don't quite see why this is still useful today (the s390
port does require at a m

Re: extended segments on 80386

2021-03-15 Thread Paul Edwards via Gcc

Actually, what I want is a processor with ECS,
EDS and EES, as new registers, and for GCC
to target that, supporting near, far and huge
code pointers and data pointers.

BFN. Paul.




-Original Message- 
From: Paul Edwards 
Sent: Tuesday, March 16, 2021 12:55 AM 
To: GCC Development 
Subject: extended segments on 80386 


Would it be possible for GCC to generate code
that reserves ESI and EDI as "extended segment"
registers to hold a source and destination
"extended segment" of any operation.

This will be the upper 32-bits of a 64-bit address.

When run on a normal 80386, such code will work
fine, and ESI and EDI will always be 0, so that source
and destination are always in the first 4 GiB.

When run on segmentation-aware hardware, the
API to obtain memory, e.g. INT 21H AH=48H (or
something much better, preferably), cx will be
set to 1 to indicate that a "far pointer" is being
requested, and if such memory is available,
EDI will be set to the segment, ie EDI = 2 will
mean the 8 GiB location. The 32-bit offset will
be returned via a normal register, e.g. EAX.

The application will set EDI to 0 before calling
the INT 21H.

Only segment-aware applications will set cx to 1
in the INT 21H request.

The exact same executable will thus work fine, within
the 4 GiB address space, just doing unnecessary
stores and loads of ESI and EDI (always 0), but on
segment-aware hardware, that exact same application
will have access to 16 EiB of memory, although with
size_t restricted to 4 GiB (although you could break
the size_t restriction by using a huge pointer instead
of a far pointer).

If ESI and EDI are not the most appropriate registers,
something else could be chosen.

Will that work?

Thanks. Paul.


extended segments on 80386

2021-03-15 Thread Paul Edwards via Gcc

Would it be possible for GCC to generate code
that reserves ESI and EDI as "extended segment"
registers to hold a source and destination
"extended segment" of any operation.

This will be the upper 32-bits of a 64-bit address.

When run on a normal 80386, such code will work
fine, and ESI and EDI will always be 0, so that source
and destination are always in the first 4 GiB.

When run on segmentation-aware hardware, the
API to obtain memory, e.g. INT 21H AH=48H (or
something much better, preferably), cx will be
set to 1 to indicate that a "far pointer" is being
requested, and if such memory is available,
EDI will be set to the segment, ie EDI = 2 will
mean the 8 GiB location. The 32-bit offset will
be returned via a normal register, e.g. EAX.

The application will set EDI to 0 before calling
the INT 21H.

Only segment-aware applications will set cx to 1
in the INT 21H request.

The exact same executable will thus work fine, within
the 4 GiB address space, just doing unnecessary
stores and loads of ESI and EDI (always 0), but on
segment-aware hardware, that exact same application
will have access to 16 EiB of memory, although with
size_t restricted to 4 GiB (although you could break
the size_t restriction by using a huge pointer instead
of a far pointer).

If ESI and EDI are not the most appropriate registers,
something else could be chosen.

Will that work?

Thanks. Paul.



Re: negative indexes

2021-03-14 Thread Paul Edwards via Gcc

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 
 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
IC15,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 0x

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. 


Re: negative indexes

2021-03-14 Thread Paul Edwards via Gcc

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 
 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
IC15,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 0x

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. 




negative indexes

2021-03-13 Thread Paul Edwards via 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
IC15,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 0x

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.



i370 - negative indexes

2018-05-05 Thread Paul Edwards

Hi.

On the i370 port of GCC 3.2.3, I am
getting the following issue.


This code:

C:\scratch\bug>type bug.c
const char *p;

void foo(void)
{
   printf("p-1 is %x\n", p[-1]);
}


generates:

...
L 2,=F'-1'
...
IC4,0(2,3)

ie it is using a value of x’’ in R2 as an index.

This works fine in AM24 and AM31 environments, but
fails for AM64 where an address above 4 GiB is
computed.

Such code is very rare, so I would like to just have
a rule that the index must always be a positive
value, and for negative indexes like the above,
different code is generated to do an actual
subtract instead of trying to do everything via
the index.

Any idea how to achieve that? I can't see
anywhere in i370.md where I can put some
sort of constraint.

Note that I am producing 32-bit modules, but
setting them to AM64 so that they can use
the full 4 GiB on certain environments (like
MVS/380), instead of having a 2 GiB limit.

Thanks. Paul.


---
This email has been checked for viruses by AVG.
http://www.avg.com



Re: i370 port

2017-03-31 Thread Paul Edwards
fig\i370\test>type onecomp.bat
rem this should be run in a directory under config/i370
copy ..\..\..\testsuite\gcc.c-torture\execute\%1 cprog.c
call mvsgccr cprog.c output.txt
grep "EXECC CPROG RC= " output.txt
if errorlevel 1 goto bad
echo %1 passed >>results.txt
goto exit
:bad
echo %1 failed >>results.txt
:exit

C:\devel\gcc\gcc\config\i370\test>



C:\devel\gcc\gcc\config\i370\test>head dotests.bat
del results.txt

call onecomp 2112-1.c
call onecomp 2113-1.c
call onecomp 2121-1.c
call onecomp 2205-1.c
call onecomp 2217-1.c
call onecomp 2223-1.c
call onecomp 2224-1.c
call onecomp 2225-1.c

C:\devel\gcc\gcc\config\i370\test>





-Original Message- 
From: Joseph S. Myers

Sent: Saturday, June 6, 2009 1:02 AM
To: Paul Edwards
Cc: gcc@gcc.gnu.org
Subject: Re: i370 port

On Sat, 6 Jun 2009, Paul Edwards wrote:


The port is to a pure C90 environment (ie not posix, not unix).  It was a
major effort to achieve that, and it has only just been completed to the
point where the compiler recompiles itself with full optimization.  The
environment where it runs is not set up to run shell scripts or makes
or test suites.  It's set up to run JCL, and there's a stack of JCL card
decks to allow GCC to compile, which would be good to have included
in the i370 directory.


You can test a cross compiler if you have some way of copying a test
executable to the i370 system, running it and getting its output and exit
status back (actually you don't need to be able to get the exit status
since DejaGnu has wrappers to include it in the output if needed).  There
is no need for the target to be able to run shell scripts or makes.  You
would need to write your own DejaGnu board file that deals with copying
to/from the i370 system and running programs there.  The testsuite
routinely runs for much more limited embedded systems (using appropriate
board files).

--
Joseph S. Myers
jos...@codesourcery.com 



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


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>



i370 - strange padding being generated for literals

2016-01-16 Thread Paul Edwards

Hi.

On the i370 target of a slightly modified
GCC 3.2.3, I am getting this strange padding:

DC46X'00'

I asked Dave Pitts about it, and he
told me it is not related to the i370
machine definition and I should ask
the group for advice instead.

Note that one variable needs a padding
of 46 and another variable needs a
padding of 66, but for some reason only
the "46" appears at all, and that
appearance is completely redundant, and
the code does not use it at all (which
is why it causes no actual problem with
the variable that needs 66 padding).

Any insights? See code below.

Thanks. Paul.





void foo(void)
{
   char buf[50] = "CDE";
   char buf2[70] = "CDE";
   
   bar(buf, buf2);

   return;
}



COPY  PDPTOP
CSECT
* Program text area
@@LC0EQU   *
DCC'CDE'
DCX'0'
DC46X'00'
DS0F
* X-func foo prologue
FOO  PDPPRLG CINDEX=0,FRAME=224,BASER=12,ENTRY=YES
B @@FEN0
LTORG
@@FEN0   EQU   *
DROP  12
BALR  12,0
USING *,12
@@PG0EQU   *
LR11,1
L 10,=A(@@PGT0)
* Function foo code
L 2,=A(@@LC0)


* first buffer needs to copy the literal
* then 46 filler 


MVC   96(4,13),0(2)
LA6,100(,13)
LA7,46(0,0)
SLR   4,4
LR5,4
MVCL  6,4

* second bufer needs to copy the literal
* then 66 filler

MVC   152(4,13),0(2)
LA6,156(,13)
LA7,66(0,0)
SLR   4,4
LR5,4
MVCL  6,4

* finished setting buffers, time for
* irrelevant function call

LA2,96(,13)
ST2,88(13)
LA2,152(,13)
ST2,92(13)
LA1,88(,13)
L 15,=V(BAR)
BALR  14,15
* Function foo epilogue
PDPEPIL
* Function foo literal pool
DS0F
LTORG
* Function foo page table
DS0F
@@PGT0   EQU   *
DCA(@@PG0)
END






i370 - block move needs 16 MiB limit

2016-01-14 Thread Paul Edwards

Hi.

On the i370 port of GCC 3.2.3 (which
can be run in 31-bit mode on z/OS),
we have the below code to do a
builtin_memcpy().

But as per description in i370.md, it
is restricted to moving LESS than
16 MiB.

If we have 16 MiB or more, I am happy
to just call the memcpy() function.

I have tried various incantations to try
to stop this code from being used when
the block size is greater than or equal
to 16 MiB, but I have not been successful.

I was successful with putting in this
code change:

C:\devel\pdos\pdpclib>cvs diff -r 1.19 -r 1.20 string.h
Index: string.h
===
RCS file: /cvsroot/pdos/pdos/pdpclib/string.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -r1.19 -r1.20
89,90c89,98
< #define memcpy(a,b,c) (__builtin_memcpy((a),(b),(c)))
< #define memcmp(s1,s2,n) (__builtin_memcmp((s1),(s2),(n)))
---

#define memcpy(s1,s2,n) ( \
 (n >= 0x0100) ? \
 ((memcpy)((s1),(s2),(n))) : \
 (__builtin_memcpy((s1),(s2),(n))) \
)
#define memcmp(s1,s2,n) ( \
 (n >= 0x0100) ? \
 ((memcmp)((s1),(s2),(n))) : \
 (__builtin_memcmp((s1),(s2),(n))) \
)


C:\devel\pdos\pdpclib>


But I believe that is considered to be
technically incorrect, because the "n"
argument is evaluated more than once.

Am I correct in believing that the code
in builtins.c shouldn't be changed,
because that is correct for all platforms,
and that the required change needs
to go in i370.md or some other
i370-specific file?

If so, can anyone tell me how to solve
this problem?

Note that compare has an identical
issue - CLCL is like MVCL.

Thanks. Paul.





/* Expand a call to the memcpy builtin, with arguments in ARGLIST.
  Return 0 if we failed, the caller should emit a normal call, otherwise
  try to get the result in TARGET, if convenient (and in mode MODE if
  that's convenient).  */

static rtx
expand_builtin_memcpy (arglist, target, mode)
tree arglist;
rtx target;
enum machine_mode mode;
{





;
; movstrsi instruction pattern(s).
; block must be less than 16M (24 bits) in length

(define_expand "movstrsi"
 [(set (match_operand:BLK 0 "general_operand" "")
   (match_operand:BLK 1 "general_operand" ""))
  (use (match_operand:SI  2 "general_operand" ""))
  (match_operand 3 "" "")]
  ""
  "
{
 rtx op0, op1;

 op0 = XEXP (operands[0], 0);
 if (GET_CODE (op0) == REG
 || (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG
 && GET_CODE (XEXP (op0, 1)) == CONST_INT
 && (unsigned) INTVAL (XEXP (op0, 1)) < 4096))
   op0 = operands[0];
 else
   op0 = replace_equiv_address (operands[0], copy_to_mode_reg (SImode, 
op0));


 op1 = XEXP (operands[1], 0);
 if (GET_CODE (op1) == REG
 || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG
 && GET_CODE (XEXP (op1, 1)) == CONST_INT
 && (unsigned) INTVAL (XEXP (op1, 1)) < 4096))
   op1 = operands[1];
 else
   op1 = replace_equiv_address (operands[1], copy_to_mode_reg (SImode, 
op1));


 if (GET_CODE (operands[2]) == CONST_INT
 && (unsigned) INTVAL (operands[2]) <= 256)
   emit_insn (gen_rtx_PARALLEL (VOIDmode,
   gen_rtvec (2,
  gen_rtx_SET (VOIDmode, op0, op1),
  gen_rtx_USE (VOIDmode, operands[2];

 else
   {
   /* implementation provided by  Richard Henderson  */
   rtx reg1 = gen_reg_rtx (DImode);
   rtx reg2 = gen_reg_rtx (DImode);
   rtx mem1 = operands[0];
   rtx mem2 = operands[1];
   rtx len = operands[2];
   if (!CONSTANT_P (len))
 len = force_reg (SImode, len);

   /* Load up the address+length pairs.  */
   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
   emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0),
   force_operand (XEXP (mem1, 0), NULL_RTX));
   emit_move_insn (gen_rtx_SUBREG (SImode, reg1, GET_MODE_SIZE 
(SImode)), len);


   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg2));
   emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 0),
   force_operand (XEXP (mem2, 0), NULL_RTX));
   emit_move_insn (gen_rtx_SUBREG (SImode, reg2, GET_MODE_SIZE 
(SImode)), len);


   /* Copy! */
   emit_insn (gen_movstrsi_1 (reg1, reg2));
   }
 DONE;
}")

; Move a block that is less than or equal to 256 bytes in length.

(define_insn ""
 [(set (match_operand:BLK 0 "s_operand" "=S")
   (match_operand:BLK 1 "s_operand" "S"))
  (use (match_operand 2 "immediate_operand" "i"))]
 "((unsigned) INTVAL (operands[2]) <= 256)"
 "*
{
 check_label_emit ();
 mvs_check_page (0, 6, 0);
 return \"MVC%O0(%c2,%R0),%1\";
}"
  [(set_attr "length" "6")]
)

; Move a block that is larger than 256 bytes in length.
;  [(set (mem:BLK (subreg:SI (match_operand:DI 0 "register_operand" "+d") 
0))
;(mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "+d") 
0)))


(define_insn "movstrsi_1"
 [(set (mem:BLK (match_operand:DI 0 "register_operand" "+d") )
   (mem:BLK (match_operand:DI 1 "register_operand" "+d") ))
  (us

Re: i370 port

2014-02-12 Thread Paul Edwards

Let me ask a different question.

On GCC 3.2.3, does this sequence look correct:

./configure --target=i370-mvspdp --prefix=~/devel/mvscross --with-sysroot=~/devel/mvshead 
--enable-languages=c

make
make install

./configure --build=x86_64-unknown-linux-gnu --host=i370-mvspdp --target=i370-mvspdp 
--prefix=~/devel/mvshost --enable-languages=c --disable-nls

make


The first bit is working well - it is creating a cross-compiler.
But the second bit is not working well, on gcc 3.2.3 at
least. The sequence worked fine on gcc 3.4.6.

Thanks. Paul.



Re: i370 port

2014-02-11 Thread Paul Edwards

Hello all.

I have previously succeeded in getting configure to
work for gcc 3.4.6. Unfortunately gcc 3.4.6 is too
buggy to use and needs to wait for Dave Pitts or
someone to fix.

gcc 3.2.3 has no known bugs for the i370 target,
but it has not been done using "configure".

I am now trying to get gcc 3.2.3 to build via configure
using the same technique I used for gcc 3.4.6.

Some differences I found so far are as follows:

I needed to define the size of short etc which I
didn't need to do with 3.4.6:

export ac_cv_func_strncmp_works=yes
export ac_cv_c_bigendian=yes
export ac_cv_c_compile_endian=big-endian
export ac_cv_sizeof_short=2
export ac_cv_sizeof_int=4
export ac_cv_sizeof_long=4
export ac_cv_c_float_format='IBM 370 hex'

And "make", after this configure:

./configure --build=x86_64-unknown-linux-gnu --host=i370-mvspdp --target=i370-mvspdp 
--prefix=/devel/mvshost --enable-languages=c --disable-nls


is failing here:

make[2]: Leaving directory 
`/home/users/k/ke/kerravon86/devel/gcc/x86_64-unknown

-linux-gnu/libiberty'
rm -f *~ Makefile config.status xhost-mkfrag TAGS multilib.out
rm -f config.log
rmdir testsuite 2>/dev/null
make[1]: [distclean] Error 1 (ignored)
make[1]: Leaving directory 
`/home/users/k/ke/kerravon86/devel/gcc/x86_64-unknown

-linux-gnu/libiberty'
loading cache ../config.cache
configure: error: can not find install-sh or install.sh in ./.. ././..
make: *** [configure-build-libiberty] Error 1

The file in question seems to exist:

~/devel/gcc>find . -name install-sh
./boehm-gc/install-sh
./install-sh
./fastjar/install-sh
~/devel/gcc>find . -name install.sh
~/devel/gcc>

and is executable.

Any suggestions?

Thanks. Paul.



Re: GCC 2.8.1 for i370

2012-04-25 Thread Paul Edwards

It seems to me that in addition to doing a strcmp to cc1, I would
also have needed to do a strcmp to cccp. Can someone confirm
that GCC 2.8.1 and GCC 3.4.6 differ in that respect - ie there
was an extra executable (cccp) in GCC 2.8.1 when doing that
task of converting from C to assember (ie compile only, no
assembly)?



That sounds right.  cccp was integrated into cc1 around 3.0.


Thanks.


If MVS has anything like a batch file or shell script, I think it would
be easier to have the gcc driver print the commands that it wants to
execute to a file.  Then have a batch job run gcc and then run the
commands the it prints out.


It uses JCL (example below that you may find amusing), and there 
is a 100-character limit on the parameter. So the way I get around 
that problem is to link gcc, cccp, and cc1 into a single executable,
and let gcc call cccp and cc1 by executing a function that takes 
argc and argv as parameters, like this:


ret_code = toplev_main(cnt, commands[i].argv);

BFN.  Paul.





//GCCGEN   JOB CLASS=C,REGION=0K
//*
//* This example is for people who don't have a PROC installed
//* in their installation. It compiles an example C program.
//*
//CCOMPPROC GCCPREF='GCC',PDPPREF='PDPCLIB',MEMBER='',
// COS1='-Os -S -ansi -pedantic-errors',
// COS2='-o dd:out -'
//*
//COMP EXEC PGM=GCC,
// PARM='&COS1 &COS2'
//STEPLIB  DD DSN=&GCCPREF..LINKLIB,DISP=SHR
//INCLUDE  DD DSN=&PDPPREF..INCLUDE,DISP=SHR
//SYSINCL  DD DSN=&PDPPREF..INCLUDE,DISP=SHR
//OUT  DD DSN=&&TEMP,DISP=(,PASS),UNIT=SYSALLDA,
//DCB=(LRECL=80,BLKSIZE=6160,RECFM=FB),
//SPACE=(6160,(500,500))
//SYSINDD DSN=&PDPPREF..SOURCE(&MEMBER),DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSTERM  DD SYSOUT=*
//*
//ASM  EXEC PGM=ASMA90,
//PARM='DECK,NOLIST',
//COND=(4,LT,COMP)
//SYSLIB   DD DSN=SYS1.MACLIB,DISP=SHR,DCB=BLKSIZE=32720
// DD DSN=&PDPPREF..MACLIB,DISP=SHR
//SYSUT1   DD UNIT=SYSALLDA,SPACE=(CYL,(20,10))
//SYSUT2   DD UNIT=SYSALLDA,SPACE=(CYL,(10,10))
//SYSUT3   DD UNIT=SYSALLDA,SPACE=(CYL,(10,10))
//SYSPRINT DD SYSOUT=*
//SYSLIN   DD DUMMY
//SYSGODD DUMMY
//SYSPUNCH DD DSN=&&OBJSET,UNIT=SYSALLDA,SPACE=(80,(4000,4000)),
//DISP=(,PASS)
//SYSINDD DSN=&&TEMP,DISP=(OLD,DELETE)
//*
//LKED EXEC PGM=IEWL,PARM='MAP',
//COND=((4,LT,COMP),(4,LT,ASM))
//SYSLIN   DD DSN=&&OBJSET,DISP=(OLD,DELETE)
// DD DDNAME=SYSIN
//SYSINDD DUMMY
//SYSLIB   DD DSN=&PDPPREF..NCALIB,DISP=SHR
//SYSLMOD  DD DSN=&&TEMPL(&MEMBER),DISP=(OLD,PASS)
//SYSUT1   DD UNIT=SYSALLDA,SPACE=(CYL,(2,1))
//SYSPRINT DD SYSOUT=*
// PEND
//*
//S1   EXEC PGM=IEFBR14
//DD1  DD DSN=&&TEMPL,DISP=(NEW,PASS),UNIT=SYSALLDA,
// SPACE=(CYL,(1,1,44)),DCB=(RECFM=U,LRECL=0,BLKSIZE=6144)
//*
//S2   EXEC CCOMP,MEMBER='PDPTEST'
//COMP.SYSIN DD *
#include 

int main(void)
{
   printf("Greetings from Jujitsu ...\n");
   printf("the makers of MVS/380 !!!\n");
   return (0);
}
//LKED.SYSLMOD DD DSN=&&TEMPL(PDPTEST),DISP=(OLD,PASS)
//*
//S3   EXEC PGM=PDPTEST
//STEPLIB  DD DSN=&&TEMPL,DISP=(OLD,PASS)
//SYSINDD DUMMY
//SYSPRINT DD SYSOUT=*
//SYSTERM  DD SYSOUT=*
//*
//



GCC 2.8.1 for i370

2012-04-24 Thread Paul Edwards

In GCC 3.4.6, in order to create a single executable called "gcc" that
takes C code and produces assembler, I needed to put this code into gcc.c:

#ifdef SINGLE_EXECUTABLE
{
int cnt = 0;

while (commands[i].argv[cnt] != NULL)
{
cnt++;
}
if (strcmp(string, "cc1") == 0)
{
ret_code = toplev_main(cnt, commands[i].argv);
if (ret_code != 0) break;
}
 }
#else

I've been looking at the only surviving document (see below)
I have from my previous (1998) failed effort to get GCC 2.8.1
to run on MVS (EBCDIC).

It seems to me that in addition to doing a strcmp to cc1, I would
also have needed to do a strcmp to cccp. Can someone confirm
that GCC 2.8.1 and GCC 3.4.6 differ in that respect - ie there
was an extra executable (cccp) in GCC 2.8.1 when doing that
task of converting from C to assember (ie compile only, no
assembly)?

It's unfortunate I don't have a copy of the patches I submitted,
as assuming there was an extra step of going through a ".i"
file or whatever, I'd like to know how I solved that on MVS.
Not sure if GCC has an option to name that temporary file
so that I can change it to dd:work or whatever. Ideally I
could eliminate that temporary file.

Thanks.  Paul.





rem compile under Watcom for i370
rem goto bypass
wcl386 -I. -Iconfig bi-opcode.c bi-parser.c bi-lexer.c bi-reverse.c
bi-opcode bi-opcode.h
bi-opcode bc-opcode.h
wcl386 -I. -Iconfig bi-arity.c bi-parser.c bi-lexer.c bi-reverse.c
bi-arity bi-arity.h
bi-arity bc-arity.h
wcl386 -I. -Iconfig genflags.c rtl.c obstack.c alloca.c
genflags config/i370/i370.md >insn-flags.h
wcl386 -I. -Iconfig gencodes.c rtl.c obstack.c alloca.c
gencodes config/i370/i370.md >insn-codes.h
wcl386 -I. -Iconfig genconfig.c rtl.c obstack.c alloca.c
genconfig config/i370/i370.md >insn-config.h
wcl386 -I. -Iconfig genattr.c rtl.c obstack.c alloca.c
genattr config/i370/i370.md >insn-attr.h
wcl386 -I. -Iconfig genattrtab.c rtl.c obstack.c rtlanal.c alloca.c
genattrtab config/i370/i370.md >insn-attrtab.c
wcl386 -I. -Iconfig genpeep.c rtl.c obstack.c alloca.c
genpeep config/i370/i370.md >insn-peep.c
wcl386 -I. -Iconfig genemit.c rtl.c obstack.c alloca.c
genemit config/i370/i370.md >insn-emit.c
wcl386 -I. -Iconfig genoutput.c rtl.c obstack.c alloca.c
genoutput config/i370/i370.md >insn-output.c
wcl386 -I. -Iconfig genextract.c rtl.c obstack.c alloca.c
genextract config/i370/i370.md >insn-extract.c
wcl386 -I. -Iconfig genopinit.c rtl.c obstack.c alloca.c
genopinit config/i370/i370.md >insn-opinit.c
wcl386 -I. -Iconfig genrecog.c rtl.c obstack.c alloca.c
genrecog config/i370/i370.md >insn-recog.c

del *.obj
rem make gcc
wcl386 -d2 -c -D__GO32__ -DIN_GCC -Dmktemp=atoi -I. -Iconfig gcc.c obstack.c 
version.c prefix.c choose-t.c alloca.c

wcl386 -d2 -c -D__GO32__ -DIN_GCC -D__MSDOS__ -I. -Iconfig pexecute.c
rem wcl386 -Fe=xgcc.exe gcc.obj obstack.obj version.obj prefix.obj 
pexecute.obj choose-t.obj alloca.obj


:bypass
rem make cpp
wcl386 -c -I. -Iconfig -D__MSDOS__ -Dmy_strerror=z2 -Dpedantic=z3 -Dfancy_abort=ze 
-Dpedwarn=zf -Dxmalloc=zg -Dmain=cccp cccp.c

rem goto end
wcl386 -d2 -c -I. -Iconfig -Dyylex=z1 -Dyylval=za -Dyychar=zb -Dyynerrs=zc -Dyyparse=zd 
-Dpedantic=z3 -Dpedwarn=zf cexp.c

wcl386 -d2 -c -I. -Iconfig prefix.c alloca.c version.c
rem wcl386 -Fe=xcpp.exe cccp.obj version.obj cexp.obj prefix.obj alloca.obj

rem make cc1
wcl386 -d2 -c -D_WIN32 -I. -Iconfig -Dwarning=z6 -Dfancy_abort=z8 -Dxrealloc=z9 
-Dxmalloc=z4 -Derror=z5 -Dmain=toplev toplev.c

wcl386 -d2 -c -I. -Iconfig version.c tree.c print-tree.c
wcl386 -d2 -c -I. -Iconfig c-common.c c-iterate.c bc-emit.c bc-optab.c
wcl386 -d2 -c -I. -Derror=z5 -Dwarning=z6 -Iconfig c-parse.c c-lang.c 
c-lex.c c-pragma.c

wcl386 -d2 -c -I. -Iconfig c-decl.c c-typeck.c c-convert.c c-aux-info.c
wcl386 -d2 -c -I. -Iconfig stor-layout.c fold-const.c function.c stmt.c
wcl386 -d2 -c -I. -Iconfig expr.c expmed.c explow.c optabs.c varasm.c
rem Watcom 10.0 stuffs up the stack in emit_call_1 unless -d2 is used
wcl386 -d2 -c -I. -Iconfig calls.c
wcl386 -d2 -c -I. -Iconfig rtl.c print-rtl.c rtlanal.c emit-rtl.c real.c
wcl386 -d2 -c -I. -Iconfig dbxout.c sdbout.c dwarfout.c xcoffout.c
wcl386 -d2 -c -I. -Iconfig integrate.c jump.c cse.c loop.c
wcl386 -d2 -c -I. -Iconfig unroll.c flow.c stupid.c combine.c
wcl386 -d2 -c -I. -Iconfig regclass.c local-alloc.c global.c
wcl386 -d2 -c -I. -Iconfig reload.c reload1.c caller-save.c
:bypass
wcl386 -d2 -c -I. -Iconfig insn-peep.c reorg.c sched.c final.c
rem goto end
wcl386 -d2 -c -I. -Iconfig recog.c reg-stack.c alloca.c
wcl386 -d2 -c -I. -Iconfig obstack.c insn-opinit.c insn-recog.c
wcl386 -d2 -c -I. -Iconfig insn-extract.c profile.c except.c bitmap.c
wcl386 -d2 -c -I. -Iconfig insn-output.c insn-emit.c
wcl386 -d2 -c -I. -Iconfig insn-attrtab.c convert.c
wcl386 -d2 -c -I. -Iconfig dwarf2out.c
wcl386 -d2 -c -I. -Iconfig getpwd.c

:bypass
wcl386 -d2 -c -I. -Iconfig config\i370\i370.c

:end
wcl386 -d2 -Fe=xg

Re: old archives from 1998

2012-04-24 Thread Paul Edwards

The revision history of the FSF version of GCC between the EGCS split
and the merge was retained on premerge-fsf-branch.  That lets me see
that this change was committed by Richard Kenner on 1998-10-04.


Thanks Ian. I contacted Richard but unfortunately he had no
evidence of communicating with me back then.

I'm considering porting the GCC 3.4.6 i370 to GCC 2.8.1 to
give the new build process a more thorough workout, and
also produce an executable for DOS/VS and z/VSE that
doesn't exceed the system limitations so that it can be made
relocatable. And also see what the memory requirements
for a compile are, to see if it can fit into the approx 11 MB
region that MVS 3.8j and DOS/VS allow.

With 2.8.1 done, I would then forward port the build process
to GCC 3.2.3 which is the most stable version. Then I should
have all the i370 changes necessary, so it can come back to
3.4.6. Then I can make another attempt to get it into GCC 4.x.
Last time I tried the cross-compiler went into a loop. So like
before, it may require Dave Pitts to get the compiler proper
working first before I add in my changes.

BFN.  Paul.



old archives from 1998

2012-04-22 Thread Paul Edwards

Hello.

During the GCC 2.7.2/2.8.1 timeframe I sent emails to this list (or
some similar list) with patches. I have found evidence of the
patches being applied:

http://hg.sourceforge.jp/view/cbc/GCC/file/ec4cbc2ac877/gcc/FSFChangeLog

527 Sun Oct  4 08:37:36 1998  Paul Edwards  
528 
529 * configure.in (AC_CHECK_HEADERS): Add sys/types.h and sys/stat.h.

530 * gcc.c (sys/types.h, sys/stat.h): Only include if exist.
531 * cccp.c, toplev.c: Likewise.

But those entries do not appear in the Changelog of GCC 3.4.6,
even though it goes back to 1991.

I suspect it might have been due to ECGS.

So my question is - is there a non-ECGS archive of some sort
that would allow me to find out who modified gcc.c with that
change documented above (I didn't have write access to the
repository) and is there a list that my circa 1998 messages
would be on so that I can find out who I was communicating
with at the time? My emails from the time were lost due to a
stolen computer.

Thanks.  Paul.



Re: i370 port

2012-04-06 Thread Paul Edwards

Hi Ulrich.

A further question.

I put some debugging on here:

 op0 = XEXP (operands[0], 0);
 if (GET_CODE (op0) == REG
 || (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG
   && GET_CODE (XEXP (op0, 1)) == CONST_INT
   && (unsigned) INTVAL (XEXP (op0, 1)) < 4096))
 {
   op0 = operands[0];
   fprintf(stderr, \"used as-is\n\");
 }
 else
 {
   op0 = replace_equiv_address (operands[0], copy_to_mode_reg (SImode, 
op0));

   fprintf(stderr, \"replaced\n\");
 }

And I found out that op0 is already being "replaced". Shouldn't this
replacement eliminate the index register and just have a base
register, so that I don't need the hack further down?

Thanks.  Paul.



Re: i370 port

2012-04-06 Thread Paul Edwards

Ah, yes.  The problem is that reload assumes any valid address
can be loaded into a register with a single instruction, and
it will thus simply generate such instructions unconditionally
-- and if the target then doesn't actually provide such a pattern,
it will fail with "unrecognizable insn".


Hi Ulrich. Thanks for your reply.

This approach seems to be quite complicated. What do you think
about the option of NOT adding this (which triggers off errors I
hadn't seen before):

#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
  ((C) == 'S')

and instead making a change similar to what I have already put in
under "hack" below? Is that legitimate?

;
; movstrsi instruction pattern(s).
; block must be less than 16M (24 bits) in length

(define_expand "movstrsi"
 [(set (match_operand:BLK 0 "general_operand" "")
   (match_operand:BLK 1 "general_operand" ""))
  (use (match_operand:SI  2 "general_operand" ""))
  (match_operand 3 "" "")]
  ""
  "
{
 rtx op0, op1;

 op0 = XEXP (operands[0], 0);
 if (GET_CODE (op0) == REG
 || (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG
 && GET_CODE (XEXP (op0, 1)) == CONST_INT
 && (unsigned) INTVAL (XEXP (op0, 1)) < 4096))
   op0 = operands[0];
 else
   op0 = replace_equiv_address (operands[0], copy_to_mode_reg (SImode, 
op0));


 op1 = XEXP (operands[1], 0);
 if (GET_CODE (op1) == REG
 || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG
 && GET_CODE (XEXP (op1, 1)) == CONST_INT
 && (unsigned) INTVAL (XEXP (op1, 1)) < 4096))
   op1 = operands[1];
 else
   op1 = replace_equiv_address (operands[1], copy_to_mode_reg (SImode, 
op1));


 /* first line is a hack - if target address involves two registers,
we can't use an MVC, even if the length to move is less than 256,
because MVC takes an S parameter. I'm unsure of the best way to
distinguish a two-register target. */
 if (!((GET_CODE(op0) == MEM) && REG_P(XEXP(op0,0))) &&
 GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 256)
   emit_insn (gen_rtx_PARALLEL (VOIDmode,
   gen_rtvec (2,
  gen_rtx_SET (VOIDmode, op0, op1),
  gen_rtx_USE (VOIDmode, operands[2];

 else
   {
   /* implementation provided by  Richard Henderson  */
   rtx reg1 = gen_reg_rtx (DImode);
   rtx reg2 = gen_reg_rtx (DImode);
   rtx mem1 = operands[0];
   rtx mem2 = operands[1];
   rtx len = operands[2];
   if (!CONSTANT_P (len))
 len = force_reg (SImode, len);

   /* Load up the address+length pairs.  */
   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
   emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0),
   force_operand (XEXP (mem1, 0), NULL_RTX));
   emit_move_insn (gen_rtx_SUBREG (SImode, reg1, GET_MODE_SIZE 
(SImode)), len);


   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg2));
   emit_move_insn (gen_rtx_SUBREG (SImode, reg2, 0),
   force_operand (XEXP (mem2, 0), NULL_RTX));
   emit_move_insn (gen_rtx_SUBREG (SImode, reg2, GET_MODE_SIZE 
(SImode)), len);


   /* Copy! */
   emit_insn (gen_movstrsi_1 (reg1, reg2));
   }
 DONE;
}")


Thanks.  Paul.



Re: i370 port

2012-04-06 Thread Paul Edwards

I've managed to isolate the problem to a small test program.

Any suggestions on how to debug this?

Thanks.  Paul.




C:\devel\gcc\gcc>type bug27.c
/* This program demonstrates a bug in a modification to GCC 3.4.6 */
/* It generates the below error when compiled with -O2 */

#if 0
bug27.c: In function `foo':
bug27.c:28: error: unrecognizable insn:
(insn 116 34 35 2 (set (reg:SI 5 5)
   (plus:SI (plus:SI (reg:SI 2 2 [orig:54 i ] [54])
   (reg/f:SI 13 13))
   (const_int 104 [0x68]))) -1 (nil)
   (nil))
bug27.c:28: internal compiler error: in ZZZ_680, at recog.c:2083
#endif

void foo(int c)
{
   int x[3];
   int y[3];
   int i;

   for (i = 0; i < 2; i++)
   {
   if (c == 1) x[i] &= y[i];
   else if (c == 2) x[i] |= y[i];
   }

   return;
}

C:\devel\gcc\gcc>





-Original Message----- 
From: Paul Edwards

Sent: Friday, April 06, 2012 3:50 PM
To: Ulrich Weigand
Cc: gcc@gcc.gnu.org
Subject: Re: i370 port

I have made this change:

C:\devel\gcc\gcc\config\i370>cvs diff -c -r 1.23 i370.md
Index: i370.md
===
RCS file: c:\cvsroot/gcc/gcc/config/i370/i370.md,v
retrieving revision 1.23
retrieving revision 1.24
diff -c -r1.23 -r1.24
*** i370.md 6 Apr 2012 03:57:08 -   1.23
--- i370.md 6 Apr 2012 04:03:21 -   1.24
***
*** 843,848 
--- 843,853 
   /*return \"STM  %1,%N1,%0\"; */
   return \"ST %1,%0\;ST   %N1,4+%0\";
 }
+   if (GET_CODE (operands[1]) == CONST_INT)
+ {
+   mvs_check_page (0, 6, 8);
+   return \"MVC%O0(8,%R0),%W1\";
+ }
   mvs_check_page (0, 6, 8);
   return \"MVC%O0(8,%R0),%1\";
 }"

C:\devel\gcc\gcc\config\i370>


And it has had a good effect:

diff old/cpplib.s new/cpplib.s
1670c1670
<  MVC   120(8,13),=F'0'
---

 MVC   120(8,13),=XL8''

1796c1796
<  MVC   120(8,13),=F'0'
---

 MVC   120(8,13),=XL8''





However, I'm still stuck.  Because when I make this change:

C:\devel\gcc\gcc\config\i370>cvs diff -r 1.17 i370.h
Index: i370.h
===
RCS file: c:\cvsroot/gcc/gcc/config/i370/i370.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -r1.17 -r1.18
599a600,602

#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
  ((C) == 'S')



It triggers off a problem with plus:SI

C:\devel\gcc\gcc>stdcompm global.c

C:\devel\gcc\gcc>gccmvs -DUSE_MEMMGR -Os -S -DHAVE_CONFIG_H -DIN_GCC -DPUREISO
-
I ../../pdos/pdpclib -I . -I config/i370 -I ../include global.c
global.c: In function `find_reg':
global.c:1325: error: unrecognizable insn:
(insn 2432 130 131 12 (set (reg:SI 15 15)
   (plus:SI (plus:SI (reg:SI 4 4 [orig:82 allocno ] [82])
   (reg:SI 3 3 [87]))
   (const_int 44 [0x2c]))) -1 (nil)
   (nil))
global.c:1325: internal compiler error: in ZZZ_680, at recog.c:2083
Please submit a full bug report,
with preprocessed source if appropriate.
See http://gccmvs.sourceforge.net> for instructions.

C:\devel\gcc\gcc>


Seems to be a problem when adding very small const_ints (in
the above case, 44) that can fit into a LA.  I tried to isolate
which plus:SI rule was causing the problem by commenting out these:

;
; addsi3 instruction pattern(s).
;
; The following insn is used when it is known that operand one is an
address,
; frame, stack or argument pointer, and operand two is a constant that is
; small enough to fit in the displacement field.
; Notice that we can't allow the frame pointer to used as a normal register
; because of this insn.
;

;(define_insn ""
;  [(set (match_operand:SI 0 "register_operand" "=d")
;^I(plus:SI (match_operand:SI 1 "general_operand" "%a")
;^I^I (match_operand:SI 2 "immediate_operand" "J")))]
;  "((REGNO (operands[1]) == FRAME_POINTER_REGNUM || REGNO (operands[1]) ==
ARG$
;  "*
;{
;  check_label_emit ();
;  CC_STATUS_INIT;  /* add assumes CC but LA doesn't set CC */
;  mvs_check_page (0, 4, 0);
;  return \"LA^I%0,%c2(,%1)\";
;}"
;   [(set_attr "length" "4")]
;)

;; The CC status bits for the arithmetic instructions are handled
;; in the NOTICE_UPDATE_CC macro (yeah???) and so they do not need
;; to be set below.  They only need to be invalidated if *not* set
;; (e.g. by BCTR) ... yeah I think that's right ...
;;

;(define_insn "addsi3"
;  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
;^I(plus:SI (match_operand:SI 1 "general_operand" "%0")
;^I^I (match_operand:SI 2 "general_operand" "g")))]
;  ""
;  "*
;{
;  check_label_emit ();
;  if (REG_P (operands[2]))
;{
;  mvs_check_

Re: i370 port

2012-04-05 Thread Paul Edwards
t;show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-cygwin"...
(gdb) run
Starting program: 
/cygdrive/c/devel/gcc/gcc/gccmvs.exe -DUSE_MEMMGR -Os -S -DHAV
E_CONFIG_H -DIN_GCC -DPUREISO -I ../../pdos/pdpclib -I . -I config/i370 -I 
../in

clude alias.c
Error: dll starting at 0x76901000 not found.
Error: dll starting at 0x761f1000 not found.
Error: dll starting at 0x76901000 not found.
Error: dll starting at 0x765f1000 not found.
Loaded symbols for /cygdrive/c/Windows/system32/ntdll.dll
Loaded symbols for /cygdrive/c/Windows/syswow64/kernel32.dll
Loaded symbols for /cygdrive/c/Windows/syswow64/KernelBase.dll

Program received signal SIGSEGV, Segmentation fault.
0x005fca41 in discover_flags_reg () at regmove.c:174
174   if (GET_CODE (tmp) == SET)
(gdb) where
#0  0x005fca41 in discover_flags_reg () at regmove.c:174
#1  0x005fdfd7 in regmove_optimize (f=0x1aaecc0, nregs=29,
   regmove_dump_file=0x0) at regmove.c:1056
#2  0x0064d6bc in rest_of_handle_regmove (decl=0x177a000, insns=0x1aaecc0)
   at toplev.c:2438
#3  0x0064f1af in ZZZ_1833 (decl=0x177a000) at toplev.c:3412
#4  0x00656061 in tree_rest_of_compilation (fndecl=0x177a000, 
nested_p=false)

   at tree-optimize.c:168
#5  0x0043e6ec in c_expand_body_1 (fndecl=0x177a000, nested_p=0)
   at c-decl.c:6190
#6  0x0043e835 in ZZZ_331 (fndecl=0x177a000) at c-decl.c:6222
#7  0x00487dee in cgraph_expand_function (node=0x177ec3c) at 
cgraphunit.c:538

#8  0x00489e7e in cgraph_expand_all_functions () at cgraphunit.c:1542
#9  0x0048a046 in cgraph_optimize () at cgraphunit.c:1607
#10 0x00447d75 in ZZZ_345 () at c-objc-common.c:240
#11 0x0044664b in ZZZ_708 () at c-lang.c:185
#12 0x0044947f in ZZZ_318 (set_yydebug=0) at c-opts.c:1270
#13 0x0064cd88 in compile_file () at toplev.c:1848
#14 0x00650f5a in do_compile () at toplev.c:4695
#15 0x00650ff5 in toplev_main (argc=26, argv=0xcc583c) at toplev.c:4735
#16 0x0054df47 in execute () at gcc.c:2785
#17 0x00551c59 in do_spec (
   spec=0x6a997c "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) 
%(cpp_debug_optio
ns)} %{!E:%{!M:%{!MM: %{traditional|ftraditional:%eGNU C no longer 
supports -tra

ditional without -E} %{save-temps|traditional-cpp|no-integr"...)
   at gcc.c:4265
#18 0x00556a1b in main (argc=16, argv=0x6e6920) at gcc.c:6437
(gdb)


/* Determine if the pattern generated by add_optab has a clobber,
  such as might be issued for a flags hard register.  To make the
  code elsewhere simpler, we handle cc0 in this same framework.

  Return the register if one was discovered.  Return NULL_RTX if
  if no flags were found.  Return pc_rtx if we got confused.  */

static rtx
discover_flags_reg (void)
{
 rtx tmp;
 tmp = gen_rtx_REG (word_mode, 1);
 tmp = gen_add3_insn (tmp, tmp, GEN_INT (2));

 /* If we get something that isn't a simple set, or a
[(set ..) (clobber ..)], this whole function will go wrong.  */
 if (GET_CODE (tmp) == SET)



I tried commenting out different plus:SI rules, but that also
met with a crash in the main compiler.

So I don't know which plus:SI is causing the problem, and
it seems very strange that the extra memory constraint
triggers off the problem.

Any ideas?

Thanks.  Paul.






-Original Message- 
From: Paul Edwards

Sent: Thursday, April 05, 2012 11:31 PM
To: Ulrich Weigand
Cc: gcc@gcc.gnu.org
Subject: Re: i370 port

Hi Ulrich.

I'm getting back to this after a long hiatus.

I have reviewed the 'W' code in PRINT_OPERAND:

else if (CODE == 'W')
 {
   /* hand-built sign-extension of signed 32-bit to 64-bit */
   mvs_page_lit += 8;
   if (0 <=  INTVAL (XV)) {
  fprintf (FILE, "=XL8'");
   } else {
  fprintf (FILE, "=XL8'");
   }
   fprintf (FILE, "%08X'", INTVAL (XV));
 }

and it looks to me like it is already correct. If movdi is given a
const_int as a parameter, then sign-extending to 64-bit is
exactly what needs to happen, isn't it?

I'm only expecting to compile programs as 32-bit, so I'm not
expecting more than 32-bit integers. The IFOX assembler
won't do more than that. In case that's the issue.

But regardless I don't know how to make this code:

mvs_check_page (0, 6, 8);
return \"MVC^I%O0(8,%R0),%1\";

make use of that 'W' operand.

Do I change that %1 to %W1 perhaps?

I'll give that a try tomorrow.

Thanks.  Paul.





-Original Message- 
From: Ulrich Weigand

Sent: Monday, August 22, 2011 10:22 PM
To: Paul Edwards
Cc: gcc@gcc.gnu.org
Subject: Re: i370 port

Paul Edwards wrote:


  if (operands[1] == const0_rtx)
  {
CC_STATUS_INIT;
mvs_check_page (0, 6, 8);
return \"MVC%O0(8,%R0),=XL8'00'\";
  }
  mvs_check_page (0, 6, 8);
  return \"MVC%O0(8,%R0),%1\";
}"
   [(set_attr "length" "8")]
)

forces it to 

Re: i370 port

2012-04-05 Thread Paul Edwards

Hi Ulrich.

I'm getting back to this after a long hiatus.

I have reviewed the 'W' code in PRINT_OPERAND:

else if (CODE == 'W')
 {
   /* hand-built sign-extension of signed 32-bit to 64-bit */
   mvs_page_lit += 8;
   if (0 <=  INTVAL (XV)) {
  fprintf (FILE, "=XL8'");
   } else {
  fprintf (FILE, "=XL8'");
   }
   fprintf (FILE, "%08X'", INTVAL (XV));
 }

and it looks to me like it is already correct. If movdi is given a
const_int as a parameter, then sign-extending to 64-bit is
exactly what needs to happen, isn't it?

I'm only expecting to compile programs as 32-bit, so I'm not
expecting more than 32-bit integers. The IFOX assembler
won't do more than that. In case that's the issue.

But regardless I don't know how to make this code:

mvs_check_page (0, 6, 8);
return \"MVC^I%O0(8,%R0),%1\";

make use of that 'W' operand.

Do I change that %1 to %W1 perhaps?

I'll give that a try tomorrow.

Thanks.  Paul.





-Original Message- 
From: Ulrich Weigand 
Sent: Monday, August 22, 2011 10:22 PM 
To: Paul Edwards 
Cc: gcc@gcc.gnu.org 
Subject: Re: i370 port 


Paul Edwards wrote:


  if (operands[1] == const0_rtx)
  {
CC_STATUS_INIT;
mvs_check_page (0, 6, 8);
return \"MVC%O0(8,%R0),=XL8'00'\";
  }
  mvs_check_page (0, 6, 8);
  return \"MVC%O0(8,%R0),%1\";
}"
   [(set_attr "length" "8")]
)

forces it to use XL8'00' instead of the default F'0' and that
seems to work.  Does that seem like a proper solution to
you?


Well, there isn't really anything special about const0_rtx.
*Any* CONST_INT that shows up as second operand to the movdi
pattern must be emitted into an 8 byte literal at this point.

You can do that inline; but the more usual way would be to
define an operand print format that encodes the fact that
a 64-bit operand is requested.

In fact, looking at the i370.h PRINT_OPERAND, there already
seems to be such a format: 'W'.  (Maybe not quite; since 'W'
sign-extends a 32-bit operand to 64-bit.  But since 'W'
doesn't seem to be used anyway, maybe this can be changed.)

Bye,
Ulrich

--
 Dr. Ulrich Weigand
 GNU Toolchain for Linux on System z and Cell BE
 ulrich.weig...@de.ibm.com


Re: i370 port

2011-08-20 Thread Paul Edwards

Adding this code:

C:\devel\gcc\gcc\config\i370>cvs diff i370.md
Index: i370.md
===
RCS file: c:\cvsroot/gcc/gcc/config/i370/i370.md,v
retrieving revision 1.21
diff -r1.21 i370.md
845a846,851

  if (operands[1] == const0_rtx)
  {
CC_STATUS_INIT;
mvs_check_page (0, 6, 8);
return \"MVC  %O0(8,%R0),=XL8'00'\";
  }


to the i370.md definition:

;
; movdi instruction pattern(s).
;

(define_insn ""
 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,m,S")
   (match_operand:DI 1 "general_operand" "g,d,SF"))]
;;  [(set (match_operand:DI 0 "r_or_s_operand" "=dS,m")
;;(match_operand:DI 1 "r_or_s_operand" "diS*fF,d*fF"))]
 "TARGET_CHAR_INSTRUCTIONS"
 "*
{
 check_label_emit ();
 if (REG_P (operands[0]))
   {
 if (FP_REG_P (operands[1]))
   {
 mvs_check_page (0, 8, 0);
 return \"STD%1,\" CONVLO \"(,13)\;LM%0,%N0,\" CONVLO \"(13)\";
   }
 if (REG_P (operands[1]))
   {
 mvs_check_page (0, 4, 0);
 return \"LR%0,%1\;LR%N0,%N1\";
   }
 if (operands[1] == const0_rtx)
   {
 CC_STATUS_INIT;
 mvs_check_page (0, 4, 0);
 return \"SLR%0,%0\;SLR%N0,%N0\";
   }
 if (GET_CODE (operands[1]) == CONST_INT
   && (unsigned) INTVAL (operands[1]) < 4096)
   {
 CC_STATUS_INIT;
 mvs_check_page (0, 6, 0);
 return \"SLR%0,%0\;LA%N0,%c1(0,0)\";
   }
 if (GET_CODE (operands[1]) == CONST_INT)
   {
 CC_STATUS_SET (operands[0], operands[1]);
 mvs_check_page (0, 8, 0);
 return \"L%0,%1\;SRDA%0,32\";
   }
 if (GET_CODE (operands[1]) == CONST_DOUBLE)
   {
 mvs_check_page (0, 6, 8);
 return \"LM%0,%N0,%1\";
   }
 mvs_check_page (0, 4, 0);
 /*return \"LM%0,%N0,%1\";*/
 return \"L%0,%1\;L%N0,4+%1\";
   }
 else if (FP_REG_P (operands[1]))
   {
 mvs_check_page (0, 4, 0);
 return \"STD%1,%0\";
   }
 else if (REG_P (operands[1]))
   {
 mvs_check_page (0, 4, 0);
 /*return \"STM%1,%N1,%0\"; */
 return \"ST%1,%0\;ST%N1,4+%0\";
   }
 if (operands[1] == const0_rtx)
 {
   CC_STATUS_INIT;
   mvs_check_page (0, 6, 8);
   return \"MVC%O0(8,%R0),=XL8'00'\";
 }
 mvs_check_page (0, 6, 8);
 return \"MVC%O0(8,%R0),%1\";
}"
  [(set_attr "length" "8")]
)


forces it to use XL8'00' instead of the default F'0' and that
seems to work.  Does that seem like a proper solution to
you?

Unfortunately there's still another problem I've noticed.
I'll put that in another message after I've investigated it.

BFN.  Paul.



Re: i370 port

2011-08-20 Thread Paul Edwards

And here is the same debug info as last time ...

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"

rtx
foo (rtx addr, int size, int n_refs)
{
 int offset = 0;

 switch (GET_CODE (addr))
   {
   case PRE_INC:
 offset = (n_refs + 1) * size;
 break;
   case PRE_DEC:
 offset = -(n_refs + 1) * size;
 break;
   case POST_INC:
 offset = n_refs * size;
 break;
   }

 if (offset)
   addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0),
GEN_INT (offset));
 else
   addr = XEXP (addr, 0);

 return addr;
}


COPY  PDPTOP
CSECT
* Program text area
DS0F
* X-func foo prologue
FOO  PDPPRLG CINDEX=0,FRAME=120,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
MVC 112(8,13),=F'0'
SLR   8,8
SLR   9,9
LR6,8
LR7,9
L 3,0(11)
L 2,8(11)
LH4,0(3)
N 4,=XL4''
ST4,104(13)
LA5,110(0,0)
CLR   4,5
BEL3
BHL6
LA15,109(0,0)
CLR   4,15
BEL4
B L7
L6   EQU   *
L 5,104(13)
LA4,112(0,0)
CLR   5,4
BEL5
B L7
L3   EQU   *
A 2,=F'1'
L 15,4(11)
ST15,116(13)
L 4,112(13)
L 5,4+112(13)
MR4,2
ST4,112(13)
ST5,4+112(13)
LR2,5
B L2
L4   EQU   *
X 2,=F'-1'
L 9,4(11)
MR8,2
LR2,9
B L2
L5   EQU   *
L 7,4(11)
MR6,2
LR2,7
L2   EQU   *
LTR   2,2
BEL7
MVC   88(4,13),=F'0'
ST2,92(13)
LA1,88(,13)
L 15,=V(ZZZ@947)
BALR  14,15
MVC   88(4,13),=F'88'
SLR   5,5
IC5,2(3)
ST5,92(13)
MVC   96(4,13),4(3)
ST15,100(13)
LA1,88(,13)
L 15,=V(ZZZ@957)
BALR  14,15
LR3,15
B L8
L7   EQU   *
L 3,4(3)
L8   EQU   *
LR15,3
* Function foo epilogue
PDPEPIL
* Function foo literal pool
DS0F
LTORG
* Function foo page table
DS0F
PGT0 EQU   *
DCA(PG0)
END



;; Function foo

;; 8 regs to allocate: 37 28 29 31 (2) 35 (2) 34 (2) 26 27
;; 26 conflicts: 26 27 28 29 31 34 35 37 11 15
;; 27 conflicts: 26 27 28 31 34 35 37 11
;; 28 conflicts: 26 27 28 31 34 35 37 11
;; 29 conflicts: 26 29 11
;; 31 conflicts: 26 27 28 31 34 35 37 11
;; 34 conflicts: 26 27 28 31 34 35 37 11
;; 35 conflicts: 26 27 28 31 34 35 37 11
;; 37 conflicts: 26 27 28 31 34 35 37 11

Spilling for insn 3.
Spilling for insn 4.
Spilling for insn 5.
Spilling for insn 45.
Spilling for insn 46.
Using reg 15 for reload 0
Spilling for insn 48.
Using reg 4 for reload 0
Spilling for insn 50.
Using reg 4 for reload 0
Spilling for insn 55.
Using reg 4 for reload 0
Spilling for insn 19.
Spilling for insn 29.
Spilling for insn 37.
Spilling for insn 63.
Spilling for insn 64.
Spilling for insn 67.
Spilling for insn 71.
Using reg 2 for reload 0
Spilling for insn 72.
Spilling for insn 73.
Spilling for insn 80.
Register 37 now on stack.

Spilling for insn 3.
Spilling for insn 4.
Spilling for insn 5.
Spilling for insn 45.
Using reg 15 for reload 0
Spilling for insn 46.
Using reg 15 for reload 1
Using reg 4 for reload 0
Spilling for insn 48.
Using reg 4 for reload 1
Using reg 5 for reload 0
Spilling for insn 50.
Using reg 4 for reload 1
Using reg 5 for reload 0
Spilling for insn 55.
Using reg 4 for reload 1
Using reg 5 for reload 0
Spilling for insn 19.
Spilling for insn 29.
Spilling for insn 37.
Spilling for insn 63.
Spilling for insn 64.
Spilling for insn 67.
Spilling for insn 71.
Using reg 2 for reload 0
Spilling for insn 72.
Spilling for insn 73.
Spilling for insn 80.
Register 31 now on stack.

Spilling for insn 113.
Spilling for insn 3.
Spilling for insn 4.
Spilling for insn 5.
Spilling for insn 45.
Using reg 4 for reload 0
Spilling for insn 46.
Using reg 4 for reload 1
Using reg 5 for reload 0
Spilling for insn 48.
Using reg 4 for reload 1
Using reg 5 for reload 0
Spilling for insn 50.
Using reg 4 for reload 1
Using reg 5 for reload 0
Spilling for insn 55.
Using reg 4 for reload 1
Using reg 5 for reload 0
Spilling for insn 19.
Using reg 4 for reload 0
Spilling for insn 20.
Using reg 4 for reload 0
Spilling for insn 21.
Spilling for insn 29.
Spilling for insn 37.
Spilling for insn 63.
Spilling for insn 64.
Spilling for insn 67.
Spilling for insn 71.
Using reg 2 for reload 0
Spilling for insn 72.
Spilling for insn 73.
Spilling for insn 80.

Reloads for insn # 113
Reload 0: reload_out (DI) = (reg:DI 31 [ si

Re: i370 port

2011-08-20 Thread Paul Edwards

(like the 8 byte move from F'0').  I'll do my own investigation
of that and report that later.


Ok, the bad MVC:

MVC 112(8,13),=F'0'

is being generated by the movdi instruction:

;
; movdi instruction pattern(s).
;

(define_insn ""
 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,m,S")
   (match_operand:DI 1 "general_operand" "g,d,SF"))]
;;  [(set (match_operand:DI 0 "r_or_s_operand" "=dS,m")
;;(match_operand:DI 1 "r_or_s_operand" "diS*fF,d*fF"))]
 "TARGET_CHAR_INSTRUCTIONS"
 "*
{
...
 return \"MVC^I%O0(8,%R0),%1\";
}"

which looks correct to me.  The problem seems to be an =F'0' being
treated as a DI operand.

That extra memory constraint thing must be allowing this rogue
value through that was normally not picked up.

Any ideas?

Thanks.  Paul.



Re: i370 port

2011-08-18 Thread Paul Edwards

Well done!  That generated sensible code:

L 15,=V(PRINTF)
BALR  14,15
L 3,=F'32880'
AR3,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 



Re: i370 port

2011-08-18 Thread Paul Edwards

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.

Let me know if that is not the debugging required.

Thanks.  Paul.




-Original Message- 
From: Ulrich Weigand

Sent: Tuesday, August 16, 2011 11:25 PM
To: Paul Edwards
Cc: gcc@gcc.gnu.org
Subject: Re: i370 port

Paul Edwards wrote:

>> Unfortunately it's not quite right, seemingly not loading R9 properly:
>>
>> LR9,13
>> AR9,13
>> MVC   0(10,9),0(2)

> That's weird.  What does the reload dump (.greg) say?

I have trimmed the code down to a reasonably small size so that I
could provide the .greg file (below) from the "-da" option.  I don't
know how to read it so I don't know if I've provided everything
required.

Here is the current problematic generated code:

* Function pdosLoadExe code
 L 2,4(11)
 MVC   88(4,13),=A(LC0)
 ST2,92(13)
 LA1,88(,13)
 L 15,=V(PRINTF)
 BALR  14,15
 LR3,13   <= probably wrong
 AR3,13   <= else this is wrong
 MVC   0(10,3),0(2)


Reload decides on the following actions:


Reloads for insn # 38
Reload 0: reload_in (SI) = (const_int 32880 [0x8070])
 ADDR_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 0)
 reload_in_reg: (const_int 32880 [0x8070])
 reload_reg_rtx: (reg:SI 3 3)
Reload 1: reload_in (SI) = (plus:SI (reg/f:SI 13 13)
(const_int 32880
[0x8070]))
 ADDR_REGS, RELOAD_FOR_INPUT (opnum = 0)
 reload_in_reg: (plus:SI (reg/f:SI 13 13)
(const_int 32880
[0x8070]))
 reload_reg_rtx: (reg:SI 3 3)


That is, first: load the constant 32880 into register 3,
and second: using that reloaded constant, compute the sum
of register 13 plus 32880 and load the result also into
register 3.  Then, use that register for addressing.

This leads to the following generated code:


(insn 271 37 273 0 (set (reg:SI 3 3)
(const_int 32880 [0x8070])) 15 {movsi} (nil)
(nil))


Load constant into register 3.


(insn 273 271 274 0 (set (reg:SI 3 3)
(reg/f:SI 13 13)) 15 {movsi} (nil)
(nil))

(insn 274 273 38 0 (set (reg:SI 3 3)
(plus:SI (reg:SI 3 3)
(reg:SI 3 3))) 41 {addsi3} (nil)
(expr_list:REG_EQUIV (plus:SI (reg/f:SI 13 13)
(reg:SI 3 3))
(nil)))


Compute the sum.  Note that this code is wrong.


(insn 38 274 41 0 (parallel [
(set (mem/s:BLK (reg:SI 3 3) [6 srchprog+0 S10 A64])
(mem:BLK (reg/v/f:SI 2 2 [orig:27 prog ] [27]) [0 S10 
A8]))

(use (const_int 10 [0xa]))
]) 25 {*i370.md:1623} (insn_list 37 (nil))
(nil))


Use register 3 for adressing.

The wrong code comes in when generating the sum (insns 273/274).
I would have expected this to be a simple addsi3 instruction, along the
lines of

(set (reg:SI 3 3) (plus:SI (reg:SI 3 3) (reg:SI 13 13)))

Note that the incoming pattern:

(set (reg:SI 3 3) (plus:SI (reg:SI 13 13) (reg:SI 3 3)))

cannot be immediately resolved, since addsi3 requires the first
operand of the plus to match the result.

However, this could have been fixed by just swapping the operands.
Instead, the code attempts to create the match by reloading the
first operand (reg 13) into the output (reg 3) -- this is bogus,
since it thereby clobbers the *second* input operand, which happens
to match the output.

The code that generates these insns is in reload1.c:gen_reload

 /* We need to compute the sum of a register or a MEM and another
register, constant, or MEM, and put it into the reload
register.  The best possible way of doing

Re: i370 port

2011-08-15 Thread Paul Edwards

You'll need to mark your new constraint as EXTRA_MEMORY_CONSTRAINT
so that reload knows what to do when an argument doesn't match.


Thanks! That certainly produced an effect.

Unfortunately it's not quite right, seemingly not loading R9 properly:

LR9,13
AR9,13
MVC   0(10,9),0(2)

And it had a knock-on effect too, producing bad code elsewhere:

<  SLR   2,2
<  SLR   3,3
<  ST2,128(13)
<  ST3,4+128(13)
<  ST2,136(13)
<  ST3,4+136(13)
<  ST2,144(13)
<  ST3,4+144(13)
---

 MVC   128(8,13),=F'0'
 MVC   136(8,13),=F'0'
 MVC   144(8,13),=F'0'


But I guess that is another can of worms to investigate.

BFN.  Paul.



Re: i370 port

2011-08-13 Thread Paul Edwards

Hi Ulrich and group.

The i370 port of GCC 3.4.6 is now complete and the result can be
downloaded from http://gccmvs.sourceforge.net

It can be built using configure/make, and there weren't that many
changes that needed to be made to the code to get it to work.

However, I have encountered a bug.

I get bad code generated for this, because a non-s_operand is
getting through:

; Move a block that is less than 256 bytes in length.

(define_insn ""
 [(set (match_operand:BLK 0 "s_operand" "=m")
   (match_operand:BLK 1 "s_operand" "m"))
  (use (match_operand 2 "immediate_operand" "I"))]
 "((unsigned) INTVAL (operands[2]) < 256)"
 "*
{
 check_label_emit ();
 mvs_check_page (0, 6, 0);
 return \"MVC  %O0(%c2,%R0),%1\";
}"
  [(set_attr "length" "6")]
)

Here is the bad code:

L 9,=F'32880'
MVC   9(10,13),0(2)

That "9" in the MVC is supposed to be a constant from 0-4095. It
can't fit the large value in so has used a register, but then tried
to use that register in the instruction. It should have added R13
to R9 and used that as the base register (instead of the 13
you see)

I was surprised that an instruction that is marked as s_operand
was getting a seemingly non-s_operand given to it, so I added an
"S" constraint:

; Move a block that is less than 256 bytes in length.

(define_insn ""
 [(set (match_operand:BLK 0 "s_operand" "=S")
   (match_operand:BLK 1 "s_operand" "m"))

That then gave an actual compiler error instead of generating bad
code, which is a step forward:

pdos.c: In function `pdosLoadExe':
pdos.c:2703: error: unable to generate reloads for:
(insn 38 37 41 0 (parallel [
   (set (mem/s:BLK (plus:SI (reg/f:SI 13 13)
   (const_int 32880 [0x8070])) [27 srchprog+0 S10 A64])
   (mem:BLK (reg/v/f:SI 2 2 [orig:27 prog ] [27]) [0 S10 A8]))
   (use (const_int 10 [0xa]))
   ]) 25 {*i370.md:1623} (insn_list 37 (nil))
   (expr_list:REG_DEAD (reg/v/f:SI 2 2 [orig:27 prog ] [27])
   (nil)))
pdos.c:2703: internal compiler error: in find_reloads, at reload.c:3690
Please submit a full bug report,
with preprocessed source if appropriate.
See http://gccmvs.sourceforge.net> for instructions.


But I am surprised that s_operand and "S" are producing different
results.

Regardless, I sort of tracked the problem down to this bit of the
machine definition:

;
; movstrsi instruction pattern(s).
; block must be less than 16M (24 bits) in length

(define_expand "movstrsi"
 [(set (match_operand:BLK 0 "general_operand" "")
   (match_operand:BLK 1 "general_operand" ""))
  (use (match_operand:SI  2 "general_operand" ""))
  (match_operand 3 "" "")]
  ""
  "
{
 rtx op0, op1;

 op0 = XEXP (operands[0], 0);
 if (GET_CODE (op0) == REG
 || (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG
 && GET_CODE (XEXP (op0, 1)) == CONST_INT
 && (unsigned) INTVAL (XEXP (op0, 1)) < 4096))
   op0 = operands[0];
 else
   op0 = replace_equiv_address (operands[0], copy_to_mode_reg (SImode, 
op0));


 op1 = XEXP (operands[1], 0);
 if (GET_CODE (op1) == REG
 || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG
 && GET_CODE (XEXP (op1, 1)) == CONST_INT
 && (unsigned) INTVAL (XEXP (op1, 1)) < 4096))
   op1 = operands[1];
 else
   op1 = replace_equiv_address (operands[1], copy_to_mode_reg (SImode, 
op1));


 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 256)
   emit_insn (gen_rtx_PARALLEL (VOIDmode,
   gen_rtvec (2,
  gen_rtx_SET (VOIDmode, op0, op1),
  gen_rtx_USE (VOIDmode, operands[2];


So now I am basically wanting to stop this code from doing that emit_insn.
I tested putting in a kludge to see if operands[2] was equal to 10 (the
length in my test case), and bypassing the emit_insn. That forced it to
use a more inefficient move instruction, but that's fine.

So I need some way of getting op0 detected as "unsuitable for use in
an MVC". I have put in debug and found that GET_CODE(op0) is equal
to MEM. I have also found that GET_CODE(XEXP(op0, 0)) is a REG_P,
whatever that means (I was just copying things I saw in the
s_operand test). Here is the s_operand test for reference:

/* Return 1 if OP is a valid S operand for an RS, SI or SS type instruction.
  OP is the current operation.
  MODE is the current operation mode.  */

int
s_operand (register rtx op, enum machine_mode mode)
{
 extern int volatile_ok;
 register enum rtx_code code = GET_CODE (op);

 if (CONSTANT_ADDRESS_P (op))
   return 1;
 if (mode == VOIDmode || GET_MODE (op) != mode)
   return 0;
 if (code == MEM)
   {
 register rtx x = XEXP (op, 0);

 if (!volatile_ok && op->volatil)
   return 0;
 if (REG_P (x) && REG_OK_FOR_BASE_P (x))
   return 1;
 if (GET_CODE (x) == PLUS
 && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0))
 && GET_CODE (XEXP (x, 1)) == CONST_INT
 && (unsigned) INTVAL (XEXP (x, 1)) < 4096)
  

Re: i370 port - status

2010-05-26 Thread Paul Edwards

So the fix below is not a fix but papering over an
issue elswhere.


Ok, this problem nearly killed me.  It took months of
effort to try to isolate the fault, delving into unfamiliar code,
trying to get something that could be reliably reproduced.

I did finally succeed in getting an executable that reliably
crashed on the 3rd identical run.

However, when I attempted to debug at a level above, ie in
the emulator, the bug would disappear also.

My working hypothesis now is that it is a bug in the
Hercules emulator to do with paging.  Which means I am
at the mercy of the operating system as to when it pages.
That operating system is MUSIC/SP, and it doesn't come
with source code, and I'm not really familiar with it anyway,
and the author is dead (a couple of years ago).

I did succeed in finding a configuration option to stop the
huge amount of paging in MUSIC/SP.  That then allowed my
compiles to go through cleanly, so I am now able to
get GCC to reproduce itself under MUSIC/SP.

The underlying presumed paging bug in either Hercules or
MUSIC/SP I decided to just package up and leave for another
day, as neither thing was my main or even important focus.

Closer to my main focus - after getting GCC working on MUSIC/SP,
the final real ("real" = "commercially used operating system,
which people use to develop code, and which doesn't have a
free C compiler already") target that I knew of that remained
was DOS/VS (z/VSE).

In April 2010 I finally got this last environment to have a hosted
C compiler that was good enough to compile a "hello world".
The C runtime library is only bare bones, so it can't handle
#include yet, only reading from stdin, but that's enough to get
the right code for a "hello world" to be generated.  Getting GCC
on that environment found a bug in the DOS/VS operating
system, and other limitations, but these problems were
worked around.

As we speak, Michel et al over here:

http://tech.groups.yahoo.com/group/H390-DOSVS/

is battling to try to get the DOS/VS environment to process a 
PARM string (in a way compatible with z/VSE).  Previously

the parameter was kludged to read it from stdin.  The old
DOS/VS doesn't have parameters basically.  Then the rest
of the library can be dealt with (reading from private source
statement libraries is the main thing).

Meanwhile, I have released GCC 3.2.3 MVS 8.0, which
can be found here:

http://gccmvs.sourceforge.net

which includes a much nicer MVS environment (with default
DCB information) for GCC et al.  It also includes the afore
mentioned MUSIC/SP and DOS/VS ports, even if the latter
is bare-bones.

Perhaps a link to that site could be put here:

http://gcc.gnu.org/extensions.html

So in the short term, the sort of things I am likely to be involved in are:

1. MVS source code management (10 million lines of code).
2. Improve VSE/380 port.
3. GCC 3.4.6 upgrade (from 3.2.3).

Although I managed to get 3.4.6 working on MVS many months ago,
I haven't formally released that port because I was trying to get the
potentially last 3.2.3 out the door.  But that happened a couple of
days ago.  So now, as long as I can bring all 4 environments along,
I should be able to upgrade.

GCC 3.4.6 has the advantage that the Unix build tools are able to
generate all the required files for MVS etc.  Before I used to
handcraft them.  I could probably backport that to 3.2.3 but haven't
tried, as my plan was to go forward.

One problem with going foward though is that I will lose the ability
to generate the generated files from i370.md.  The reason for that
is that one of the generator programs opens lots of files by name,
and those names are not appropriate for MVS usage.  I can
probably work around that, but rather than spending the effort
doing that, I was planning on revisiting that in GCC 4, and in the
meantime, just do that part of the build on Unix instead.  If people
truly need a self-contained MVS (EBCDIC) C compiler, then 3.2.3
will always be available.

Hopefully I'll have more positive news on GCC on the EBCDIC
platfoms in the months ahead.  :-)  Thanks to everyone who
helped in getting it so far already.

BFN.  Paul.






- Original Message - 
From: "Richard Guenther" 

To: "Paul Edwards" 
Cc: 
Sent: Sunday, November 29, 2009 2:02 AM
Subject: Re: i370 port - music/sp - possible generic gcc problem


On Sat, Nov 28, 2009 at 4:13 PM, Paul Edwards  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 

Re: i370 port - 3.4.6 to 4.4 upgrade attempt

2009-12-07 Thread Paul Edwards

Well I have good news to report.

I applied most of your recommended changes, but it still crashed,
still at the same spot:

:0: internal compiler error: Segmentation fault

However, I managed to track it down to some floating point stuff
in the i370 code, and got rid of that, and now I can compile a
"hello, world" program!

The changes to 4.4.0 required to do that can be found here:

http://rapidshare.com/files/317504205/gcc4-alpha6.zip


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.


I found that if I didn't define anything for this at all, it still worked.
I'm not sure when the lack of "hex float" will actually start
affecting me.  I got it to generate code like:

LD 0,=D'5.599...e+0'

which will only require minor modifications to be acceptable to 
HLASM.  And in fact, that's basically the same code that was

being generated with GCC 3.4.6 anyway.

In the meantime, I'll see how much of gcc 4.4 can be self-compiled.

BFN.  Paul.



Re: i370 port

2009-12-02 Thread Paul Edwards

I think I would stop right there.  Why can't the i370 port support
64-bit integers?  Plenty of 32-bit hosts support them.


It got an internal error.  I don't have the skills to get that to work,
but I do have the skills to bypass it one way or another (and I
demonstrated what I am doing now, but I know that that
intrusive code will break everything else, so want to back it out,
without losing the functionality that I want).


A failure in your target is not a reason to change target-independent
code.


Well I found out what was causing this - the adddi3 definition.
Commenting that out allowed the target to be built the normal
way.

However, when doing the host build, I wanted everything done
by the (ansi) book so that I end up with code that can be compiled
with a C90 compiler, be it IBM's C/370 or Borland C++.

I found that I could achieve that by making my dummy cross-compile
script introduce the -ansi -pedantic-errors options.

However, that triggered off some more changes to configure like this ...

Index: gccnew/libiberty/configure
diff -c gccnew/libiberty/configure:1.1.1.3 gccnew/libiberty/configure:1.25
*** gccnew/libiberty/configure:1.1.1.3^ISun Nov 15 19:41:46 2009
--- gccnew/libiberty/configure^IWed Dec  2 17:18:07 2009
***
*** 4190,4196 
 #if defined (__stub_$ac_func) || defined (__stub___$ac_func)
 choke me
 #else
! char (*f) () = $ac_func;
 #endif
 #ifdef __cplusplus
 }
--- 4190,4196 
 #if defined (__stub_$ac_func) || defined (__stub___$ac_func)
 choke me
 #else
! char (*f) () = (char (*)())$ac_func;
 #endif
 #ifdef __cplusplus
 }
***
*** 4199,4205 
 int
 main ()
 {
! return f != $ac_func;
   ;
   return 0;
 }
--- 4199,4205 
 int
 main ()
 {
! return f != (char (*)())$ac_func;
   ;
   return 0;
 }


I still haven't found the wild pointer in my GCC 3.2.3 port that gets
masked with xcalloc.  It's a tough one because the problem keeps
on disappearing whenever I try to introduce debug info and I haven't
found a technique yet.

So I'm working on 3.2.3, 3.4.6 and 4.4 at any particular time.  :-)

BFN.  Paul..



Re: i370 port - music/sp - possible generic gcc problem

2009-11-29 Thread Paul Edwards
Latest information - 


Ok, based on this, I traced it back further:

rtx
gen_rtx_fmt_e0 (code, mode, arg0)
RTX_CODE code;
enum machine_mode mode;
rtx arg0;
{
 rtx rt;
 rt = ggc_alloc_rtx (2);
 memset (rt, 0, sizeof (struct rtx_def) - sizeof (rtunion));


The request for 2 (I guess, rtx's) results in a malloc for 65536
bytes, so presumably each rtx is 32k.  It appears that only the 
single byte at offset 47072 needs to be initialized to some

appropriate value (I found that x'08' and x'81' also work, and
I am still experimenting on that) in order to circumvent the 
problem of garbage code generation.



rtx
gen_rtx_MEM (mode, addr)
enum machine_mode mode;
rtx addr;
{
 rtx rt = gen_rtx_raw_MEM (mode, addr);

 /* This field is not cleared by the mere allocation of the rtx, so
we clear it here.  */
 MEM_ATTRS (rt) = 0;

 return rt;
}


I wonder if another field like the above also needs to be
initialized?  Or maybe the same field, but it needs to be
for the second rtx?

I will try to see if I can map that offset onto a meaningful variable.

BFN.  Paul.



Re: i370 port - music/sp - possible generic gcc problem

2009-11-28 Thread Paul Edwards

: In function `acos':
:137: Internal compiler error in ?, at :724
Please submit a full bug report,
with preprocessed source if appropriate.
See http://gcc.gnu.org/bugs.html> for instructions.

I might be able to trace it from a different approach, getting more
information about that internal error, now that I know where some
of the involved memory is.  I'll get that  converted into a
PC filename first.


6 hours of compilation later, I was unsuccessful in getting the proper
filename displayed.  As far as I can tell, it's aborting but not displaying
any output.  ie randomly displaying the above message.

However, not to worry, since there's only one line 724 with an
abort() in it, and it's this bit of code:

static int
insert_save (chain, before_p, regno, to_save, save_mode)
struct insn_chain *chain;
int before_p;
int regno;
HARD_REG_SET *to_save;
enum machine_mode *save_mode;
{
 int i;
 unsigned int k;
 rtx pat = NULL_RTX;
 int code;
 unsigned int numregs = 0;
 struct insn_chain *new;
 rtx mem;

 /* A common failure mode if register status is not correct in the RTL
is for this routine to be called with a REGNO we didn't expect to
save.  That will cause us to write an insn with a (nil) SET_DEST
or SET_SRC.  Instead of doing so and causing a crash later, check
for this common case and abort here instead.  This will remove one
step in debugging such problems.  */

 if (regno_save_mem[regno][1] == 0)
   abort ();


which is in the same file as the init_caller_save() function that
allocated the memory in the first place.

One fortunate thing is that this source file is under 1000 lines
long so hopefully amenable to debugging.

BFN.  Paul.



Re: i370 port - music/sp - possible generic gcc problem

2009-11-28 Thread Paul Edwards

If GC does that, then how come there is all this effort to do
mmap testing to see if it has the facility to zero memory, and



I can't see what you are refering to.


I obviously misinterpreted that then.


why is the surrounding code (in GCC 4.4's alloc_page())
calling XCNEWVEC instead of XNEWVEC?



That's the page table entries, not the data itself.



There wouldn't be the need for ggc_alloc_cleared if ggc_alloc
would already zero pages.


Ok, based on this, I traced it back further:

rtx
gen_rtx_fmt_e0 (code, mode, arg0)
RTX_CODE code;
enum machine_mode mode;
rtx arg0;
{
 rtx rt;
 rt = ggc_alloc_rtx (2);
 memset (rt, 0, sizeof (struct rtx_def) - sizeof (rtunion));



rtx
gen_rtx_MEM (mode, addr)
enum machine_mode mode;
rtx addr;
{
 rtx rt = gen_rtx_raw_MEM (mode, addr);

 /* This field is not cleared by the mere allocation of the rtx, so
we clear it here.  */
 MEM_ATTRS (rt) = 0;

 return rt;
}



void
init_caller_save ()
{
...
 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   for (mode = 0 ; mode < MAX_MACHINE_MODE; mode++)
 if (HARD_REGNO_MODE_OK (i, mode))
   {
 rtx mem = gen_rtx_MEM (mode, address);


And indeed, this code - caller_save, shows up as one of the symptoms.
One of the symptoms is that where it is meant to be saving a register
prior to a function call, it instead generates a completely stupid
instruction - and that stupid instruction happens to be the first
instruction listed in i370.md.

Right at the moment the symptom is:

/ID SAVE-JOB-123456 @BLD000    
/SYS REGION=,XREGION=64M
/FILE SYSPRINT PRT OSRECFM(F) OSLRECL(256)
/FILE SYSIN N(MATH.C) SHR
/FILE O N(MATH.S) NEW RECFM(V) SP(1000)
/FILE SYSINCL PDS(*.H)
/FILE INCLUDE PDS(*.H)
/PARM -Os -S -DUSE_MEMMGR -DMUSIC -o dd:o -
/LOAD XMON
: In function `acos':
:137: Internal compiler error in ?, at :724
Please submit a full bug report,
with preprocessed source if appropriate.
See http://gcc.gnu.org/bugs.html> for instructions.

compiling something from my C runtime library.  But I basically get
different behaviour depending on what I initialize uninitialized memory
to.

Any ideas on what to look for now?  I can probably isolate which bit
of the malloc()ed memory is being referenced before initialization.
But finding out who is doing the reference could be tricky.

I might be able to trace it from a different approach, getting more
information about that internal error, now that I know where some
of the involved memory is.  I'll get that  converted into a
PC filename first.

BFN.  Paul.



Re: i370 port - music/sp - possible generic gcc problem

2009-11-28 Thread Paul Edwards

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.


Hi Richard.

If GC does that, then how come there is all this effort to do
mmap testing to see if it has the facility to zero memory, and
why is the surrounding code (in GCC 4.4's alloc_page())
calling XCNEWVEC instead of XNEWVEC?

Thanks.  Paul.



i370 port - music/sp - possible generic gcc problem

2009-11-28 Thread Paul Edwards

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 -  1.1.1.1
--- ggc-page.c  28 Nov 2009 14:13:41 -
***
*** 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 
# 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

Re: i370 port - 3.4.6 to 4.4 upgrade attempt

2009-11-24 Thread Paul Edwards

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.


Hmmm.  Well I don't know anything about floating point.

Thanks very much for all your comments.  I will see what
difference that makes.


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.


Ok, well what I did in the original (3.2) port was to ANSIfy it and
then use different debuggers (Borland, Watcom) on my Windows
box.  I'll see what I can come up with this time.


Overall, I still think that adding HLASM support to the s390
back-end would probably be a simpler task ...


Well in that case, maybe now is the time to be doing exactly
that.  I could make 3.4.6 the last of the i370 ports.

Can you tell me what is required to convert s390, which has a
very alien assembler output, into hlasm?

And that brings me to another question.  The i370 hlasm port
uses tabs in every instruction to separate the instruction and
operand.  This is not valid in hlasm.  In order to get around
this, I ended up doing a #define for putc etc to channel everything
through my own routine which converted those tabs into an
appropriate number of spaces.  I suspect there's a neater way
to do things, but I never stumbled across that in my travels.

Thanks.  Paul.



Re: i370 port - 3.4.6 to 4.4 upgrade attempt

2009-11-23 Thread Paul Edwards

Ok, now that 3.4.6 is fully working, I made a start on the 4.4 port.

4.4 appears to have invalidated a lot of 3.4.6 things.  Below are all
the changes I needed to make just to get an xgcc executable
built.  I didn't really know what most of it was about, but the
purpose was just to scope the changes.  Any changes that need
to be done to 4.4 I can now refer to how it was accomplished
in 3.4.6.

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.

This time I don't have a working code generator.  With these
changes to force an executable, I can go:

xgcc --version

and it works, but when I attempt a compile (with -S), I get an
internal error in builtin line 0, which is presumably completely
meaningless because I haven't actually done the work yet.

Thanks.  Paul.



Index: gcc4/config.sub
diff -c gcc4/config.sub:1.3 gcc4/config.sub:1.4
*** gcc4/config.sub:1.3 Mon Nov 23 12:58:07 2009
--- gcc4/config.sub Mon Nov 23 22:47:08 2009
***
*** 940,945 
--- 940,948 
  rtpc | rtpc-*)
   basic_machine=romp-ibm
   ;;
+  i370 | i370-*)
+   basic_machine=i370-ibm
+   ;;
  s390 | s390-*)
   basic_machine=s390-ibm
   ;;
Index: gcc4/gcc/config.gcc
diff -c gcc4/gcc/config.gcc:1.3 gcc4/gcc/config.gcc:1.4
*** gcc4/gcc/config.gcc:1.3 Mon Nov 23 12:58:07 2009
--- gcc4/gcc/config.gcc Mon Nov 23 22:46:56 2009
***
*** 358,363 
--- 358,366 
  cpu_type=spu
  need_64bit_hwint=yes
  ;;
+ i370*-*-*)
+  cpu_type=i370
+  ;;
 s390*-*-*)
  cpu_type=s390
  need_64bit_hwint=yes
***
*** 1964,1969 
--- 1967,1984 
  thread_file='aix'
  extra_headers=altivec.h
  ;;
+ 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"
+  ;;
 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"
Index: gcc4/gcc/config/i370/i370-c.c
diff -c gcc4/gcc/config/i370/i370-c.c:1.5 gcc4/gcc/config/i370/i370-c.c:1.6
*** gcc4/gcc/config/i370/i370-c.c:1.5 Mon Nov 23 22:17:42 2009
--- gcc4/gcc/config/i370/i370-c.c Mon Nov 23 22:46:22 2009
***
*** 34,40 

 #ifdef TARGET_HLASM

! #define BAD(msgid) do { warning (msgid); return; } while (0)

 /* #pragma map (name, alias) -
In this implementation both name and alias are required to be
--- 34,43 

 #ifdef TARGET_HLASM

! #define BAD(msgid) do { warning (0, msgid); return; } while (0)
!
! /* +++ c_lex has gone. however, we don't use it for anything important 
anyway */

! #define c_lex(a)

 /* #pragma map (name, alias) -
In this implementation both name and alias are required to be
***
*** 42,52 
anyone clarify?  */

 void
! i370_pr_map (pfile)
!  cpp_reader *pfile ATTRIBUTE_UNUSED;
 {
   tree name, alias, x;

   if (c_lex (&x) != CPP_OPEN_PAREN)
 BAD ("missing '(' after '#pragma map' - ignored");

--- 45,55 
anyone clarify?  */

 void
! i370_pr_map (cpp_reader *pfile ATTRIBUTE_UNUSED)
 {
   tree name, alias, x;

+ #if 0
   if (c_lex (&x) != CPP_OPEN_PAREN)
 BAD ("missing '(' after '#pragma map' - ignored");

***
*** 63,70 
 BAD ("missing ')' for '#pragma map' - ignored");

   if (c_lex (&x) != CPP_EOF)
! warning ("junk at end of '#pragma map'");
!
   mvs_add_alias (IDENTIFIER_POINTER (name), TREE_STRING_POINTER (alias), 
1);

 }

--- 66,73 
 BAD ("missing ')' for '#pragma map' - ignored");

   if (c_lex (&x) != CPP_EOF)
! warning (0, "junk at end of '#pragma map'");
! #endif
   mvs_add_alias (IDENTIFIER_POINTER (name), TREE_STRING_POINTER (alias), 
1);

 }

***
*** 74,84 
anyone clarify?  */

 void
! i370_pr_linkage (pfile)
!  cpp_reader *pfile ATTRIBUTE_UNUSED;
 {
   tree name, mode, x;

   if (c_lex (&x) != CPP_OPEN_PAREN)
 BAD ("missing '(' after '#pragma linkage' - ignored");

--- 77,87 
anyone clarify?  */

 void
! i370_pr_linkage (cpp_reader *pfile ATTRIBUTE_UNUSED)
 {
   tree name, mode, x;

+ #if 0
   if (c_lex (&x) != CPP_OPEN_PAREN)
 BAD ("missing '(' after '#pragma linkage' - ignored");

***
*** 95,102 
 BAD ("missing ')' for '#pragma linkage' - ignored");

   if (c_lex (&x) != CPP_EOF)
! warning ("junk at end of '#pragma linkage'");
!
 }

 /* #pragma checkout (mode) -
--- 98,105 
 BAD ("missing ')' for '#pragma linkage' - ignored");

 

Re: i370 port - constructing compile script

2009-11-21 Thread Paul Edwards

gcov-iov creates a gcov-iov.h which has a version number
which changes when I change MVS versions.  So I am
thinking of updating gcov-iov.c so that when the target is
MVS, it generates a more fixed format.


I don't see how the generated number depends on the MVS
version ...  It is supposed to depend solely on the *GCC*
version string of the compiler currently being built.


Mostly yes.  However, it still grabs the full version string,
which includes the text "MVS 0.X" (which I added, to identify
the sub-version of 3.4.6 on MVS (note that for 3.2.3 I am
up to MVS 7.6 there's been so much activity).  And basically
I don't want that GCOV header file to change between
MVS releases.  Anyway, in the build scripts (ie outside the
normal configure/make process, so no-one needs to see it)
I just overwrite the header, and I didn't notice any ill-effect.


gengtype-yacc.c & .h gets created with my new version of bison.
I just want to use the one that came with 3.4.6 instead of
having it regenerated.  Do I need to hide my bison to stop
that from happening?


Well, it's just a make step -- the files will get rebuilt if
and only if the gengtype-yacc.y file is more recent than the
gengtype-yacc.c and .h files.  In the default 3.4.6 tarball
this is not the case.  Did you somehow modify file timestamps
while unpacking / copying the files?


Yes, I imported everything into CVS and that presumably changed
all the timestamps.  I wasn't aware of that.  Anyway, I got around
that problem by making dummy changes to the .c and .h and
then reversing them out.  So that is fixed now, thanks.


gencheck.h is being generated as an empty file, which doesn't
work well on some environments.  I want it to at least have a
comment saying "/* empty file */".  I can put that in as part of
the build script too.


Well, adding a comment should be trivial at the place in the
Makefile.in where gencheck.h is generated (s-gencheck).


Ok, I decided it was better to keep it outside the common files.


In any case, more recent GCC versions no longer refer to this
file at all.


And I don't even need to revisit that decision for GCC 4 it seems.  :-)

So I've basically finished doing what I wanted for 3.4.6 now.  I'm
not going to spend time doing niceties like putting the generated
files generation onto MVS so that mainframe users can upgrade
the machine definition without needing a non-MVS machine.  I
have that nicety already for 3.2.3 and I may look into it again
for 4.x.

There's still one last thing for 3.4.6, although it's not really 3.4.6,
I'm doing it for 3.2.3, but will have to incorporate that change into
3.4.6.  And that thing is the MUSIC/SP port.  I have managed to
get dynamic allocation to work, which changes the whole look
of the port, so I'm working through that, which I expect will take
a couple of weeks.  So that will be 3 nicely-working EBCDIC
platforms.  4 if you count USS, but I don't use or test that, so
don't know whether it works there currently.

I should be starting the GCC 4 port in a matter of days, while
using my Unix machine.

Thanks everyone for helping get it to this point.

BFN.  Paul.



Re: i370 port - constructing compile script

2009-11-18 Thread Paul Edwards

Ok, I've now reached a new milestone - the mshort.h which
redefines all the long names into ZZZ_123 etc is now 
automatically generated as part of the build process.


The libiberty and gcc aren't split yet, but I'll probably defer
that to gcc 4, and see if I can simply reproduce what I have
with 3.4.6 first.

But there are some things I want to change in the 3.4.6
before starting that.

There are some files that are being automatically generated
as part of the build process, which I would like to stop.

gcov-iov creates a gcov-iov.h which has a version number
which changes when I change MVS versions.  So I am
thinking of updating gcov-iov.c so that when the target is
MVS, it generates a more fixed format.  Or maybe as part
of the build process I can just put in a
#define GCOV_VERSION 0
Not sure if it's actually being used for anything in my
environment.

gengtype-yacc.c & .h gets created with my new version of bison.
I just want to use the one that came with 3.4.6 instead of
having it regenerated.  Do I need to hide my bison to stop
that from happening?

configargs.h I will just overwrite with something simple as part
of the build process.

gencheck.h is being generated as an empty file, which doesn't
work well on some environments.  I want it to at least have a
comment saying "/* empty file */".  I can put that in as part of
the build script too.

Basically I'm looking for consistent source that won't change
with my build environment.

The raw "MVS source" can then be taken to another environment
to be compiled.

Thanks.  Paul.



Re: i370 port - finally building

2009-11-15 Thread Paul Edwards

I have wonderful news to report.

I am finally able to build GCC 3.4.6 for MVS using the normal
build process.

There is still a lot of extra i370-specific utilities to e.g. generate
compile JCL, but these are completely separate scripts so not
intrusive at all.

Here's all the changes I have made to 3.4.6, including the
extra i370 stuff, and including the generated files like insn-*.c.

http://rapidshare.com/files/307362433/gccnew-beta72.zip

And here's the file of more interest - much smaller:

http://rapidshare.com/files/307366004/gcc-change.zip

that contains just the changes to common files.  There are 78
files in total that have been changed.  Almost all of the changes
are quite small.

I am now in a strong position to do 2 things:

1. Experiment with changes to the build procedure, because I can
easily check that the whole thing still works (it takes 2 hours to do
an end-to-end test, so I see the results in the morning etc).

2. Replicate the same thing on GCC 4.

I'll work on number 1 first, as I haven't put the external name remapping
into the suggested place yet.  And I haven't incorporated that (external)
remap-generation into the build process either.

Hopefully by the time I've finished that, someone can suggest precisely
what autoconfigure changes would be best for (2), thinking especially
of a config-by-prototype option.

BFN.  Paul.



Re: i370 port - constructing compile script

2009-11-14 Thread Paul Edwards

LIBOBJS includes a strcasecmp.s$U.s

That suffix is certainly strange-looking though.  I checked in
config.log and I can see that it automatically detected that
my "object code" has a ".s" extension, which is basically
correct given that I forced the "-S" option.


Why do you pass -S in the compiler script?  configure sort of expects
that neither -S nor -c are passed automatically.


The only thing the compiler is capable of doing is generating
assembler code.  Just getting that to work has been a 20
year effort.

So what I have done is get the compiler to fail on any missing
prototype.  I think perhaps we need to have a generic gcc or
autoconfigure option called "config by prototype".  MVS is just
one instance where you might wish to do it this way.  Other
ports in their infancy may not have working cross-assemblers
and linkers either.  It worked out quite well.


that strncmp does not work.  It uses the cache variable
ac_cv_func_strncmp_works, which you can set if you need to override the
decision, e.g.:
 ac_cv_func_strncmp_works=yes
 export ac_cv_func_strncmp_works


Ok, thanks, I've added that, and can confirm that it did the
trick.


A more permanent solution would be to set this correctly based upon
$host in libiberty/configure.ac and regenerate libiberty/configure with
autoconf.


Ok, that's what a lot of this exercise is about - finding out what
needs to be changed in the long term in GCC 4 if MVS is to be
supported.


And then I changed ac_libobjs to stop putting that $U in there as
well, and I finally got my strcasecmp.


Why does that $U hurt you?  It should get expanded to nothing later on.
(It is a remainder from some ansi2knr scheme.)


Ok, I put it back in, and indeed, it does work.  I must have been
confused by an unrelated failure.


Note that I also seem to be getting strerror.  It's on the list
of "required files", even though it isn't required or wanted.
configure correctly detected that I already had strerror.
I manually excluded that from my list of files and now things
are looking good again - including strcasecmp being
automatically selected in the build process.  :-)


Again, rather than hacking the generated configure script, I think you
should start modifying the input files, configure.ac in this case, for
permanent solutions to your build issues.  


As above, that is certainly on the cards.  However, I'm trying
to flesh out the issues that exist before seeing if we can get
agreement for changes in GCC 4.  E.g. what do you think of
the generic "configure by prototype rather than link" facility?
Personally I'd like a "configure by standard" option, where
autoconfigure knows what to do based on me just telling it
that the compiler is C90 (or C99 as another option) compliant,
so that I don't even need to provide headers.  But I think the
header file option is also useful, so both should be selectable.


Even if you're only changing
a few lines, doing it each time you want to build a different GCC
version is an unnecessary burden.


Man, I really wish that was even 1% of the issues that needed to be
sorted out going from GCC 3.4.6 to GCC 4.x.  :-)  I'd be happy to do
it for the rest of my life.  :-)  While the amount of intrusive code is
relatively small, it's still quite widespread.  ie more than 80 files.
And that's just the intrusive code.  There's all the separate port
files that need to be taken care of.  :-)  There's a good reason it took
20 years to get to this point.  :-)

BFN.  Paul.



Re: i370 port - constructing compile script

2009-11-14 Thread Paul Edwards

Well, the configure process should result in the variable LIBOBJS
in the generated libiberty Makefile to be set to list of objects
containing implementations of replacement system routines.

So if you do not have HAVE_STRCASECMP in config.h, you should
have been getting strcasecmp.o in LIBOBJS ...


And indeed, I sort of am.

LIBOBJS includes a strcasecmp.s$U.s

That suffix is certainly strange-looking though.  I checked in
config.log and I can see that it automatically detected that
my "object code" has a ".s" extension, which is basically
correct given that I forced the "-S" option.

All of the LIBOBJS are like that.

In addition, there's another problem - it has included strncmp
in the list.  I had a look and it appears that it attempts to
actually run the program to see if strncmp works.  That's
not going to work in a cross-compile environment though.
So maybe it assumes the worst.

I've taken a look at the Makefile to try to find out what is
happening.  It seems that there are REQUIRED_OFILES
which include things like safe-ctype and that has to have
a ".o" extension.  Give that those are hardcoded and
forced to ".o", why isn't LIBOBJS done the same way?

Anyway, I decided to change this:

else
 LIBOBJS="$LIBOBJS $ac_func.$ac_objext"
fi

code you showed earlier to be hardcoded to .o.

And then I changed ac_libobjs to stop putting that $U in 
there as well, and I finally got my strcasecmp.


Note that I also seem to be getting strerror.  It's on the list
of "required files", even though it isn't required or wanted.
configure correctly detected that I already had strerror.
I manually excluded that from my list of files and now things
are looking good again - including strcasecmp being
automatically selected in the build process.  :-)

Hopefully it won't be too much longer before I have the stage 1
JCL being automatically generated so that I can verify the
new files to be compiled actually work on MVS.  :-)

BFN.  Paul.



Re: i370 port - constructing compile script

2009-11-13 Thread Paul Edwards

Next, a stack of libiberty files were not compiled - strcasecmp,
vasprintf, asprintf, getpagesize, strdup.  I don't know why this
would be the case, because e.g. HAVE_STRCASECMP is
not defined.  Anyway, I added them to the source list manually,
and with a script, awk and m4, I was able to produce my
traditional compile script (which is a stepping stone for doing
the same thing on MVS).


The libiberty configure process attempts to detect which functions
need to be built via link tests by default.  As you don't have a
cross-linker, something may be going wrong here.  As an alternative,
you can hard-code which functions to use in libiberty's configure.ac.


The thing is, I already know it has detected that I don't have
strcasecmp.  That's why it doesn't have HAVE_STRCASECMP
defined in the config.h.  You are right that I don't have a linker,
but the compile with error-on-no-prototype is working fine - I
can see the result in config.h.


Oh, one other change I made - I normally define PREFIX in a
common header file.  However, this caused a conflict between
prefix.c and regex.c which both try to use this keyword.  It
would be good if this define was made unique within the
source base.  I realise there are different ways around this,
but it would still be good to be unique.  For now I just updated
prefix.c to use "" as a default prefix if none is provided.  That's
neater than any immediate alternative I can think of.


Why would you define this by hand?  The usual make process will
define PREFIX while building prefix.c, using the appropriate
value determined at configure time ...


Because when my assemble and compile jobs start running on
MVS, I would first of all need to put in a special define for that
in the compile step for prefix - the only exception in fact.  Secondly,
I am running close to the 100-character limit of the PARM
statement already, with the things I was forced to add:

//ST2CMP   PROC GCCPREF='GCC',MEMBER='',
// PDPPREF='PDPCLIB',
// COS1='-Os -S -ansi -pedantic-errors -remap -DHAVE_CONFIG_H',
// COS2='-DIN_GCC -DPUREISO -o dd:out -'

Having another define, just to define an empty string, seems very
ugly indeed, even assuming it comes in under 100 characters.

By the way - that previous discussion we had about the potential
for the MVS version to one day be able to do a system().  Even
if it works for MVS eventually, which it probably will, it won't
work for MUSIC/SP in batch.  It's tragic, because I wanted to
use exactly that to issue a "/file" for dynamic file allocation
similar to how the CMS port does.  I only have one other
option - maybe the DYNALLOC call will work under MUSIC/SP,
which would be nicer than doing a "/file" anyway.  I will be trying
that in the days ahead, but regardless, I need gcc to be a
single executable on that environment if I want to run in batch.
And yes, I want to run my compiles in batch!  :-)

BFN.  Paul.



Re: i370 port - constructing compile script

2009-11-13 Thread Paul Edwards

Ok, now I have some results from the auto-compile-script-generation.

I got it to work, but it required some manual corrections.

First of all, I got link errors, because sched-ebb etc were trying
to call various functions, but those functions were not being
compiled in because INSN_SCHEDULING was not defined
(that's my quick analysis, anyway).  So I just grepped those
files out of the "source list".

Next, a stack of libiberty files were not compiled - strcasecmp,
vasprintf, asprintf, getpagesize, strdup.  I don't know why this
would be the case, because e.g. HAVE_STRCASECMP is
not defined.  Anyway, I added them to the source list manually,
and with a script, awk and m4, I was able to produce my
traditional compile script (which is a stepping stone for doing
the same thing on MVS).

Oh, one other change I made - I normally define PREFIX in a
common header file.  However, this caused a conflict between
prefix.c and regex.c which both try to use this keyword.  It
would be good if this define was made unique within the
source base.  I realise there are different ways around this,
but it would still be good to be unique.  For now I just updated
prefix.c to use "" as a default prefix if none is provided.  That's
neater than any immediate alternative I can think of.

But anyway, the short story is that things are looking great,
and it is looking like I have managed to slot into the existing
build process with fairly minimal intrusive code, which bodes
well for a future GCC 4 port attempt.  :-)  The remaining work
I know of doesn't require any more intrusive code.

BFN.  Paul.



Re: i370 port - constructing compile script

2009-11-12 Thread Paul Edwards

* Paul Edwards wrote on Thu, Nov 12, 2009 at 03:02:59PM CET:

Well, I have good news to report.  The restructuring was a success.

That means with those 30-odd changes to the configure scripts, I
was able to get an auto-host.h built that allowed me to take the
generated source and compile it with my own scripts as per
normal.


It would be a good idea if you took the extra mile and reported all
these changes to the bug-autoconf mailing list, so it could be fixed
for good there.


I was under the impression that the root cause was a problem
with configure.ac in gcc rather than autoconf.  However, I took
a look at that file, and I can only see a couple of references
to sys/types.h, none of which look the same as the sort of
thing I needed to change.

 /* end confdefs.h.  */
 #include 
 #include 
+ #if !defined(__MVS__)
 #include 
 #include 
+ #endif

 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
+ #if !defined(__MVS__)
 #include 
+ #endif


Furthermore, it would be really good if we could get Autoconf to build
and run on your system, so you could run its test suite there.  That
would provide much better coverage of all the issues that would need
fixing, and allow us to fix them once in the macros, instead of having
you do this repeatedly in every configure script.


I am running on a Linux box!  The thing I am doing that is unusual
is two things:

1. Only providing C90 headers when cross-building a host.  That
means that things like sys/types are failing.

2. No linking is done, because I don't have a cross-linker.

As far as I can tell, peculiarity number 2 has not caused the need
for any changes, with the possible exception of ones like this:

+ #if !defined(__MVS__)
 #include 
 #include 
+ #endif
+ #if defined(__MVS__)
+ #define BIG_ENDIAN 1
+ #define LITTLE_ENDIAN 2
+ #define BYTE_ORDER 1
+ #endif

I'm not sure what that one was all about, and I'm not sure the
result of it is even used.

Note that peculiarity 2 ideally requires prototypes for all
functions, so there were a couple of other changes made to the
gcc 3.4.6 code, such as this one:

 #ifdef HAVE_SYS_RESOURCE_H
 #include 
 #endif
! #if defined (HAVE_DECL_GETRUSAGE) && !HAVE_DECL_GETRUSAGE
 extern int getrusage (int, struct rusage *);
 #endif

--- 86,100 
 #include "prefix.h"
 #include "gcc.h"
 #include "flags.h"

 #ifdef HAVE_SYS_RESOURCE_H
 #include 
 #endif
! #if defined (HAVE_GETRUSAGE) && !HAVE_DECL_GETRUSAGE
 extern int getrusage (int, struct rusage *);
 #endif

Anyway, all of this should be reproducible building any ASCII
target on any ASCII machine, just by using a C90 set of head
files and a dummy compile script like this:

C:\devel\gccnew\gcc\config\i370>type i370-mvspdp-gcc
echo $* >>/tmp/build.txt
i370-mvspdp-xxx -Werror-implicit-function-declaration -DPUREISO -S -I 
/devel/mvshead/usr/include $*


Note the '-S' which could be '-c' instead and the -W.


However, Autoconf requires Perl and GNU M4 (and some shell environment
as well as a make program), so I'm not sure whether it is possible to
get to this point.


Those are all available on the build machine, even though, out of those,
only m4 is available on the host.  :-)

BFN.  Paul.



Re: i370 port - constructing compile script

2009-11-12 Thread Paul Edwards

Well, I have good news to report.  The restructuring was a success.

That means with those 30-odd changes to the configure scripts, I
was able to get an auto-host.h built that allowed me to take the
generated source and compile it with my own scripts as per
normal.

There's still a stack more work to do of course, such as reversing
out the ansidecl.h change, which is pretty horrible:

#ifdef PUREISO
#include "../gcc/unixio.h"
#include "../gcc/config/i370/mvspdp.h"
#endif

I needed to put in the relative path to allow compilation.

However, now I would like to know:

1. I think my unixio.h, which has a stack of POSIX functions
that need to be there (mkdir, pwait, open, fileno etc), needs to
be considered "honorary ansi" (after all, so much code assumes
that they exist) and get included in ansidecl, with unixio.h
living in include, and unixio.c living in libiberty.  Does that
sound reasonable?

2. A 3rd EBCDIC port has recently been achieved - MUSIC/SP.
As part of doing that port I ran into an old problem - IFOX's
399 external limitation.  On MVS and CMS we had people who
knew how to modify IFOX.  On MUSIC, we don't.  I have a code
workaround:

#define flag_test_coverage gflags[0]
#define flag_branch_probabilities gflags[1]
#define flag_reorder_blocks gflags[2]
#define flag_reorder_functions gflags[3]
#define flag_rename_registers gflags[4]
#define flag_force_mem gflags[5]
#define flag_force_addr gflags[6]
#define flag_defer_pop gflags[7]
#define flag_float_store gflags[8]
#define flag_strength_reduce gflags[9]

etc

What would be really good is if flags.h and toplev.c had a 
consecutive block of flags, so that even if my few lines of

intrusive code aren't accepted, it's at least easy for me to
mask out an entire block.  At the moment I have to look
for a few largish chunks of flags to mask out.

I'm not sure how many I need to mask out in total.  I'll be
experimenting with that in the coming days on one computer,
while on the other computer I will be getting the compile
scripts auto-generated from the file list.  I haven't tried
linking with the auto-generated file list yet.  I know that
it is a bit different from my list (by something like 10 files),
but haven't yet determined if it is functional anyway.

I'll come back to making the configure changes more
streamlined after the rest of the stuff is working.

BTW, with MUSIC/SP done, VSE is the only currently-used
EBCDIC programming environment without a GCC port, and
in fact, probably the only computer system (definition:
has assembler, has editor, has programmers who use that
editor, commercially-used) in existence without a free C 
compiler (and thus, to me, preventing C from being a truly
universal language for computers).  And there's only about 
1000 lines of assembler in the way of that happening.  
Unfortunately it's the same 1000 lines we've been waiting for 
several years for.  :-)  But I will be concentrating on making

the MUSIC/SP port look nicer first.  If I can get DYNALLOC
working for output datasets, it should be fine.  Otherwise,
the workaround for that problem is pretty horrible.  :-)

Anyway, thanks guys for your help.  I'll post the code after
I've cleaned it up further.

BFN.  Paul.



Re: i370 port

2009-11-10 Thread Paul Edwards

There are a couple of places where I need to do something different
if I'm running on an EBCDIC host (e.g. MVS, CMS, MUSIC, VSE).

So in mvspdp.h I have put:

/* If running on MVS, need some EBCDIC-related differences */
#if defined(__MVS__) || defined(__CMS__)
#define HOST_EBCDIC 1
#endif

and c-parse.c:

#ifdef HOST_EBCDIC
#define YYTRANSLATE(YYX)  \
 ((unsigned int) (YYX) <= YYMAXUTOK ? \
 ((unsigned int) (YYX) < 256 ? yytranslate[_sch_ebcasc[YYX]] \
 : yytranslate[YYX]) : YYUNDEFTOK)
#else
#define YYTRANSLATE(YYX) ^I^I^I^I^I^I\
 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
#endif

and opts.c:

#ifdef HOST_EBCDIC
static size_t
find_opt (const char *input, int lang_mask)
{
/* sequential search */


Is that a reasonable way to do it?

I think I should probably make the opts.c into a PUREISO so that
the sequential search is always used (ie work on an arbitrary C90
platform, not necessarily ASCII or EBCDIC).

But the c-parse one is definitely a translation that will only work
on EBCDIC.  That is useful so that I don't need to have a working
bison.  Similarly, the opts.c change doesn't require a working
shell!


I think I would stop right there.  Why can't the i370 port support
64-bit integers?  Plenty of 32-bit hosts support them.


It got an internal error.  I don't have the skills to get that to work,
but I do have the skills to bypass it one way or another (and I
demonstrated what I am doing now, but I know that that
intrusive code will break everything else, so want to back it out,
without losing the functionality that I want).


That said, these days gcc always defines __SIZEOF_LONG_LONG__.  It
would be perfectly reasonable for hwint.h to test that.  Maybe
something along the lines of

#if !defined HAVE_LONG_LONG
# if GCC_VERSION >= 3000
#  ifdef __SIZEOF_LONG_LONG__
#define HAVE_LONG_LONG 1
#define SIZEOF_LONGLONG __SIZEOF_LONG_LONG__
#  else
#   define HAVE_LONG_LONG 1
#   define SIZEOF_LONG_LONG 8


These both switch long_long on.  I want to switch it off (which it was
already).


extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
#  endif
# endif
#endif


So would defining a new option be a reasonable solution for any
target that wants to limit code generation for whatever reason?

Thanks.  Paul.



Re: i370 port

2009-11-10 Thread Paul Edwards

I can see that ansidecl.h is a tempting place to put this, but I don't
think it is correct.  ansidecl.h is used by many different programs,
including the GNU binutils and gdb.  Changes that are specific to gcc
should be in gcc, probably in gcc/system.h.  Changes specific to
libiberty should be in libiberty, probably in include/libiberty.h.


Another "where" question.  The i370 port can't cope with 64-bit
integers.  The below bit keeps on defining it.  So I created a
WANT64 which obviously is never going to be set.

I've just updated config/i370/mvspdp.h to define
USE_C_ALLOCA
because the i370 also doesn't have this builtin.  I was wondering
if I could define another variable, USE_ONLY32, to achieve the
same thing for the 64-bit integers.

PUREISO (I'll change it to C90 later when everything is working)
is not always going to be true for the pdp port.  By default, someone
extracting the modified 3.4.6 code will in fact get a non-C90 build
and it will have the traditional separate gcc, cc1 etc modules.  So
I can't use that.

So - is USE_ONLY32 the way to go or is there another method?

Thanks.  Paul.




C:\devel\gccnew\gcc>cvs diff -c hwint.h
Index: hwint.h
===
RCS file: c:\cvsroot/gccnew/gcc/hwint.h,v
retrieving revision 1.2
diff -c -r1.2 hwint.h
*** hwint.h 24 Apr 2009 14:27:58 -  1.2
--- hwint.h 10 Nov 2009 13:38:16 -
***
*** 22,28 
but they're all cross-compile-only.)  Just in case, force a
constraint violation if that assumption is incorrect.  */
 #if !defined HAVE_LONG_LONG
! # if GCC_VERSION >= 3000 && !PUREISO
 #  define HAVE_LONG_LONG 1
 #  define SIZEOF_LONG_LONG 8
 extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
--- 22,28 
but they're all cross-compile-only.)  Just in case, force a
constraint violation if that assumption is incorrect.  */
 #if !defined HAVE_LONG_LONG
! # if GCC_VERSION >= 3000 && !PUREISO && defined(WANT64)
 #  define HAVE_LONG_LONG 1
 #  define SIZEOF_LONG_LONG 8
 extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];





Re: i370 port

2009-11-09 Thread Paul Edwards

Now all code needs to be exposed to this.  ie libiberty and
gcc.  To fit in with the new style of building, I basically want
to update ansidecl.h to do a:

#ifdef PUREISO
#include "mshort.h"
#endif

Does that seem reasonable?


The ISO C99 standard requires that an identifier have 31 significant
initial characters, so PUREISO does not seem like the right name here.


Ok.  I was under the impression that C99 was rarely fully
implemented, and far from universal, thus pretty irrelevant.


Based on your suggested #define's, your system seems even more
restrictive than ISO C99 requires.  I vaguely recall that ISO C90
requires 6 significant initial characters, so something like


Yep, externals need to be unique in the first 6 characters, and
with case ignored.  My system requires 8, and ignores case.


PURE_ISO_C90 might be right here.


Ok.


I can see that ansidecl.h is a tempting place to put this, but I don't
think it is correct.  ansidecl.h is used by many different programs,
including the GNU binutils and gdb.


Ok, but it's a non-default option, so would have no effect on those.


Changes that are specific to gcc
should be in gcc, probably in gcc/system.h.  Changes specific to
libiberty should be in libiberty, probably in include/libiberty.h.


I can give it a go, but I'm not sure they kick in early enough.  I
even had to move the ansidecl in cplus-dem.c up to get it to
take effect soon enough.

But in principle, separating the remaps for libiberty and gcc into
two different files sounds like the correct thing to be doing, so
I'll see if I can get that to work.  Needs a bit more infrastructure
to be written though.  :-)

BFN.  Paul.



Re: i370 port

2009-11-09 Thread Paul Edwards

Still making great progress.

The process is being simplified.

I have a question.  I need to remap long names to short, and I
wish to use #defines to do this as it is portable.

So I have a whole lot of:

#define align_functions ZZZ_1
#define align_functions_log ZZZ_2

etc

and I have put them all into an mshort.h for convenience.

Now all code needs to be exposed to this.  ie libiberty and
gcc.  To fit in with the new style of building, I basically want
to update ansidecl.h to do a:

#ifdef PUREISO
#include "mshort.h"
#endif

Does that seem reasonable?

Actually I also need to #include "unixio.h" to include various
types that must be present, st_ino or whatever too.

I may have other miscellaneous defines as well.  I'm still in
the process of unwinding all the hacks I put in years ago.  :-)

Thanks.  Paul.



Re: i370 port

2009-11-03 Thread Paul Edwards

C:\devel\gccnew\gcc>gccmvs -DUSE_MEMMGR -Os -S -ansi -pedantic-errors -DHAVE_CON
FIG_H -DIN_GCC -DPUREISO -I ../../pdos/pdpclib -I . -I config/i370 -I
../include
 varasm.c
(insn 117 429 118 7 (parallel [
(set (reg:SI 64)
(compare:SI (mem/s:BLK (plus:SI (reg/f:SI 21
virtual-stack-vars)

(const_int 456 [0x1c8])) [232 value+0 S196 
A64])

(mem:BLK (plus:SI (reg/v/f:SI 61 [ desc ])
(const_int 8 [0x8])) [0 A8])))
(use (const_int 196 [0xc4]))
]) -1 (nil)
(nil))
varasm.c: In function `force_const_mem':
varasm.c:3021: internal compiler error: in 
instantiate_virtual_regs_lossage,

at function.c:3767


OK, so what goes on here is that GCC attempts to replace the "virtual"
register 21 (virtual-stack-vars) with some real register, that is
frame pointer + STARTING_FRAME_OFFSET.  It seems for the i370 port,
this should resolve to
 register 13 + STACK_POINTER_OFFSET + current_function_outgoing_args_size

Overall, the middle-end would therefore replace "reg 21 + 456" with
"reg 13 + X", where X is constant computed from 456 + STACK_POINTER_OFFSET
+ current_function_outgoing_args_size.

It will then re-process the insn pattern constraints to verify that the
resulting insn is still valid.  At this stage, it appears we're running
into the above error.  I'm not quite sure why this would be case, this
will require some further debugging why the insn was not recognized ...


This mystery is finally solved.

The previous workaround I had in place failed when I tried to do an
unoptimized compile of varasm.c.  I found this out when I tried speeding
up the experimental configure/make process.  However, since it was
occurring with unoptimized compiles, I thought it would be easier to
track down, and indeed, I found out that the memcmp was only
failing for values 128 and above. 127 was working fine.  That made me
suspect a signed char vs unsigned char problem.

And it's the "QI" below that was causing the grief ...

*** 699,711 
 {
   op2 = gen_rtx_MEM (BLKmode, copy_to_mode_reg (SImode, op2));
 }
!
!   /* one circumstance has been found where this short comparison
!  causes an internal error. Could be related to the fact that
!  both displacements were non-zero, which is unusual. So check
!  for that */
!   if (((iv1 == 0) || (iv2 == 0)) &&
!   GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256)
 {
   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
   gen_rtx_SET (VOIDmode, operands[0],
--- 697,705 
 {
   op2 = gen_rtx_MEM (BLKmode, copy_to_mode_reg (SImode, op2));
 }
!
!   if (GET_CODE (operands[3]) == CONST_INT
!   && (unsigned)INTVAL (operands[3]) < 256)
 {
   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
   gen_rtx_SET (VOIDmode, operands[0],
***
*** 747,753 
   [(set (match_operand:SI 0 "register_operand" "=d")
   (compare:SI (match_operand:BLK 1 "s_operand" "m")
(match_operand:BLK 2 "s_operand" "m")))
!(use (match_operand:QI 3 "immediate_operand" "I"))]
   "((unsigned) INTVAL (operands[3]) < 256)"
   "*
 {
--- 741,747 
   [(set (match_operand:SI 0 "register_operand" "=d")
   (compare:SI (match_operand:BLK 1 "s_operand" "m")
(match_operand:BLK 2 "s_operand" "m")))
!(use (match_operand:SI 3 "immediate_operand" "I"))]
   "((unsigned) INTVAL (operands[3]) < 256)"
   "*
 {

The QI must be a signed char, and thus rejecting any value greater than 127.
As you can see, I changed it to SI, which, with the constraints and tests
in place, should be fine.

Just to be sure, I did a before and after comparison of the generated
assembler for all of GCC (3.4.6) and it all checked out fine.  :-)

BFN.  Paul.



Re: i370 port - constructing compile script

2009-11-02 Thread Paul Edwards

I've been having fantastic success building gcc.  I have got it
to iterate through the entire build (as far as I can tell) now.


Then finally I ran into an internal compiler error which I haven't seen
before.  One of the gcc options must have triggered something off.
Perhaps it was -Wwrite-strings, or maybe the -O2 (I normally use
-Os for a completely unrelated reason).  Either way, I need to find
out how to switch off those flags.  I'll also try to fix the compiler
internal error in i370.md.


This problem was due to the build being done with 64-bit
long long enabled - something i370.md can't cope with.

I forced it off with these two things:

configure:
 main ()
 {
! long long int i;
   ;
   return 0;
 }
--- 3196,3202 
 int
 main ()
 {
! zlong long int i;


hwint.h:
 #if !defined HAVE_LONG_LONG
! # if GCC_VERSION >= 3000 && !PUREISO && defined(WANT64)
 #  define HAVE_LONG_LONG 1
 #  define SIZEOF_LONG_LONG 8


Now at the end of the build, I can save the output, and do a
grep "^i370-mvspdp-gcc" to get all the source files that need to be
compiled.  I could attempt to use the .o files (that are really .s)
directly, but that's not something I really need.

The auto-host.h looks fine, plus I have the generated files.

I still need to clean up the scripts further (the below is a work in
progress), and I need to write the programs that will generate the
compile JCL and then try it out!

Part of the cleanup will hopefully get around the multiple make failures ...

+ make
+ cp gcc/config/i370/dummy_config.h gcc/config.h
+ make
+ cp gcc/config/i370/i370-mvspdp-gcc2 ../mvscross/bin/i370-mvspdp-gcc
+ make

:-)

BFN.  Paul.


Index: gccnew/gcc/configure
diff -c gccnew/gcc/configure:1.1.1.1 gccnew/gcc/configure:1.12
*** gccnew/gcc/configure:1.1.1.1 Thu Jul  9 10:25:05 2009
--- gccnew/gcc/configure Fri Oct 30 12:34:44 2009
***
*** 2463,2470 
--- 2463,2472 
 /* end confdefs.h.  */
 #include 
 #include 
+ #if !defined(__MVS__)
 #include 
 #include 
+ #endif
 /* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
 struct buf { int x; };
 FILE * (*rcsopen) (struct buf *, struct stat *, int);
***
*** 3194,3200 
 int
 main ()
 {
! long long int i;
   ;
   return 0;
 }
--- 3196,3202 
 int
 main ()
 {
! zlong long int i;
   ;
   return 0;
 }
***
*** 3377,3383 
--- 3379,3387 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
+ #if !defined(__MVS__)
 #include 
+ #endif


 int
***
*** 3448,3454 
--- 3452,3460 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
+ #if !defined(__MVS__)
 #include 
+ #endif


 int
***
*** 3519,3525 
--- 3525,3533 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
+ #if !defined(__MVS__)
 #include 
+ #endif


 int
***
*** 3590,3596 
--- 3598,3606 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
+ #if !defined(__MVS__)
 #include 
+ #endif


 int
***
*** 3662,3668 
--- 3672,3680 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
+ #if !defined(__MVS__)
 #include 
+ #endif


 int
***
*** 3735,3741 
--- 3747,3755 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
+ #if !defined(__MVS__)
 #include 
+ #endif


 int
***
*** 5656,5662 
--- 5670,5678 
 if test $ac_cv_header_time = yes; then

 cat >>confdefs.h <<\_ACEOF
+ #if !defined(__MVS__)
 #define TIME_WITH_SYS_TIME 1
+ #endif
 _ACEOF

 fi
***
*** 6150,6157 
--- 6166,6180 
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
+ #if !defined(__MVS__)
 #include 
 #include 
+ #endif
+ #if defined(__MVS__)
+ #define BIG_ENDIAN 1
+ #define LITTLE_ENDIAN 2
+ #define BYTE_ORDER 1
+ #endif
 int
 main ()
 {
***
*** 6192,6199 
--- 6215,6229 
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
+ #if !defined(__MVS__)
 #include 
 #include 
+ #endif
+ #if defined(__MVS__)
+ #define BIG_ENDIAN 1
+ #define LITTLE_ENDIAN 2
+ #define BYTE_ORDER 1
+ #endif
 int
 main ()
 {
***
*** 6731,6738 
--- 6761,6770 
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
+ #if !defined(__MVS__)
 #include 
 #include 
+ #endif
 int
 main ()
 {
***
*** 6851,6857 
--- 6883,6891 
 #endif
 /* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply.  */
+ #if !defined(__MVS__)
 char $ac_func ();
+ #endif
 /* The GNU C library defines this for functions which it implements
 to always fail with ENOSYS.  Some functions are actually named
 something starting with __ and the normal name is an alias.  */
***
*** 7051,7057 
--- 7085,7093

Re: i370 port - constructing compile script

2009-10-27 Thread Paul Edwards

This means that if your GCC source tree resides in a directory, say,
 ~/gcc-src
you should *not* run ./configure while in ~/gcc-src.  Instead, you
should create a second, empty directory
 ~/gcc-build
(which is not a subdirectory of ~/gcc-src), and run
 ../gcc-src/configure ...
while in ~/gcc-build.


Ok, I tried that, and it still didn't fix the problem.  Not only that, after
I fixed the problem (below), I ended up getting an error that way.
input.h not found or something like that.  So I went back to the
source tree build, and made quite a lot of progress.

First of all, the problem was obvious in hindsight.  I had commented
out a whole lot of stuff in configure in order to stop things from being
auto-detected.  However, that was interfering with the configure for
the build environment!!!

So I put #if !defined(__MVS__) around everything that I was commenting
out, and I was able to get past genmodes and on to the next error.

The next error was that it was trying to use ino_t in a header file, which
doesn't exist.  The way I got around this using my own procedure was
to create a unixio.h which has the various Posix stuff in it.  E.g. I have
an open() that calls fopen().  ino_t is one of the typedefs there.

Anyway, I put a #include "unixio.h" into config.h and got past that
problem.  I don't think that was the right thing to do though, because
that is a generated file.  What should I have done instead?

A #include of "config/i370/mvspdp.h" got around the next problem,
and I think I need to do more investigation as to why that was needed.

Then finally I ran into an internal compiler error which I haven't seen
before.  One of the gcc options must have triggered something off.
Perhaps it was -Wwrite-strings, or maybe the -O2 (I normally use
-Os for a completely unrelated reason).  Either way, I need to find
out how to switch off those flags.  I'll also try to fix the compiler
internal error in i370.md.

BFN.  Paul.



Re: i370 port - constructing compile script

2009-10-23 Thread Paul Edwards

If you use --disable-nls on the configure line, the intl directory
should be skipped ...


Ok, that's working.


The next thing I hit was that genmodes didn't compile because
there were conflicts between the strsignal function in the
Linux include files and the system.h.  Looking at the system.h,
it was including things in because it thought that the prototypes
didn't exist.  Which would have been true for the cross-compiler,
but isn't true for a native gcc.  How are those two different things
meant to be reconciled?


Before including "system.h", generator files include "bconfig.h"
where core compiler files include "config.h".  The former then
in turn includes "auto-build.h", while the latter includes
"auto-host.h".


And this much is fine.


These contain the configure results for the
--build= and --host= systems, respectively.


However, the auto-build.h is not detecting the all the includes etc.
So while auto-host.h has a #define HAVE_DECL_CALLOC 1, the
auto-build.h has it as 0.

There's nothing in config.log showing a CALLOC of 0.  So where
can I find out what's setting this?


All this should work automatically if you use the proper
configure options, so something odd must be going on ...


Yeah, I've probably changed something when making all the
additions to get my new target and that is now interfering.
Something similar to that dummy pwait.  Now I've got to find
it and reverse it (or mask it out).


Are you running the top-level configure?  (If you run a
subdirectory configure, e.g. the one in gcc/, directly,
things may not work correctly.)


Yes I am.

One other thing I did - I compiled the cross-compiler, and installed it.

Then I wiped out the directory and extracted a fresh version and did
the configure for building the host.  I thought that would make things
clean.  But maybe the previous build had the correct auto-build.h
that I need, and without it I get some sort of dummy auto-build.h?

BFN.  Paul.



Re: i370 port - constructing compile script

2009-10-23 Thread Paul Edwards

As to the pex-unix.c, you certainly should provide a MVS-specific
version of the PEX callbacks.  They are selected in configure.ac:

# Figure out which version of pexecute to use.
case "${host}" in
*-*-mingw* | *-*-winnt*)   pexecute=pex-win32.o  ;;
*-*-msdosdjgpp*)   pexecute=pex-djgpp.o  ;;
*-*-msdos*)pexecute=pex-msdos.o  ;;
*-*-os2-emx*)  pexecute=pex-os2.o;;
*) pexecute=pex-unix.o   ;;
esac

Your MVS version might be just a dummy that always fails.
Even better would be a version that actually works; in this
case all the "single-exectuable" hacks would become superfluous.

Note that e.g. pex-msdos.c implements the required callbacks
solely in terms of the C99 "system" routine.  If you at least
have this facility available on MVS, you might be able to just
use the msdos version?


I tried using the MSDOS version and it had non-C90 compile
errors.  But provding a dummy pex-mvs is fine.


Finally, even with this in place, the build process stopped at
the next roadblock.  The file "genmodes.c" couldn't be
compiled.  I was surprised to see that it was being compiled
with i370-mvspdp-gcc.  The genmodes "needs" to be run on
Unix still.  It's only the source code that IT generates that
needs to be cross-compiled.


If this happens, then something went very wrong during configure.
Did you make sure to use the proper build / host / target flags?
In particular, the --build= configure argument must be present
and refer to the build architecture.  This is used to determine
which architecture to build the generator programs for.


Ok, perhaps this error was because when I hit errors in intl,
which I've never used before, I just went to the gcc directory and
did a make.

Regardless, I added a stack of touch xxx.o in the intl directory
after the failure of the first make, which allowed me to do a second
make, and then it was satisfied with the intl directory and moved
on to the gcc directory, where it did in fact invoke the correct
gcc rather than the cross-compiler.

The next thing I hit was that genmodes didn't compile because
there were conflicts between the strsignal function in the
Linux include files and the system.h.  Looking at the system.h,
it was including things in because it thought that the prototypes
didn't exist.  Which would have been true for the cross-compiler,
but isn't true for a native gcc.  How are those two different things
meant to be reconciled?

Thanks.  Paul.



Re: i370 port - constructing compile script

2009-10-22 Thread Paul Edwards

Hi Ulrich.

I'll try out some of those things.  I have some initial
comments.


Hmmm, the access() use probably needs to be guarded by a configure
check.  Or else you might provide a MVS-specific implementation of
"access" (if that is possible), and compile it into libiberty by
providing an EXTRA_OFILES setting in a host makefile fragment;


Probably too many of them.  Just like open() etc in GCC main.
I'll see what can be faked up, now that I know those object files
are basically mandatory.


in 3.4 these are set in config.table:
case "${host}" in
 rs6000-ibm-aix3.1 | rs6000-ibm-aix)
   frag=mh-aix ;;
 *-*-cxux7*)   frag=mh-cxux7 ;;
 *-*-freebsd2.1.*) frag=mh-fbsd21 ;;
 *-*-freebsd2.2.[012]) frag=mh-fbsd21 ;;
 i370-*-opened*)   frag=mh-openedition ;;
 i[34567]86-*-windows*)frag=mh-windows ;;
esac

As to the pex-unix.c, you certainly should provide a MVS-specific
version of the PEX callbacks.  They are selected in configure.ac:

# Figure out which version of pexecute to use.
case "${host}" in
*-*-mingw* | *-*-winnt*)   pexecute=pex-win32.o  ;;
*-*-msdosdjgpp*)   pexecute=pex-djgpp.o  ;;
*-*-msdos*)pexecute=pex-msdos.o  ;;
*-*-os2-emx*)  pexecute=pex-os2.o;;
*) pexecute=pex-unix.o   ;;
esac


Ok, thanks.


Your MVS version might be just a dummy that always fails.


Ok.


Even better would be a version that actually works; in this
case all the "single-exectuable" hacks would become superfluous.


Having a single executable, especially in my environment where
only assembler code is ever generated, has its own merits even if
a working system() can be done in the future.


Note that e.g. pex-msdos.c implements the required callbacks
solely in terms of the C99 "system" routine.  If you at least
have this facility available on MVS, you might be able to just
use the msdos version?


I don't have a working system that can execute another C program
yet.  Note that C90 leaves the behaviour of system() as
"implementation defined".  Well, on my system, I can do a system()
to call some simple programs that clear the screen.  In one
environment on my system, anyway.  :-)


Finally, even with this in place, the build process stopped at
the next roadblock.  The file "genmodes.c" couldn't be
compiled.  I was surprised to see that it was being compiled
with i370-mvspdp-gcc.  The genmodes "needs" to be run on
Unix still.  It's only the source code that IT generates that
needs to be cross-compiled.


If this happens, then something went very wrong during configure.
Did you make sure to use the proper build / host / target flags?
In particular, the --build= configure argument must be present
and refer to the build architecture.  This is used to determine
which architecture to build the generator programs for.


Yes, I have all 3 specified, with --build of i686-linux.  Now that I
know that the generator files are meant to be built with the i686
gcc, I'll try to find out where it's picking that up from.

BFN.  Paul.



Re: i370 port - constructing compile script

2009-10-21 Thread Paul Edwards

Hi Ulrich.  I've had considerable success in this process.  I've
now reached the point where I seem to have a correctly
generated config.h in libiberty and correct auto-host.h in gcc,
which is one of the aims in order to get an eventual link on
MVS.


However, it meant that I could look at the auto-host.h and
see what it had come up with.  It correctly figured out that
I didn't have a raft of header files, but still thought I had
lots of functions like fork() and getrusage().

I suspect that is because my fake compiler is compiling
with the "-S' option and returning success when it's after
a link failure.



OK.  I thought with the fake as and ld scripts, you should
no longer need a "fake compiler" script?


I haven't got to the stage of playing around with that yet.


But even so, you're right that the "fake linker" will not
actually check whether symbols are present in your
library ...



I had an idea - maybe I can have warnings switched on
for functions without prototypes, and then my dummy
compiler trap the output and do a "wc" and if there's
an unexpectedly high number of lines, then it can exit
with failure.



Or simply use -Werror when doing test compiles in
configure.


Turns out that -Werror-implicit-function-declaration wasn't
sufficient.  Because "configure" dutifully goes and inserts
its own declaration for the non-existant functions!

However, more intrusive code:

+ #if !defined(__MVS__)
 char $ac_func ();
+ #else
+ #include 
+ #include 
+ #include 
+ #include 
+ #include 
+ #include 
+ #endif

got past that problem, such that I could get the config
file I needed.  I needed to put in the standard includes,
otherwise it thought that I didn't even have memcmp!

Any suggestion on how to make this less intrusive?  Or
perhaps is it logical to have a generic "trap at compile
time instead of link time" configure option for other
environments also?  Maybe we could have two variables,
a BEFORE_AC_FUNC and AFTER_AC_FUNC which
are defined in all those tests, and can be set to open
comment and close comment + includes to achieve
the above effect.  Or maybe I should simply pass over
the configure script doing that substitution, since the
string to search for is unique and consistent, ie
grep "^char \$ac_func" configure

char $ac_func ();
/* The GNU C library define
   to always fail with ENO
   something starting with
#if defined (__stub_$ac_fun
choke me
#else
char (*f) () = $ac_func;

I was thinking that maybe what I should do is in the fake
linker, see what the output executable is.  If the output
executable is a conftest, then do a scan of the VCONs
(external references) in the assembler making sure they
are all C90.  But that seems to be the wrong approach to
me.  If there's going to be a list of C90 functions and
variables it should probably be in configure.ac I think.

Speaking of which.  When I was putting in the intrusive
code, I saw things like newlib and Vxworks which had
explicit mention and explicit settings for various things.
Perhaps I should be doing something like that too rather
than faking things to get them through?  That would lower
the barrier for an arbitrary and possibly complicated target
with no extensions.

However, let's stay on the current track, so that e.g. this
could be used to target mvsdignus, which probably does
have various extensions, and they may wish to make use
of them in their MVS build.  Thus, it needs to go through
the detection process.

Assuming that detection process has worked, and the
config.h file is correctly set, then I run into the next problem.

A stack of C files in libiberty failed to compile, because they
have extensions in them.  E.g. make-temp-file.c calls
access().  I've never noticed them before because I've never
included them in my links, because they are not required
on MVS.  Even totally unrelated things like pex-unix.c are
being compiled.  So what is the best way of switching the
source code to compile?

It is at this stage that I wish to create a single executable,
so would want the fake linker to do a tar or zip.  (or simply
an echo, I'm flexible on that).  So those failing files would
presumably be omitted from that anyway?  Or are they
normally unconditionally compiled and linked?

Finally, even with this in place, the build process stopped at
the next roadblock.  The file "genmodes.c" couldn't be
compiled.  I was surprised to see that it was being compiled
with i370-mvspdp-gcc.  The genmodes "needs" to be run on
Unix still.  It's only the source code that IT generates that
needs to be cross-compiled.

Regardless, genmodes.c didn't compile because auto-build.h
correctly detected that my Unix system has 
etc, but my own header files don't have that, so a cross
compile doesn't work.

How does that normally work when cross-compiling a host?

BTW, I really like the idea of the fake linker zipping up all the
generated assembler as it goes through, which is ultimately
what I need to send up to MVS.  The JCL can be generated
from "unzip -v" a

Re: i370 port - constructing compile script

2009-10-20 Thread Paul Edwards

../configure --target=i370-mvspdp --prefix=/devel/mvscross 
--with-sysroot=/devel/mvshead
 --enable-languages=c

plus make and make install

then I went to

mvscross/bin and renamed i370-mvspdp-gcc to i370-mvspdp-xxx

and replaced it with a script that does:

i370-mvspdp-xxx -S $*


Maybe a more generic way to work around the missing assembler and linker
would be to provide dummy scripts i370-mvspdp-as


I created one of them, but as far as I can tell it didn't pick it up.


and i370-mvspdp-ld, where
the "assembler" would simply copy the assembler source input as text to 
the

"object" file output, and the "linker" would collect all input files into
a tar file (or some other archive) as "executable" output ...


Sounds good.


This would allow usual build processes (including "make") to proceed as
expected.


Yes.


The compiler error output found in the config.log file should hopefully
point to the problem ...


Well, below are some of the changes I made today to get it to go
past the various errors.  Probably the most interesting was this
one:

! #define BIG_ENDIAN 1
! #define LITTLE_ENDIAN 2
! #define BYTE_ORDER 1

I don't have a sys/param.h and so I just stuck those in somewhere
that it seemed to be looking for, so that it didn't come up and say
that it couldn't determine the endian order.

It seemed to try very hard to stick in sys/types.h and sys/time.h
and I'm not sure how well I got around that.

It also seemed to execute /bin/as at one point instead of my
dummy cross-assembler.  I'll try to figure out what the logic
is tomorrow.

Note - all this is on 3.4.6.

BFN.  Paul.




Index: configure
===
RCS file: /cvsroot/gccnew/gcc/configure,v
retrieving revision 1.1.1.1
retrieving revision 1.8
diff -c -r1.1.1.1 -r1.8
*** configure 9 Jul 2009 00:25:05 - 1.1.1.1
--- configure 20 Oct 2009 12:39:48 - 1.8
***
*** 2463,2470 
 /* end confdefs.h.  */
 #include 
 #include 
! #include 
! #include 
 /* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
 struct buf { int x; };
 FILE * (*rcsopen) (struct buf *, struct stat *, int);
--- 2463,2470 
 /* end confdefs.h.  */
 #include 
 #include 
! /*#include 
! #include */
 /* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
 struct buf { int x; };
 FILE * (*rcsopen) (struct buf *, struct stat *, int);
***
*** 3377,3383 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
! #include 


 int
--- 3377,3383 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
! /*#include */


 int
***
*** 3448,3454 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
! #include 


 int
--- 3448,3454 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
! /*#include */


 int
***
*** 3519,3525 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
! #include 


 int
--- 3519,3525 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
! /*#include */


 int
***
*** 3590,3596 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
! #include 


 int
--- 3590,3596 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
! /*#include */


 int
***
*** 3662,3668 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
! #include 


 int
--- 3662,3668 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
! /*#include */


 int
***
*** 3735,3741 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
! #include 


 int
--- 3735,3741 
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #include "confdefs.h"
! /*#include */


 int
***
*** 5656,5662 
 if test $ac_cv_header_time = yes; then

 cat >>confdefs.h <<\_ACEOF
! #define TIME_WITH_SYS_TIME 1
 _ACEOF

 fi
--- 5656,5662 
 if test $ac_cv_header_time = yes; then

 cat >>confdefs.h <<\_ACEOF
! /*#define TIME_WITH_SYS_TIME 1*/
 _ACEOF

 fi
***
*** 6150,6157 
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
! #include 
! #include 
 int
 main ()
 {
--- 6150,6160 
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
! /*#include 
! #include */
! #define BIG_ENDIAN 1
! #define LITTLE_ENDIAN 2
! #define BYTE_ORDER 1
 int
 main ()
 {
***
*** 6192,6199 
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
! #include 
! #include 
 int
 main ()
 {
--- 6195,6205 
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
! /*#include 
! #include */
! #define BIG_ENDIAN 1
! #define LITTLE_ENDIAN 2
! #define BYT

Re: i370 port - constructing compile script

2009-10-19 Thread Paul Edwards

.../configure --target=i370-mvs --prefix=... --with-sysroot=...  \
  --enable-languages=c

where prefix points to the directory where the cross-compiler
should be installed, and sysroot points to the directory where
the MVS libraries and header are installed.


Ok, I used

../configure --target=i370-mvspdp --prefix=/devel/mvscross --with-sysroot=/devel/mvshead 
--enable-languages=c


plus make and make install

then I went to

mvscross/bin and renamed i370-mvspdp-gcc to i370-mvspdp-xxx

and replaced it with a script that does:

i370-mvspdp-xxx -S $*


For step 3 (cross-building a native compiler), you'd need
something along the lines of

 .../configure --build=i686-linux --host=i370-mvs --target=i370-mvs \
   --prefix=... --with-build-sysroot=... --enable-languages=c


./configure --build-i686-linux --host=i370-mvspdp --target=i370-mvspdp --prefix=/devel/mvshost 
--with-build-sysroot=/devel/mvshead --enable-languages=c


I wasn't sure if that --with-build-sysroot was right - pointing to
the same headers, but couldn't think of anything else to do with it!


This configure run will then use the i370-mvs-gcc cross-compiler
you built in step 2 in order to detect MVS host properties.


Ok, it (3.4.6 I am using) got as far as:

checking size of void *... configure: error: cannot determine a size of void 
*

make: *** [configure-gcc] Error 1

I haven't had a chance to investigate what it's trying to do there, to
see if I can devise a workaround.

I know that it seems to try to compile with "-g" all the time which
gives a warning about it not being supported, but I don't think
warnings produce bad return codes like that.

BFN.  Paul.



Re: i370 port - constructing compile script

2009-10-14 Thread Paul Edwards

> Huh.  I've never seen this before.  Is this with your patches to
> generate a "single executable" or without?

My patches are applied, but shouldn't be activated, because
I haven't defined SINGLE_EXECUTABLE.

I could try taking it back to raw 3.4.6 though and see if that has
the same problem.


Might be interesting ...


Things are never that simple.  :-)

My target isn't in raw 3.4.6, so I had to use a different target (dignus),
which worked!

But dignus no longer worked with my changes.

So had to get dignus working again before I could compare.

I tried other shortcuts, but wasn't successful.

After getting dignus working again I was able to start narrowing
it down.

For some reason gdb doesn't seem to be working as expected,
so had to do without it.

In the end, one line, long forgotten, in my target config file:

#define pwait(a,b,c) (0)

was what was responsible.  :-)  Most of my Posix replacement
functions are in a separate unixio.h, which would normally be
ignored in a configure/real unix environment.  Not sure why this
one ended up there.

Anyway, after that interlude, I can finally move on to the original
challenge!

BFN.  Paul.



Re: i370 port - constructing compile script

2009-10-06 Thread Paul Edwards

The failure (on 3.4.6, but not on 3.2.3) is that after the successful
build, when I do an xgcc -S, it produces the assembler file, and then 
hangs.  I traced this to gcc.c which was in a loop doing this:


pid = pwait (commands[i].pid, &status, 0);

getting a return of 0 all the time, while the process (cc1) that it is
waiting on is showing up as being .

Not sure what that is about.  I have gcc 3.2.3 working without that
problem, so I'll spend some time comparing how the two pexecutes
work differently.


Huh.  I've never seen this before.  Is this with your patches to
generate a "single executable" or without?


My patches are applied, but shouldn't be activated, because
I haven't defined SINGLE_EXECUTABLE.

I could try taking it back to raw 3.4.6 though and see if that has
the same problem.


For the cross-compiler,
you shouldn't need any of the MVS host-specific patches ...


My target is new basically.  It's closest to mvsdignus, which
was used as a starting point, but it has evolved.  :-)


In the meantime, I have a question.  You said above that I have to
point sysroot to the MVS libraries and headers.  What libraries?
And why, at the point of building a cross-compiler, do I need any
of those things?  The normal way I build a cross-compiler I just
do the above configure without prefix or with-sysroot, and it
builds an xgcc executable as expected, using the Linux headers,
as expected.

I would certainly like an option to force it to use my C90-only
Linux headers and my C90-only libraries, but that should be
strictly optional, and if I did do that, I would expect to see
configure saying things like "no you don't have fork, or getrusage,
or sys/types" etc etc.

I think I am still failing to understand some major aspect of the
build process.


Maybe the confusion is about what "sysroot" for a cross-compiler
means.  The libraries and headers in the sysroot are *not* used
to build the compiler itself.  You need to specify the sysroot
location at build time of the compiler only so that this location
can be compiled into the gcc/cc1 binaries.  Once you later *use*
the resulting cross-compiler, this cross-compiler will refer to
the sysroot location for standard headers and libraries.

That is to say, if you build a cross-compiler with
   --prefix=/home/gccmvs/cross
   --sysroot=/home/gccmvs/sysroot
   --target=i370-mvs
the result of the build process ("make" and then "make install")
will be a cross-compiler in /home/gccmvs/cross/bin/i370-mvs-gcc
(and additional files in /home/gccmvs/cross/lib/gcc/...).


Ok, that's a new concept to me.  Thanks.


Note that the build process of the compiler itself will refer to
the host's default headers in /usr/include and libraries in
/usr/lib.

However, once you *run* this i370-mvs-gcc, and it processes a source
file using #include , the compiler will search the directory
/home/gccmvs/sysroot/include for the stdio.h header file, and it will
invoke the cross-linker passing /home/gccmvs/sysroot/lib as the 
location to search for standard libraries like libc.  (Note that the

names of such standard libraries, if any, are defined by the MVS
target definitions, in particular the setting of target macros like
LIB_SPEC in your target header files in config/i370/*.h.)


I don't seem to have that variable defined.  Not surprising since
there's no include or lib directories like that on MVS.


It is important to get this cross-compiler working correctly, i.e.
refering to the proper headers and libraries, because in the next
step, when you configure and build the native compiler, you'll be
using the cross-compiler, and what headers it uses will determine
which host features are detected by configure ...


I see.  Anyway, I'll start with raw 3.4.6 and move forward from
there.  The good thing about doing it that way is that I know the end
result is actually achievable.

Gone are the dark days of the 3.2 port where I was doing a lot of
work, and had no idea whether at the end of all that work it would
all be wasted, because the compiler wouldn't run natively due to
some ASCII-specific bug beyond my ability to fix or work around.  :-)

BFN.  Paul.



Re: i370 port - constructing compile script

2009-10-06 Thread Paul Edwards

Would you be able to give me the two suggested configure
commands so that I can find out the answer to the above, one
way or another?


For step 2 (building the cross-compiler), you'd need something
along the lines of

.../configure --target=i370-mvs --prefix=... --with-sysroot=...  \
  --enable-languages=c

where prefix points to the directory where the cross-compiler
should be installed, and sysroot points to the directory where
the MVS libraries and header are installed.


I tried to action this today.

But first I tried to get the normal make process working, ie without
the --prefix and --with-sysroot above, and just using defaults.  I had
some surprising success, but also one failure.

The failure (on 3.4.6, but not on 3.2.3) is that after the successful
build, when I do an xgcc -S, it produces the assembler file, and then 
hangs.  I traced this to gcc.c which was in a loop doing this:


pid = pwait (commands[i].pid, &status, 0);

getting a return of 0 all the time, while the process (cc1) that it is
waiting on is showing up as being .

Not sure what that is about.  I have gcc 3.2.3 working without that
problem, so I'll spend some time comparing how the two pexecutes
work differently.

Of course I don't have system-related problems like this on MVS,
because I have a single executable and a simple function call.  :-)

In the meantime, I have a question.  You said above that I have to
point sysroot to the MVS libraries and headers.  What libraries?
And why, at the point of building a cross-compiler, do I need any
of those things?  The normal way I build a cross-compiler I just
do the above configure without prefix or with-sysroot, and it
builds an xgcc executable as expected, using the Linux headers,
as expected.

I would certainly like an option to force it to use my C90-only
Linux headers and my C90-only libraries, but that should be
strictly optional, and if I did do that, I would expect to see
configure saying things like "no you don't have fork, or getrusage,
or sys/types" etc etc.

I think I am still failing to understand some major aspect of the
build process.

BFN.  Paul.



Re: i370 port - constructing compile script

2009-10-05 Thread Paul Edwards

.../configure --target=i370-mvs --prefix=... --with-sysroot=...  \
  --enable-languages=c


Thanks Ulrich.  That's very different from the concept I had of
how the build process was meant to work.


Ignoring the cross stuff, if this is all you need I would suggest calling
make in the right way to generate this script.  We'll use a fake
"compiler" for making cc1 which does nothing else than appending its
command line to your compile script.  Hence, create a script
collect-stuff.sh with this content:

 snip --
#!/bin/sh
echo stdcomp ${1+"$@"} >> /tmp/compile
 snap --

Now we'll call make so that it only tries to make cc1 with this compiler
to collect the commands:

% cd gcc
% make CC=collect-stuff.sh cc1


Thanks Michael.  That's exactly the sort of thing I was after.  Just
one thing - I'll need more than cc1.  I need the files that normally
go into gcc as well.  So a combination of those two sets of source,
so that I can get a single standalone executable.  So I'll need to
create a new Makefile target that's a bit bigger than cc1.  But
cc1 will come close.

Also, I decided that I'd better go back to gcc 3.4.6 in order to do
this experimentation, because at least with that I know that at
the end of the day, there's no compiler issue, so if it doesn't
work, the fault must lie withe the build process.

I can't say that about 4.4, because I already know a normally
built cross-compiler on 4.4 with a resuscitated i370 will
build, but has a runtime error which wasn't immediately
obvious (ie gdb didn't point to something wrong).  After 3.4.6
is working, I'll hopefully have an easier time with 4.4.

Anyway, I'll try it out tomorrow etc, and report back the results.

BFN.  Paul.



Re: i370 port - constructing compile script

2009-10-04 Thread Paul Edwards

In step 3, configure will use the A->B cross-compiler (from step 2)
to do the trial compiles.  This compiler, if built correctly, will
use host *B* header files and libraries from its sysroot, and thus
configure will detect properties of system *B* (which again is correct,
as in step 3, "host" == B).

From the symptoms you describe, it would appear that you're picking
up bad configure results in step 3.  Depending on what exactly you
do, this might be either because you don't actually re-run configure
but attempt to use the configure results from step 2 (that certainly
cannot work), or else your step 2 cross-compiler was itself built
incorrectly in some form so it doesn't properly pick up headers
from its sysroot, or else the headers in the sysroot are simply
incorrect ...  You should investigate the various log files left by
configure to figure out what's going on.


Thanks for the explanation Ulrich.

I was previously under the impression (my interpretation of the
documentation) that I just needed to do one configure, and it 
would do both of the steps you mentioned.



Note that one problem might be that your step 2 cross-compiler
cannot actually link executables as it is missing the cross-linker
required to do so.  I *think* the core GCC (C-only) configure
process should be able to handle this, but I might be mistaken
here.


Would you be able to give me the two suggested configure
commands so that I can find out the answer to the above, one
way or another?

Perhaps if that bit fails I will need to replace the cross-compiler
and cross-linker with normal gcc during the configure process,
and only give it access to some C90 libraries.  It so happens
that I have a full suite of those, but even if I didn't, I could
create a dummy printf etc so that it would at least link.

Or does the configure process attempt to run the executables
as well?

No mind - as I said, I have the full suite for a configure to work.

But it won't be able to correctly determine the stack direction
if it does that.  So that is the sort of thing I would need some
intrusive code (out of my 20 lines quota!) to force it to 0
(unknown stack direction).

Thanks.  Paul.



Re: i370 port - constructing compile script

2009-10-03 Thread Paul Edwards

* Copy header files and libraries from the host (MVS).


That's fine.  And use the --with-root option of configure to get
them used?


--with-sysroot, yes.


I have been trying combinations of --prefix and --with-sysroot, and
--with-build-sysroot, but it is still insisting that I have an
fputs_unlocked etc, despite pointing all those things to a
directory that has no such thing in it, and just has my C90
headers.


The --with-sysroot option tells gcc where to find header files and
libraries for the target.  The --with-build-sysroot option tells gcc
where to find header files and libraries for the target while building
gcc itself.


But that's the first step in what I'm doing, isn't it?


fputs_unlocked is called by gcc itself, not by target code;


As such, I am in a position where I can point it to my C90 libraries.

I have everything I need to create the xgcc as a single executable
on Linux that produces i370 assembler.  That's what I already have
with gcc 3.4.6.

With 3.4.6, I have a script called "compile", which looks like this:

call stdcomp alias.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcomp alloc-pool.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcomp attribs.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcomp bb-reorder.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcomp bitmap.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcomp bt-load.c %1 %2 %3 %4 %5 %6 %7 %8 %9
...
gcc -s -nostdlib -o gccmvs.exe *.o ../../pdos/pdpclib/pdpwin32.a -lkernel32

The Windows version is simpler, but I have the equivalent for Linux.

I call it gccmvs instead of xgcc.

That's my cross-compiler.

That was sort of hand-constructed (I actually selected stuff from
the output of a normal make on Linux, skipping stuff that was
used to produce the generator files (genrecog etc).

I believe that a simple script like above can be *generated* with a
few lines of changes to an appropriate makefile.  That's why I
mentioned before that I'm after a makefile target that only lists
the object code that would go into a stage 1 executable.


therefore, what matters for whether fputs_unlocked is supported
is the host header files and libraries, not the target header files
and libraries.  So using --with-sysroot is never going to affect
whether gcc itself uses fputs_unlocked.


Well even with --with-build-sysroot I don't seem to be able to
steer it away from my system's header files.  But this is a
more minor aspect to what I'm interested in.  I think I'll just
rename my system header files and copy in the C90
headers.


The case where that should work if you configure gcc using
--with-sysroot to point to C90 headers and libraries, and you use that
gcc to build another gcc.  That is, configure gcc as a cross-compiler
to a system which happens to be very similar to the host system, and
then use that cross-compiler to build a new compiler, in what is
effectively a same-system Canadian Cross.  The second gcc should not
use fputs_unlocked in that case.


This comment has me confused.

I already have gcc 4.4 installed as a native compiler.  I am now
trying to build on Linux, to produce a Linux-to-i370 cross-compiler.

Therefore the first thing I want to do is build a cross-compiler,
right?  Or does the build process want to force me to compile
gcc 4.4 as a native compiler *again*?  I was expecting it to just
use what I already have, which coincidentally happens to be
gcc 4.4.  Can I skip that step then?  I (used to) sometimes use
a different compiler, such as Watcom or Borland, on Windows,
in order to build the windows-to-i370 cross.


Similarly, getrlimit and getrusage are entirely optional.  They are
used if available, otherwise not.


Right.  I'm having trouble getting it to ignore the ones that are 
installed

on the build system, and to switch to the directory given with
--with-sysroot.


When talking about this kind of thing, you have to distinguish the
build system and the host system.  The header files on the build
system are irrelevant.  The header files on the host system are what
matter.  Normally the build system and the host system are the same,
but this is not true when building with a cross-compiler.


In my case, I intend to run the cross-compiler on Linux to make sure
it works.  On Linux I also want to generate the compile script, and
to generate the JCL.

Once I have all those things (on the best system for gcc tools), I
then want to package it all up and move to Windows.

There I will run the compile script (shown above), and make sure that
it also produces a single executable.  I will use gcc 3.4.4 for that task,
because it comes by default with Cygwin.  I may choose to use
Borland etc instead, but unlikely.

At this stage I will be confident that I have a single C90-compliant
executable, and the challenge becomes whether I can reproduce
that on MVS.

So I run a slightly different script, compmvs, which looks like this:

call stdcompm alias.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcompm alloc-pool.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcompm attribs.c %1 %2 %3 %4 %5 %6 %

Re: i370 port - constructing compile script

2009-10-03 Thread Paul Edwards

* Configure gcc as a cross-compiler.


So this would not be considered a Canadian Cross after all,
and with configure I only change the target, not the host?


The end result is a Canadian Cross, but the first step in a typical
build of a Canadian Cross is a cross-compiler.


Ok.


* Write a cross-assembler and cross-linker.


Sure, and that's what I'm trying to avoid.  I have a perfectly working
assembler and linker on MVS already.  It's been working for several
decades.


There are many advantages of a cross-assembler and cross-linker, but,
whatever.


One of them is not "you can leverage into all the existing work
of the existing-and-working-fine IFOX00 and IEWL".


* Copy header files and libraries from the host (MVS).


That's fine.  And use the --with-root option of configure to get
them used?


--with-sysroot, yes.


I have been trying combinations of --prefix and --with-sysroot, 
and --with-build-sysroot, but it is still insisting that I have an 
fputs_unlocked etc, despite pointing all those things to a

directory that has no such thing in it, and just has my C90
headers.


(Note that you mention fork, but as you probably know the gcc code
never actually calls fork.  It calls the pexecute routines in
libiberty.  Those routines have been ported to several different
hosts, including MS-DOS.  If you port them to MVS, then you don't have
to worry about fork.)


I spent several minutes going through the config.h looking at the
"detected" functions to find a good example.  Maybe I should I
have getrlimit or getrusage or fputs_unlocked instead.


fputs_unlocked is only used for systems which provide it.  On systems
which don't, gcc uses fputs.

Similarly, getrlimit and getrusage are entirely optional.  They are
used if available, otherwise not.


Right.  I'm having trouble getting it to ignore the ones that are installed
on the build system, and to switch to the directory given with
--with-sysroot.  Also, for the long term, it would be better to
distinguish the headers that I use on the build system, to the
headers used when cross-compiling.  As I mentioned, I happen
to be in a position where I can use the same ones on MVS, on
Linux (and some other platforms too), so I can get away with
forcing it to the C90 headers immediately.


I've been discussing this under the assumption that you want to
contribute your port back to gcc.  If you don't, then I think I will
step out.  You can pursue whatever path you like.


I do want it to be in the mainline gcc.  But the requirements for
reversing the 2004 deletion of the i370 target (which can be done
with two svn commands) are too onerous to be met for likely
years.  I personally think it's strange that we had an i370 target 
that didn't meet those requirements from 1993 to 2004, but now 
it isn't, regardless of the fact that it now works better than ever 
before (not suprising after more than 5 years of effort by multiple

people).  But there's not much I can do about that.

Way back In 1998 I was talking to someone from GCC (not ecgs)
about getting some mods in to support MVS (I wasn't aware of
other MVS activity on the ecgs side).  The computer with the 
conversation was stolen, so I don't know who that was.  Whoever

it was, I think they had plans to rewrite the i370.md themselves
(but that obviously didn't happen).  My changes were all outside that.

Basically I needed those small mods to create a single executable
plus some other minor mods (similar to what I posted here recently).
I don't recall if any of it was accepted or not (I just gave the patches,
and no longer have those to see if they got in).  I know the 
single-executable mods didn't get in, because I know what to

look for, and it isn't there.

There's not much I can do about the non-acceptance of the mods,
but the one thing I can do is keep my modification footprint low.
That's why I believe that 20 lines somewhere in the configuration
scripts are probably enough to get what I want, without upsetting
the existing structure.  Maybe eventually those 20 lines will be
accepted as a non-default option, but that is beyond my control.

But regardless of whether it is accepted or not, I want to be able
to demonstrate it working first.

Where "working" doesn't mean "write my own cross-assembler 
and cross-linker and change MVS to be posix instead of MVS

and get the entire test suite working", but rather "work the same
way that gccmvs 3.2.3 works (ie bootstrapping works), except 
get the JCL and auto-host to be automatically generated instead

of manually constructed for each release".

It takes several days of effort to manually construct those files 
and debug the problems with them, when I suspect that with the 
right config command-line and a little bit of intrusive code, plus

some external support scripts (that are no skin off anyone's
nose), the whole thing can be automated.

Anyway, I'll keep plugging away.  I resorted to renaming
/usr/include, but that triggered off other problems.  I suspect 

Re: i370 port - constructing compile script

2009-10-02 Thread Paul Edwards

Hi Ian, thanks for your reply.


1. First I need to use my current build machine, Linux,
to first of all convert the i370.md into insn*.c files, then
generate an xgcc.  The xgcc would be capable of producing
i370 code so long as I use the "-S" option.  It doesn't really
matter how this xgcc was created (ie using non-C90
stuff like fork available on my build machine).

2. It is now (at the Alaskan stage) that I need a different sort
of config.h/auto-host.h that excludes things like fork.  I can
present my i370 include files here, that only include C90
functions.  It is at this stage that I need it to invoke xgcc
(still on the build machine), but it will be with the -S option,
so there will be no .o files (although I could perhaps fake
that via a scipt to keep "make" happy) and no executable
built.  The "fake" script could generate JCL at the same time.
The C90 library (for MVS) also needs to be cross-compiled
here.

3. Then I need to assemble all the assembler on real i370
(MVS).  It is at this point that a real host (ie on i370 MVS)
xgcc is built.

4. Then I can use that xgcc (on MVS) to compile arbitary
C programs.  Technically I could have had a requirement
for this i370-mvs host compiler to produce say sparc target
code.


What most people do is:

* Configure gcc as a cross-compiler.


So this would not be considered a Canadian Cross after all,
and with configure I only change the target, not the host?


* Write a cross-assembler and cross-linker.


Sure, and that's what I'm trying to avoid.  I have a perfectly working
assembler and linker on MVS already.  It's been working for several
decades.


* Copy header files and libraries from the host (MVS).


That's fine.  And use the --with-root option of configure to get
them used?


Now you have a complete cross-toolchain running on a supported host
which can produce executables which run on MVS.


It's a can of worms just trying to copy MVS load modules.  There's
meta-data in 2 different places and it needs to be packaged.


* Use that cross-toolchain to build a version of gcc which runs on
 MVS.  At this step you port gcc to work on MVS.
* Run that gcc on MVS.

(Note that you mention fork, but as you probably know the gcc code
never actually calls fork.  It calls the pexecute routines in
libiberty.  Those routines have been ported to several different
hosts, including MS-DOS.  If you port them to MVS, then you don't have
to worry about fork.)


I spent several minutes going through the config.h looking at the
"detected" functions to find a good example.  Maybe I should I
have getrlimit or getrusage or fputs_unlocked instead.


To fit into the standard Canadian Cross 3-step model, I need
to either collapse steps 2 and 3 into 1 theoretical step, executed
across 2 platforms (compile on one, assemble on another),


Right, people normally do this by using a cross-assembler and
cross-linker.


Ok.


I suspect that it will only take 20 lines or similar of intrusive
Makefile/shell script changes to shoe-horn my way into the
existing gcc methodology.  All I need to do is force it to use
my C90 headers at the right spot, so that it stops thinking
that I have fork etc, and stop it trying to build an executable.

Can someone tell me where to put those 20 lines?


One way to shoe-horn those lines in would be to make your
cross-assembler and cross-linker actually be shell scripts.


Ok, that's no problem.


They
would copy the files to MVS, run the real assembler and linker, and
copy the output back.


I might theoretically be able to do such a thing, but that's not what I'm
after.  I'm just after 200+ assembler files to be produced so that I can
zip them up and take them to a real MVS site or whatever to get
compiled.  It looks like someone just wrote a C compiler in
370 assembler, which is now all natural MVS (the objective of the
exercise).


That would be more than 20 lines, but it seems
doable to me.


Actually, that would be 0 lines of intrusive code (ie changing GCC
itself).


But I don't understand the bit about C90 headers.  gcc doesn't need
fork, but it does need a way to execute other programs.


No, I use intrusive code to convert the pexecute call into a static
call to cc1 (effectively - I actually intercept it within gcc itself, see
below).  And that is why I need a Makefile target that includes
all the object code.  Because I compile the 450,000 lines of C code
into 850,000 lines of assembler code to produce a 3.4 MB gcc load
module for MVS.  Those figures are from gcc 3.4.6.

BFN.  Paul.




***
*** 2610,2615 
--- 2623,2631 
 static int
 execute (void)
 {
+ #ifdef SINGLE_EXECUTABLE
+   int ret_code = 0;
+ #endif
   int i;
   int n_commands; /* # of command.  */
   char *string;
***
*** 2756,2761 
--- 2772,2792 
   char *errmsg_fmt, *errmsg_arg;
   const char *string = commands[i].argv[0];

+ #ifdef SINGLE_EXECUTABLE
+  {
+  int cnt = 0;
+
+  while (commands[i].argv[cnt] != 

Re: i370 port - constructing compile script

2009-10-02 Thread Paul Edwards

I tried again but I'm not making much progress.

Maybe I need to go further than Canada, let's say Alaska.

1. First I need to use my current build machine, Linux,
to first of all convert the i370.md into insn*.c files, then
generate an xgcc.  The xgcc would be capable of producing
i370 code so long as I use the "-S" option.  It doesn't really
matter how this xgcc was created (ie using non-C90
stuff like fork available on my build machine).

2. It is now (at the Alaskan stage) that I need a different sort
of config.h/auto-host.h that excludes things like fork.  I can
present my i370 include files here, that only include C90
functions.  It is at this stage that I need it to invoke xgcc
(still on the build machine), but it will be with the -S option,
so there will be no .o files (although I could perhaps fake
that via a scipt to keep "make" happy) and no executable
built.  The "fake" script could generate JCL at the same time.
The C90 library (for MVS) also needs to be cross-compiled
here.

3. Then I need to assemble all the assembler on real i370
(MVS).  It is at this point that a real host (ie on i370 MVS)
xgcc is built.

4. Then I can use that xgcc (on MVS) to compile arbitary
C programs.  Technically I could have had a requirement
for this i370-mvs host compiler to produce say sparc target
code.

All of the above ignores the bootstrap on MVS, which I know
is easy to add on later.

To fit into the standard Canadian Cross 3-step model, I need
to either collapse steps 2 and 3 into 1 theoretical step, executed
across 2 platforms (compile on one, assemble on another), or I
need to omit step 4, and say that I cannot target any platform
other than the host.  Which is fine by me anyway.  If combining
steps 2 and 3, we could ignore the fact that step 3 happens at
all, and assume that there is a theoretical machine that directly
executes assembler code.

I suspect that it will only take 20 lines or similar of intrusive
Makefile/shell script changes to shoe-horn my way into the
existing gcc methodology.  All I need to do is force it to use
my C90 headers at the right spot, so that it stops thinking
that I have fork etc, and stop it trying to build an executable.

Can someone tell me where to put those 20 lines?  I have been
playing around with something like this:

./configure --host=i370-mvspdp --enable-languages=c 
--with-local-prefix=/devel/pdos/pdpclib

but haven't been getting very far.

I have one more option, and in fact, maybe it's even a preference.

The C90-only library (PDPCLIB) I have on MVS is also on Linux,
and gives me advance warning of problems about to happen on
MVS.  As such, I could force the build machine to use this C90 library
to build the first xgcc.  Then the config file etc would be correct
for the next step.  Mostly correct, anyway.  It would probably get
the stack direction wrong instead of leaving it unknown.

What suggestions for a configure command that would come
closest to what I want?  Note that with the above host I had to
copy "ar" to "i370-mvspdp-ar" to get it to the stage of building
the xgcc.

Note - prior to this latest exercise, in order to get some initial
feedback, I had been manually constructing the auto-host
and using my manually-created compile script to compile.
But that's a pretty horrible life, when I'm pretty sure that a
judiciously-placed 20 lines of code and some nifty config
parameters for host and target will automate the thing.

Any suggestions that don't involve "forget about MVS - no-one
even knows how to spell MVS these days"?

Thanks.  Paul.



Re: i370 port - constructing compile script

2009-10-01 Thread Paul Edwards

But from the Unix system, I need to be able to generate the
above very simple compile script, which is a precursor to creating
very simple JCL steps (trust me, you don't want to see what
ST2CMP looks like).  Note that the JCL has the filenames
truncated to 8 characters, listed twice, uppercased, and '-'
and '_' converted to '@'.



Why are you not making use of z/OS Unis System Services?  GNU Make and
other GNU tools are available and already built for z/OS.


USS is not available for free, or even for a price on MVS 3.8j,
and it is not native MVS, it is an expensive overhead.

It's a bit like asking "why don't you use a JCL emulator instead 
of make on Unix?".  :-)


You know, even as a batch job with JCL, people then said to me
that reading the C source from a file instead of "standard input"
(ie stdin, ie //SYSIN DD) is really weird, and so I had to make a
pretty small mod to GCC to allow "-" as the filename, so that
the JCL at least looks like a normal MVS compiler.


Perhaps because he is a hacker in the good ol' sense of the word ?

Mjam, MVS, JCL, the possibility of COBOL, perhaps even PL/1 ...


Both Cobol and PL/1 front-ends are already supported to some
extent ...

http://www.opencobol.org/

http://pl1gcc.sourceforge.net/

although we're not really at the stage of even attempting to get
that onto native MVS.

Actually, PL/1 basically requires GCC 4.x, which is my main
interest in upgrading 3.4.6 to 4.x.  :-)

Someone else said he would like to see PL/S, and maybe if
PL/1 was available, the super-secret PL/S language would 
start to be made available.


But it all rests on getting the HLASM-generator working on a more
modern GCC.  :-)

And C90 is the lingua franca.


[ Over a quarter of century ago I worked at the computer center
  of the Dutch Postal Service. One of my colleagues managed the
  IBM system group.  He had an assistant to write the JCL jobs he needed
  for him. ]


Maybe for old times sake you'd like to load up:

http://mvs380.sourceforge.net

It comes with GCC so you can now do what you always wanted
to do back then.  :-)  And of course, all perfectly usable on z/OS
too.  Natively.  :-)

850,000 lines of assembler.  Like wow, man.  I wonder what
GCC 4.4 will clock in as?  3.2.3 was 700,000, so we're probably
up to a million lines of pure 370 assembler.  :-)

BFN.  Paul.



Re: i370 port - constructing compile script

2009-10-01 Thread Paul Edwards

the gcc build system working. Trying to bootstrap gcc there seems
like a lot
of pain for no real benefit.


The effort is mostly in the Canadian Cross.  The changes to get it to
bootstrap from that point are relatively small.


I think you are underestimating the work involved.


?  Note that I have *already* ported both GCC 3.2.3 and GCC 3.4.6
such that they bootstrap on MVS, in a totally non-Unix environment,
with nothing more than a C90 compiler (with zero (0) extensions).

The trouble is that in the process of doing that (ie mainly for the
Canadian Cross part), I had to:

1. Construct the config.h/auto-host by hand (having the stack
direction go the wrong way was a lot of fun for sure).
2. Got the list of files to compile by hand.
3. Constructed the compile JCL by hand.

I believe all of these things can be integrated into the existing
build process on Unix with minimal fuss if you know where to
put it.

At the time I was doing the original porting, I didn't even have
Unix, so it was easier to do it by hand.

But now I'm interested in neat, minimal integration.  With appropriate
workarounds, GCC is very close to C90 already.


Many years ago now, when Steve Chamberlain started porting the GNU
tools to bootstrap on Windows, he realized that the best approach was
to write (what is now known as) cygwin.  It may sound crazy now, but
bringing the Unix environment to yours is doable, and it has many
ancillary benefits.


Adding POSIX to MVS 3.8j is certainly a worthwhile project.

However, I consider bashing GCC into C90-shape to be a worthwhile
project too.  For whenever you're on a non-Posix system, not just
MVS.  E.g. DOS/VS, or CMS, or MUSIC/SP, or TPF, or MVT, or
MFT, or some of the others I have heard mentioned.  :-)

I'm really only interested in DOS/VS, CMS, MUSIC/SP.  Maybe
TPF as well.  But bringing POSIX to them is a separate exercise
to writing the 1000 lines (literally) of assembler that is required to
get them to work.  GCC 3.4.6 is 850,000 lines of (generated)
assembler code.  But the way things are structured, it only requires
1000 lines for each of those different targets (to do I/O).

MVS and CMS are already done.  MUSIC/SP is half done (the
person doing the port died).  DOS/VS is not done, although a
couple of people started an attempt.

Adding POSIX to all those environments may be done at some
point in the future, but no-one has even started, and everyone
wants native support regardless.  Can you imagine if GCC was
running on Unix with some sort of emulated-MVS I/O?  You'd
rip out that nonsense and replace it with native POSIX in an
instant.  CMS actually supports emulated MVS I/O too, and
indeed, that's what the first port was.  But someone has already
spent the effort to replace it with native CMS I/O, which gets
around various restrictions.

I think that we have now reached the point where two quite
different cultures meet.  :-)  People have been freaking out a
bit on the MVS side too.  :-)

BFN.  Paul.



Re: i370 port - constructing compile script

2009-10-01 Thread Paul Edwards

I am happy to construct all of this on a Unix system with the various
tools (m4 etc) available.

But from the Unix system, I need to be able to generate the
above very simple compile script, which is a precursor to creating
very simple JCL steps (trust me, you don't want to see what
ST2CMP looks like).  Note that the JCL has the filenames
truncated to 8 characters, listed twice, uppercased, and '-'
and '_' converted to '@'.


Have you considered the obvious solution: Don't do that?
i.e. use a cross compiler from a sane system. If you really want to a 
native

compiler than I still suggest building it as a canadian cross.


That's what this is.

Or at least, replace ST2CMP with ST1CMP and it is the Canadian Cross.

ST1CMP will run the assemblies using HLASM.

Almost identical JCL will run a compile, then an assemble with HLASM.


My guess is
that getting gcc hosted in a bizarre environment is much easier than 
getting


Not so bizarre when so many of the Fortune 500 use it.

the gcc build system working. Trying to bootstrap gcc there seems like a 
lot

of pain for no real benefit.


The effort is mostly in the Canadian Cross.  The changes to get it to
bootstrap from that point are relatively small.  The extra things
required are:

1. header.gcc to remap includes.
2. scripts to rename includes.
3. 20 lines of JCL in the stage 2 procs, to do compiles.

Here's the first of those from 3.4.6, so you can see the scope of
the work:

builtin-attrs.def builtina.h
builtin-types.def builtint.h
builtins.def builtind.h
c-common.def ccommond.h
diagnostic.def diagndef.h
machmode.def machmodd.h
params.def paramsd.h
predict.def predictd.h
rtl.def rtld.h
stab.def stabd.h
timevar.def timevard.h
tree.def treed.h
insn-constants.h i-constants.h
langhooks-def.h langhdef.h
hosthooks-def.h hosthdef.h
gt-dwarf2asm.h gt-dwasm.h
gcov-io.c gcovioc.h

It's now very rare to have a problem on the MVS EBCDIC host that
doesn't also occur on a Unix ASCII cross-compiler.

So for that extra bit of work, mainframers are able to modify the
C compiler on their native platform instead of having to mess
around with a Unix system they know nothing about.

Part of open source is making the source available and
usable on the native environment, I think.  Otherwise, the job
of providing a free, open source C compiler on the mainframe
hasn't really been done, I think.  And I was dreaming of that
way back in 1987 when I had a 3270 terminal plus a
mainframe.  Although admittedly I only wanted to use it, not
build it.  But the easier it is for a mainframer to access the
code, the more likely it is that they will be inspired to add
a PL/S or Cobol front-end to it.

BFN.  Paul.



Re: i370 port - constructing compile script

2009-10-01 Thread Paul Edwards

> 2. If the normal way to do things is to parse the make -n output
> with perl etc, that's fine, I'll do it that way.  I was just wondering
> if the proper way was to incorporate the logic into a Makefile
> rule and get that rule repeatedly executed rather than just
> having a simple "echo".  It seems to me that having a generic
> rule to execute an external script would be neater???

I'm not sure what you are suggesting here, but I do know that it
wouldn't make sense for us to change the gcc Makefile to use a rule
which executes an external script.


I didn't mean use by default.


The "normal way to do things" is to use GNU make.  I think you are the
first person trying to build gcc without it.


It's also the first native MVS port.

Anyway, since then I had another idea.  I should be able to achieve
the same thing by just changing the C compiler to be "echo" or the
external script replacement.

Then all I need is a consolidated stage 1 target.

But today I spent my time fighting a different battle.

I tried to get configure to use my provided minimal (ie all of C90,
but no extensions) header files, using the --with-root option
and --with-build-root.

But it seemed to ignore those and use the ones on my Linux box,
insisting that sys/types existed etc.  Maybe I need to change my
INCLUDE_PATH or something instead.


Not the first - BSDs have been known to import GCC sources into their
repositories and write their own build system using BSD make.  No doubt
this is a lot of work that needs repeating for each new version imported -
that's the price you pay if you don't want to use the normal GCC build
system.



(And GCC didn't always require GNU make - but the BSDs replacing the build
system are a much closer analogy here than ordinary builds of old versions
with other make implementations before GNU make was required.)


Yeah, make isn't available (environment variables aren't available
in batch either), and even if it was, that's not what people want.  People
want SMP/E in fact.  But I don't know SMP/E.  I only know JCL, which
is the normal (and much much simpler) rival for SMP.

I don't think that doing a glorified "make -n" is a radical change to
the existing methodology.  Nor is a make target that just lists all
the stage 1 object files.  I think it would be a neat addition (even
if it remains a patch forever).

BFN.  Paul.



  1   2   >