public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: i370 port
@ 2009-09-09 22:33 Paul Edwards
  2009-09-14 15:42 ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-09-09 22:33 UTC (permalink / raw)
  To: Joseph S. Myers, Ulrich Weigand; +Cc: gcc

> 2. I am unable to do an optimized compile even as a cross-compile,
> I get an internal error in this function:
> 
> gcse.c:
> 
> static void
> compute_hash_table_work (struct hash_table *table)
> {
> ...
>  if (!current_bb) /* +++ why are we getting NULL here? */

It appears I have misdiagnosed this.  The code will handle NULL
already.  Taking that out though, exposes this internal error:

int
i370_branch_dest (branch)
     rtx branch;
{
  rtx dest = SET_SRC (PATTERN (branch));
  int dest_uid;
  int dest_addr;

  /* first, compute the estimated address of the branch target */
  if (GET_CODE (dest) == IF_THEN_ELSE)
    dest = XEXP (dest, 1);
  dest = XEXP (dest, 0);
  /* +++ why is this becoming NULL? */
  if (!dest)
  {
      printf("internal error in branch dest\n");
      exit (0);
  }

which is obviously specific to the i370 port.  This code works fine on
3.2.3 though, so any idea what 3.4.6 changed to stop this from
working?

Thanks.  Paul.




  dest_uid = INSN_UID (dest);
  dest_addr = INSN_ADDRESSES (dest_uid);

  /* next, record the address of this insn as the true addr of first ref */
  {
     label_node_t *lp;
     rtx label = JUMP_LABEL (branch);
     int labelno = CODE_LABEL_NUMBER (label);

     if (!label || CODE_LABEL != GET_CODE (label)) abort ();

     lp = mvs_get_label (labelno);
     if (-1 == lp -> first_ref_page) lp->first_ref_page = mvs_page_num;
     just_referenced_page = lp->label_page;
  }
  return dest_addr;
}

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-09 22:33 i370 port Paul Edwards
@ 2009-09-14 15:42 ` Ulrich Weigand
  2009-09-15 12:59   ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-09-14 15:42 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Joseph S. Myers, gcc

Paul Edwards wrote:

> int
> i370_branch_dest (branch)
>      rtx branch;
> {
>   rtx dest = SET_SRC (PATTERN (branch));
>   int dest_uid;
>   int dest_addr;
> 
>   /* first, compute the estimated address of the branch target */
>   if (GET_CODE (dest) == IF_THEN_ELSE)
>     dest = XEXP (dest, 1);
>   dest = XEXP (dest, 0);

This is set up only to handle direct branches of the form

  (set (pc) (label_ref ...))

and indirect branches of the form

  (set (pc) (if_then_else (...) (label_ref ...) (pc)))

but *not* indirect branches of the form

  (set (pc) (if_then_else (...) (pc) (label_ref ...)))

This latter form is accepted by the "negated conditional
jump instructions in the i370.md file, like so:

(define_insn ""
  [(set (pc)
        (if_then_else (eq (cc0)
                          (const_int 0))
                      (pc)
                      (label_ref (match_operand 0 "" ""))))
;   (clobber (reg:SI 14))
   ]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 0);
  if (i370_short_branch(insn) || mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {


Therefore, the i370_branch_dest routine needs to handle
those as well.  Probably something along the following lines:

  if (GET_CODE (dest) == IF_THEN_ELSE)
    {
      if (GET_CODE (XEXP (dest, 1) == LABEL_REF)
	dest = XEXP (dest, 1);
      else
	dest = XEXP (dest, 2);
    }

  gcc_assert (GET_CODE (dest) == LABEL_REF);
  dest = XEXP (dest, 0);

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-14 15:42 ` Ulrich Weigand
@ 2009-09-15 12:59   ` Paul Edwards
  2009-09-15 13:51     ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-09-15 12:59 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Joseph S. Myers, gcc

> Therefore, the i370_branch_dest routine needs to handle
> those as well.  Probably something along the following lines:
>
>  if (GET_CODE (dest) == IF_THEN_ELSE)
>    {
>      if (GET_CODE (XEXP (dest, 1) == LABEL_REF)
> dest = XEXP (dest, 1);
>      else
> dest = XEXP (dest, 2);
>    }
>
>  gcc_assert (GET_CODE (dest) == LABEL_REF);
>  dest = XEXP (dest, 0);

Hi Ulrich.  Thanks for the reply.  I didn't use gcc_assert because I
didn't see it defined anywhere, but the rest of the fix worked fine.

I have now reached the stage where I can (*) self-compile with
optimization on (**).  It takes 6 hours (***).  :-)

(*) I had to disable the MH (multiply halfword) instruction in order
to get it to go through unfortunately.  See below (+).

(**) Except that c-common is being compiled with it off, because of
a bug in the emulator I think, rather than GCC.

(***) It would be closer to 4 hours if I didn't have to do two passes on
the mainframe.  I can't do that though until I can verify the integrity
of the generated code.  And I can't do that until I can get a fully
optimized compile done, because otherwise the register selection changes
slightly on PC vs mainframe causing slight differences in the one
file being compiled without optimization, that prevents an automatic
compare.


(+) Can you spot anything wrong with this?

Here is the error I get:

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
         cppexp.c
cppexp.c: In function `ZZZ_1148':
cppexp.c:980: error: unable to generate reloads for:
(insn 15 14 19 0 (set (reg:SI 4 4 [32])
        (mult:SI (reg:SI 4 4 [30])
            (const_int -858993459 [0xcccccccd]))) 52 {*i370.md:2585} 
(insn_list
12 (nil))
    (expr_list:REG_DEAD (reg:SI 4 4 [30])
        (nil)))
cppexp.c:980: internal compiler error: in find_reloads, at reload.c:3690
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gccmvs.sourceforge.net> for instructions.


I can bypass this error by commenting out the MH pattern, and
the code that would normally invoke it.  Note that I didn't write
that "XXX trouble" stuff, and I don't know if it is still relevant.

;
; mulsi3 instruction pattern(s).
;

(define_expand "mulsi3"
  [(set (match_operand:SI 0 "general_operand" "")
        (mult:SI (match_operand:SI 1 "general_operand" "")
                 (match_operand:SI 2 "general_operand" "")))]
  ""
  "
{
  /*if (GET_CODE (operands[1]) == CONST_INT
      && REG_P (operands[0])
      && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
    {
      emit_insn (gen_rtx_SET (VOIDmode, operands[0],
                          gen_rtx_MULT (SImode, operands[2], operands[1])));
    }
  else if (GET_CODE (operands[2]) == CONST_INT
           && REG_P (operands[0])
           && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))
    {
      emit_insn (gen_rtx_SET (VOIDmode, operands[0],
                          gen_rtx_MULT (SImode, operands[1], operands[2])));
    }
  else */
    {
      rtx r = gen_reg_rtx (DImode);

      /* XXX trouble.  Below we generate some rtx's that model what
       * is really supposed to happen with multiply on the 370/390
       * hardware, and that is all well & good.  However, during 
optimization
       * it can happen that the two operands are exchanged (after all,
       * multiplication is commutitive), in which case the doubleword
       * ends up in memory and everything is hosed.  The gen_reg_rtx
       * should have kept it in a reg ...  We hack around this
       * below, in the M/MR isntruction pattern, and constrain it to
       * \"di\" instead of \"g\".  But this still ends up with lots & lots 
of
       * movement between registers & memory and is an awful waste.
       * Dunno how to untwist it elegantly; but it seems to work for now.
       */
      if (GET_CODE (operands[1]) == CONST_INT)
      {
      emit_insn (gen_rtx_SET (VOIDmode,
                          gen_rtx_SUBREG (SImode, r, GET_MODE_SIZE 
(SImode)),
                                          operands[1]));
      emit_insn (gen_rtx_SET (VOIDmode, r,
                          gen_rtx_MULT (DImode, r, operands[2])));
      }
      else
      {
      emit_insn (gen_rtx_SET (VOIDmode,
                          gen_rtx_SUBREG (SImode, r, GET_MODE_SIZE 
(SImode)),
                                          operands[2]));
      emit_insn (gen_rtx_SET (VOIDmode, r,
                          gen_rtx_MULT (DImode, r, operands[1])));
      }
      emit_insn (gen_rtx_SET (VOIDmode, operands[0],
                          gen_rtx_SUBREG (SImode, r, GET_MODE_SIZE 
(SImode))));
    }
  DONE;
}")

;(define_insn ""
;  [(set (match_operand:SI 0 "register_operand" "=d")
;       (mult:SI (match_operand:SI 1 "register_operand" "0")
;                (match_operand:SI 2 "immediate_operand" "K")))]
;  ""
;  "*
;{
;  check_label_emit ();
;  mvs_check_page (0, 4, 0);
;  return \"MH  %0,%H2\";
;}"
;   [(set_attr "length" "4")]
;)

; See mulsi3 comment above as to why this is constrained to
; "di" rather than "g"
(define_insn ""
  [(set (match_operand:DI 0 "register_operand" "=d")
        (mult:DI (match_operand:DI 1 "general_operand" "0")
                 (match_operand:SI 2 "general_operand" "di")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"MR       %0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"M    %0,%2\";
}"
   [(set_attr "length" "4")]
)


Regardless, when that code is NOT commented out, such that I get that
error, it is surprising that it is passing through this code:

      emit_insn (gen_rtx_SET (VOIDmode, r,
                          gen_rtx_MULT (DImode, r, operands[2])));

where it is clearly attempting to do a DImode multiply, and thus
shouldn't be matching the MH, that I am getting the problem.

Although almost all of the GCC code can be compiled with
this in place.  It's only when I have that very large constant,
0xcccccccd, not sure where that's coming from, that I have
the problem.

Commenting out the MH pattern (and the code that tries to
call MH) makes it happily use the proper intended MR instruction,
and everything works so well that gcc 3.4.6 can self-compile
on an EBCDIC environment.  :-)

Any ideas?

Thanks.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-15 12:59   ` Paul Edwards
@ 2009-09-15 13:51     ` Ulrich Weigand
  2009-09-17 13:00       ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-09-15 13:51 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Joseph S. Myers, gcc

Paul Edwards wrote:

> Hi Ulrich.  Thanks for the reply.  I didn't use gcc_assert because I
> didn't see it defined anywhere, but the rest of the fix worked fine.

Ah, I see this macro was only added in 4.x.  In 3.x you should just
use abort () directly, like so:

  if (GET_CODE (dest) != LABEL_REF)
    abort ();

> (*) I had to disable the MH (multiply halfword) instruction in order
> to get it to go through unfortunately.  See below (+).
 
> (+) Can you spot anything wrong with this?

> ;(define_insn ""
> ;  [(set (match_operand:SI 0 "register_operand" "=d")
> ;       (mult:SI (match_operand:SI 1 "register_operand" "0")
> ;                (match_operand:SI 2 "immediate_operand" "K")))]
> ;  ""
> ;  "*
> ;{
> ;  check_label_emit ();
> ;  mvs_check_page (0, 4, 0);
> ;  return \"MH  %0,%H2\";
> ;}"
> ;   [(set_attr "length" "4")]
> ;)

The combination of predicates and constraints on this insn is broken.

Before reload, the predicate "immediate_operand" explicitly allows
*any* SImode immediate value.  However, during reload, the "K"
constraint accepts only a subset of values.  As there is no other
alternative, and the insn supports neither memory nor register
operands, this is impossible for reload to fix up.

In addition, I don't quite understand how this pattern works in
the first place; MH requires a memory operand, but this pattern
seems to output an immediate value as operand.  Is there some
magic going on in your assembler?

If you indeed want to output immediate values here, you should
probably define a new *predicate* that constrains the set of
allowed values even before reload.

In the s390 port, we're instead modelling the MH instruction
with a memory operand (this still allows the generic parts of
GCC to push immediate operands into memory, if they are in
range for an HImode operand):

(define_insn "*mulsi3_sign"
  [(set (match_operand:SI 0 "register_operand" "=d")
        (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R"))
                 (match_operand:SI 1 "register_operand" "0")))]
  ""
  "mh\t%0,%2"
  [(set_attr "op_type"  "RX")
   (set_attr "type"     "imul")])

> ; See mulsi3 comment above as to why this is constrained to
> ; "di" rather than "g"
> (define_insn ""
>   [(set (match_operand:DI 0 "register_operand" "=d")
>         (mult:DI (match_operand:DI 1 "general_operand" "0")
>                  (match_operand:SI 2 "general_operand" "di")))]
>   ""
>   "*
> {
>   check_label_emit ();
>   if (REG_P (operands[2]))
>     {
>       mvs_check_page (0, 2, 0);
>       return \"MR       %0,%2\";
>     }
>   mvs_check_page (0, 4, 0);
>   return \"M    %0,%2\";
> }"
>    [(set_attr "length" "4")]
> )

This also seems broken.  A MULT:DI must have two DImode operands,
it cannot have one DImode and one SImode operand.  Also, it is in
fact incorrect that it takes the full DImode first operand; rather,
it only uses the low 32-bit of its first operand as input.

In the s390 port we're modelling the real behavior of the instruction
using two explicit SIGN_EXTEND codes:

(define_insn "mulsidi3"
  [(set (match_operand:DI 0 "register_operand" "=d,d")
        (mult:DI (sign_extend:DI
                   (match_operand:SI 1 "register_operand" "%0,0"))
                 (sign_extend:DI
                   (match_operand:SI 2 "nonimmediate_operand" "d,R"))))]
  "!TARGET_64BIT"
  "@
   mr\t%0,%2
   m\t%0,%2"
  [(set_attr "op_type"  "RR,RX")
   (set_attr "type"     "imul")])

> Regardless, when that code is NOT commented out, such that I get that
> error, it is surprising that it is passing through this code:
> 
>       emit_insn (gen_rtx_SET (VOIDmode, r,
>                           gen_rtx_MULT (DImode, r, operands[2])));
> 
> where it is clearly attempting to do a DImode multiply, and thus
> shouldn't be matching the MH, that I am getting the problem.

Well, the point of optimization is that the RTXes do not stay the
way they were originally expanded ...   The optimizers will attempt
to perform various generic optimization on the code, and if the
back-end claims to support a pattern that implements any of those
optimized forms, it will get used.  In this case, even though you
expanded a DImode multiply, common code may notice that it can
be optimized to a SImode multiply instead.

Generally speaking, your RTX patterns *must* be fully correct and
represent the actual behavior of the machine in all cases.  If there
are corner cases formally allowed by the RTX pattern, but the
behavior of the machine differs, this may cause breakage.  Even if
your expanders avoid those corner cases when using your patterns,
this will not be true for the optimizers.

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-15 13:51     ` Ulrich Weigand
@ 2009-09-17 13:00       ` Paul Edwards
  2009-09-17 17:55         ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-09-17 13:00 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Joseph S. Myers, gcc

Hi Ulrich.

Good news is that I have now gotten GCC 3.4.6 to recompile
itself with full optimization on.  The compilation time on the
(emulated) mainframe is only 2.5 hours as only a single pass
is required.  GCC 3.4.6 requires 49 MB to recompile c-common!

I assume with GCC 3.4.6 it is doing global optimization or
something.  It was only 20 MB under 3.2.3.

Anyway, I'm still continuing the cleanup, but now have a strong
fallback position.  Basically I won't introduce any machine
definition change that causes the self-compile to fail.

>> ;(define_insn ""
>> ;  [(set (match_operand:SI 0 "register_operand" "=d")
>> ;       (mult:SI (match_operand:SI 1 "register_operand" "0")
>> ;                (match_operand:SI 2 "immediate_operand" "K")))]
>> ;  ""
>> ;  "*
>> ;{
>> ;  check_label_emit ();
>> ;  mvs_check_page (0, 4, 0);
>> ;  return \"MH  %0,%H2\";
>> ;}"
>> ;   [(set_attr "length" "4")]
>> ;)
>
> The combination of predicates and constraints on this insn is broken.
>
> Before reload, the predicate "immediate_operand" explicitly allows
> *any* SImode immediate value.  However, during reload, the "K"
> constraint accepts only a subset of values.

Is there a way to give a predicate that just says "look at the
constraint"?  It seems a bit overkill to add a new predicate
for this one instruction.

> As there is no other alternative,

No other alternative for this same pattern, right?  There was an
alternative - the pattern that I explictly asked it to use, since
I'd already done the K check in advance.

> and the insn supports neither memory nor register
> operands, this is impossible for reload to fix up.

Hmmm.  I was wondering whether I could put a memory operand
there, if that means it can fix it up regardless.  But that would
give it the idea that it can put a fullword there, when a halfword
operand is required, right?

> In addition, I don't quite understand how this pattern works in
> the first place; MH requires a memory operand, but this pattern
> seems to output an immediate value as operand.  Is there some
> magic going on in your assembler?

%H2 is ...

;; Special formats used for outputting 370 instructions.
;;
;;   %H -- Print a signed 16-bit constant.

in the i370.md documentation which can be seen here:

http://gcc.gnu.org/viewcvs/trunk/gcc/config/i370/i370.md?revision=71850&view=markup&pathrev=77215

(there's not a lot of technical changes since then, mainly
because no-one knew how to make them).

> If you indeed want to output immediate values here, you should

As opposed to wanting what?  All I want is the MH instruction
to be available for use, so that when someone writes x = x * 5,
it doesn't have to organize a register pair.

> probably define a new *predicate* that constrains the set of
> allowed values even before reload.

Ok, that should be straightforward if that's the best solution.

> In the s390 port, we're instead modelling the MH instruction
> with a memory operand (this still allows the generic parts of
> GCC to push immediate operands into memory, if they are in
> range for an HImode operand):
>
> (define_insn "*mulsi3_sign"
>  [(set (match_operand:SI 0 "register_operand" "=d")
>        (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R"))
>                 (match_operand:SI 1 "register_operand" "0")))]
>  ""
>  "mh\t%0,%2"
>  [(set_attr "op_type"  "RX")
>   (set_attr "type"     "imul")])

I tried a lot of variations to try to get this to fit into the i370
scheme, but didn't have any luck.

e.g. I managed to make this:

(define_insn ""
 [(set (match_operand:SI 0 "register_operand" "=d")
       (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "g"))
                (match_operand:SI 1 "register_operand" "0")))]
 ""
 "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 0);
  return \"MH^I%0,%2\";
}"
   [(set_attr "length" "4")]
)

produce:

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
         cfgloopanal.c
cfgloopanal.c: In function `average_num_loop_insns':
cfgloopanal.c:1379: error: unrecognizable insn:
(insn 68 67 71 7 (set (reg:SI 45)
        (mult:SI (reg:SI 44 [ <variable>.frequency ])
            (const_int 10000 [0x2710]))) -1 (insn_list 67 (nil))
    (expr_list:REG_DEAD (reg:SI 44 [ <variable>.frequency ])
        (nil)))

> This also seems broken.  A MULT:DI must have two DImode operands,
> it cannot have one DImode and one SImode operand.  Also, it is in
> fact incorrect that it takes the full DImode first operand; rather,
> it only uses the low 32-bit of its first operand as input.

Ok.

> In the s390 port we're modelling the real behavior of the instruction
> using two explicit SIGN_EXTEND codes:
>
> (define_insn "mulsidi3"
>  [(set (match_operand:DI 0 "register_operand" "=d,d")
>        (mult:DI (sign_extend:DI
>                   (match_operand:SI 1 "register_operand" "%0,0"))
>                 (sign_extend:DI
>                   (match_operand:SI 2 "nonimmediate_operand" "d,R"))))]

Ok.  That certainly looks better.

> Well, the point of optimization is that the RTXes do not stay the
> way they were originally expanded ...   The optimizers will attempt
> to perform various generic optimization on the code, and if the
> back-end claims to support a pattern that implements any of those
> optimized forms, it will get used.  In this case, even though you
> expanded a DImode multiply, common code may notice that it can
> be optimized to a SImode multiply instead.
>
> Generally speaking, your RTX patterns *must* be fully correct and
> represent the actual behavior of the machine in all cases.  If there
> are corner cases formally allowed by the RTX pattern, but the
> behavior of the machine differs, this may cause breakage.  Even if
> your expanders avoid those corner cases when using your patterns,
> this will not be true for the optimizers.

Ok.  It seems the proper way to go, but given that I don't know
how to integrate that into the existing code, it's probably better
for me to go with the new predicate, which I can very likely get
to work.

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-17 13:00       ` Paul Edwards
@ 2009-09-17 17:55         ` Ulrich Weigand
  2009-09-18  0:35           ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-09-17 17:55 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Joseph S. Myers, gcc

Paul Edwards wrote:

> > The combination of predicates and constraints on this insn is broken.
> >
> > Before reload, the predicate "immediate_operand" explicitly allows
> > *any* SImode immediate value.  However, during reload, the "K"
> > constraint accepts only a subset of values.
> 
> Is there a way to give a predicate that just says "look at the
> constraint"?

Not that I'm aware of.

> It seems a bit overkill to add a new predicate
> for this one instruction.

As an alternative to the operand predicate, you might also add
an extra check to the insn condition.  For example, something
along the following lines should work:

 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=d")
         (mult:SI (match_operand:SI 1 "register_operand" "0")
                  (match_operand:SI 2 "const_int_operand" "K")))]
   "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"

> > As there is no other alternative,
> 
> No other alternative for this same pattern, right?  There was an
> alternative - the pattern that I explictly asked it to use, since
> I'd already done the K check in advance.

I was using "alternative" in the sense of multi-alternative
constraints within a single insn pattern, yes.  Reload will
never switch to use a different insn pattern, it will only
select one of the existing alternatives in the pattern.

> > and the insn supports neither memory nor register
> > operands, this is impossible for reload to fix up.
> 
> Hmmm.  I was wondering whether I could put a memory operand
> there, if that means it can fix it up regardless.  But that would
> give it the idea that it can put a fullword there, when a halfword
> operand is required, right?

Yes, the memory operand would have to be HImode in that case.

> > In addition, I don't quite understand how this pattern works in
> > the first place; MH requires a memory operand, but this pattern
> > seems to output an immediate value as operand.  Is there some
> > magic going on in your assembler?
> 
> %H2 is ...
> 
> ;; Special formats used for outputting 370 instructions.
> ;;
> ;;   %H -- Print a signed 16-bit constant.

Yes, it prints an immediate *constant*.

> > If you indeed want to output immediate values here, you should
> 
> As opposed to wanting what?  All I want is the MH instruction
> to be available for use, so that when someone writes x = x * 5,
> it doesn't have to organize a register pair.

My point was that the MH instruction on an instruction set
architecture level *does not accept* an immediate operand,
but only a memory operand:

   MH     R1,D2(X2,B2)     [RX]

(There is a MULTIPLY HALFWORD IMMEDIATE (MHI) instruction as well, 
but I'm assuming you don't want to use it in the i370 port as that
instruction was added later on.)

So the usual way of using MH to multiply by an immediate value
is to place the constant into memory, typically some form of
literal pool.  But I see nothing in the i370 port that would
actually do that; instead, you seem to simply output the immediate
value itself into the assembler source.

If this works, it seems that the assembler will under the covers
manage a literal pool.  I was simply wondering if this is indeed
what you're relying on ...   (In the s390 port, the compiler will
always manage literal pools completely on its own and does never
rely on any assembler magic in that area.)

> e.g. I managed to make this:
> 
> (define_insn ""
>  [(set (match_operand:SI 0 "register_operand" "=d")
>        (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "g"))
>                 (match_operand:SI 1 "register_operand" "0")))]
>  ""
>  "*
> {
>   check_label_emit ();
>   mvs_check_page (0, 4, 0);
>   return \"MH^I%0,%2\";
> }"
>    [(set_attr "length" "4")]
> )
> 
> produce:
> 
> 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
>          cfgloopanal.c
> cfgloopanal.c: In function `average_num_loop_insns':
> cfgloopanal.c:1379: error: unrecognizable insn:
> (insn 68 67 71 7 (set (reg:SI 45)
>         (mult:SI (reg:SI 44 [ <variable>.frequency ])
>             (const_int 10000 [0x2710]))) -1 (insn_list 67 (nil))
>     (expr_list:REG_DEAD (reg:SI 44 [ <variable>.frequency ])
>         (nil)))

Well, in this case someone has to push the constant into a literal pool.
You can either do this at expand time by calling force_const_mem, or else
you have to change the predicate to also accept immediates before reload
(then reload will do the force_const_mem for you).  (Note that if you in
fact do not manage a literal pool in the compiler today but rely on the
assembler, as discussed above, this whole approach may be difficult.)

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-17 17:55         ` Ulrich Weigand
@ 2009-09-18  0:35           ` Paul Edwards
  2009-09-18 12:06             ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-09-18  0:35 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Joseph S. Myers, gcc

>> > The combination of predicates and constraints on this insn is broken.
>> >
>> > Before reload, the predicate "immediate_operand" explicitly allows
>> > *any* SImode immediate value.  However, during reload, the "K"
>> > constraint accepts only a subset of values.
>> 
>> Is there a way to give a predicate that just says "look at the
>> constraint"?
> 
> Not that I'm aware of.

This below was what I was hoping for ...

>> It seems a bit overkill to add a new predicate
>> for this one instruction.
> 
> As an alternative to the operand predicate, you might also add
> an extra check to the insn condition.  For example, something
> along the following lines should work:
> 
> (define_insn ""
>   [(set (match_operand:SI 0 "register_operand" "=d")
>         (mult:SI (match_operand:SI 1 "register_operand" "0")
>                  (match_operand:SI 2 "const_int_operand" "K")))]
>   "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"

My eyes lit up when I saw that!  However, it produced a compiler
error when I tried it.  But undeterred, I tried this:

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=d")
^I(mult:SI (match_operand:SI 1 "register_operand" "0")
^I^I (match_operand:SI 2 "immediate_operand" "K")))]
  "(GET_CODE (operands[2]) == CONST_INT
   && REG_P (operands[0])
   && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 0);
  return \"MH^I%0,%H2\";
}"
   [(set_attr "length" "4")]
)

And it worked (verified by self-compile)!  And I relaxed the 
constraint on the "M" instruction as well.  Those old warnings 
are apparently irrelevant now.  Thank you sir.  :-)

> My point was that the MH instruction on an instruction set
> architecture level *does not accept* an immediate operand,
> but only a memory operand:
> 
>   MH     R1,D2(X2,B2)     [RX]
> 
> (There is a MULTIPLY HALFWORD IMMEDIATE (MHI) instruction as well, 
> but I'm assuming you don't want to use it in the i370 port as that
> instruction was added later on.)

Oh, I understand now.

> So the usual way of using MH to multiply by an immediate value
> is to place the constant into memory, typically some form of
> literal pool.  But I see nothing in the i370 port that would
> actually do that; instead, you seem to simply output the immediate
> value itself into the assembler source.

Right, with an "=".

> If this works, it seems that the assembler will under the covers
> manage a literal pool.  I was simply wondering if this is indeed
> what you're relying on ...

Yes indeed.

And we go to a lot of effort to maintain the length of that literal
pool, so we know when we need to break out into a new page.

That's what this does:

>>   mvs_check_page (0, 4, 0);

Although, as usual, it's broken.  Needs to be (0, 4, 2) for the
4-byte instruction followed by the 2 bytes it will use from the
literal pool.

> (In the s390 port, the compiler will
> always manage literal pools completely on its own and does never
> rely on any assembler magic in that area.)

I see.  That explains one of the difficulties of trying to get s390
instruction definitions and use them on i370.  People keep asking
why I don't "just" use the s390 ones.  If only life were that
simple.  :-)

> Well, in this case someone has to push the constant into a literal pool.
> You can either do this at expand time by calling force_const_mem, or else
> you have to change the predicate to also accept immediates before reload
> (then reload will do the force_const_mem for you).  (Note that if you in
> fact do not manage a literal pool in the compiler today but rely on the
> assembler, as discussed above, this whole approach may be difficult.)

That's putting it mildly.  :-)

Anyway, with that out of the way, I'll take a look at the next one.
There's only one bug remaining that I know of, and 3 workarounds
that I would like to reverse out and fix properly.

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-18  0:35           ` Paul Edwards
@ 2009-09-18 12:06             ` Ulrich Weigand
  2009-09-18 12:23               ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-09-18 12:06 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Joseph S. Myers, gcc

Paul Edwards wrote:

> > As an alternative to the operand predicate, you might also add
> > an extra check to the insn condition.  For example, something
> > along the following lines should work:
> > 
> > (define_insn ""
> >   [(set (match_operand:SI 0 "register_operand" "=d")
> >         (mult:SI (match_operand:SI 1 "register_operand" "0")
> >                  (match_operand:SI 2 "const_int_operand" "K")))]
> >   "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
> 
> My eyes lit up when I saw that!  However, it produced a compiler
> error when I tried it.  But undeterred, I tried this:
> 
> (define_insn ""
>   [(set (match_operand:SI 0 "register_operand" "=d")
>         (mult:SI (match_operand:SI 1 "register_operand" "0")
>                  (match_operand:SI 2 "immediate_operand" "K")))]
>   "(GET_CODE (operands[2]) == CONST_INT
>    && REG_P (operands[0])
>    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"

Huh.  Instead of adding an explicit CONST_INT check, my approach
above used a const_int_operand predicate (instead of immediate_operand).
That should have had the exact same effect ...   I'm not sure why the
REG_P check on the other operand would be necessary at this point.

> And it worked (verified by self-compile)!  And I relaxed the 
> constraint on the "M" instruction as well.  Those old warnings 
> are apparently irrelevant now.  Thank you sir.  :-)

OK, that's good to know.

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-18 12:06             ` Ulrich Weigand
@ 2009-09-18 12:23               ` Paul Edwards
  2009-09-18 13:27                 ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-09-18 12:23 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Joseph S. Myers, gcc

>> > As an alternative to the operand predicate, you might also add
>> > an extra check to the insn condition.  For example, something
>> > along the following lines should work:
>> >
>> > (define_insn ""
>> >   [(set (match_operand:SI 0 "register_operand" "=d")
>> >         (mult:SI (match_operand:SI 1 "register_operand" "0")
>> >                  (match_operand:SI 2 "const_int_operand" "K")))]
>> >   "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
>>
>> My eyes lit up when I saw that!  However, it produced a compiler
>> error when I tried it.  But undeterred, I tried this:

Sorry.  I just copied the last line into the existing pattern, didn't
notice that you'd changed the predicate too.

>> (define_insn ""
>>   [(set (match_operand:SI 0 "register_operand" "=d")
>>         (mult:SI (match_operand:SI 1 "register_operand" "0")
>>                  (match_operand:SI 2 "immediate_operand" "K")))]
>>   "(GET_CODE (operands[2]) == CONST_INT
>>    && REG_P (operands[0])
>>    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
>
> Huh.  Instead of adding an explicit CONST_INT check, my approach
> above used a const_int_operand predicate (instead of immediate_operand).
> That should have had the exact same effect ...   I'm not sure why the
> REG_P check on the other operand would be necessary at this point.

I just copied that from the existing condition too.  Once I realised
that I could put a check in advance, I just copied the check
across basically.  I'd seen that before, it just hadn't sunk in that
I could use it for this situation.

I will try out your original suggestion again properly.  :-)

>> And it worked (verified by self-compile)!  And I relaxed the
>> constraint on the "M" instruction as well.  Those old warnings
>> are apparently irrelevant now.  Thank you sir.  :-)
>
> OK, that's good to know.

Indeed.

And as I mentioned, there's just one real bug that I know of left.  I can
bypass the bug in the GCC code that I am compiling, by forcing a
function call.

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
varasm.c: In function `force_const_mem':
varasm.c:3021: internal compiler error: in instantiate_virtual_regs_lossage, 
at
function.c:3765
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gccmvs.sourceforge.net> for instructions.

This is the code that is triggering off that bug:

force_const_mem (enum machine_mode mode, rtx x)
{
  int hash;
  struct constant_descriptor_rtx *desc;
...
    if (compare_constant_rtx (mode, x, desc))


static int
compare_constant_rtx (enum machine_mode mode, rtx x,
^I^I      struct constant_descriptor_rtx *desc)
{
  struct rtx_const value;

  decode_rtx_const (mode, x, &value);

  /* Compare constant contents.  */
#if defined(XTARGET_MVS) /* +++ seems we have a machine definition problem 
*/
  return (memcmp) (&value, &desc->value, sizeof (struct rtx_const)) == 0;
#else
  return memcmp (&value, &desc->value, sizeof (struct rtx_const)) == 0;
#endif
}


You can see how I normally work around this problem by forcing a
function call.

If I do that force, then I get this code generated:

L445     EQU   *
         LTR   3,3
         BE    L442
         MVC   88(4,13),0(11)
         MVC   92(4,13),4(11)
         LA    2,560(,13)
         ST    2,96(13)
         LA    1,88(,13)
         L     15,=A(@@F17)
         BALR  14,15
         ST    2,88(13)
         LR    2,3
         A     2,=F'8'
         ST    2,92(13)
         MVC   96(4,13),=F'196'
         LA    1,88(,13)
         L     15,=V(MEMCMP)
         BALR  14,15
         LTR   15,15

which is bizarre.  It seems to be comparing two values that are 8 bytes
apart, for a length of 196.  Can't imagine that doing anything useful.

It's almost certainly an i370 port bug, but I haven't had any bright
ideas on how to fix that yet.  :-)

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-18 12:23               ` Paul Edwards
@ 2009-09-18 13:27                 ` Ulrich Weigand
  2009-09-18 13:42                   ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-09-18 13:27 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Paul Edwards wrote:

> And as I mentioned, there's just one real bug that I know of left.  I can
> bypass the bug in the GCC code that I am compiling, by forcing a
> function call.
> 
> 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
> varasm.c: In function `force_const_mem':
> varasm.c:3021: internal compiler error: in instantiate_virtual_regs_lossage, 
> at
> function.c:3765
> Please submit a full bug report,
> with preprocessed source if appropriate.
> See <URL:http://gccmvs.sourceforge.net> for instructions.

That's a bit hard to diagnose without some further information ...

What insn it is failing on?  (To find out, use a debugger, or maybe
add a "debug_rtx (insn)" statement before the abort in 
instantiate_virtual_regs_lossage)?

> which is bizarre.  It seems to be comparing two values that are 8 bytes
> apart, for a length of 196.  Can't imagine that doing anything useful.

This is conceivably another effect of the same bug, but again it's
hard to say.  You'd have to look at the generated RTX and see how
it changes over the various optimization stages (use -da to generate
RTX dumps after each stage).

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-18 13:27                 ` Ulrich Weigand
@ 2009-09-18 13:42                   ` Paul Edwards
  2009-09-18 16:08                     ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-09-18 13:42 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

> That's a bit hard to diagnose without some further information ...
>
> What insn it is failing on?  (To find out, use a debugger, or maybe
> add a "debug_rtx (insn)" statement before the abort in
> instantiate_virtual_regs_lossage)?

I did the latter.

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
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gccmvs.sourceforge.net> for instructions.


Which would seem to correspond to this:

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

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=d")
^I(compare:SI (match_operand:BLK 1 "s_operand" "m")
^I^I (match_operand:BLK 2 "s_operand" "m")))
   (use (match_operand:QI 3 "immediate_operand" "I"))]
  "((unsigned) INTVAL (operands[3]) < 256)"
  "*
{
  check_label_emit ();
  mvs_check_page (0, 22, 0);
  return 
\"CLC^I%O1(%c3,%R1),%2\;BH^I*+12\;BL^I*+6\;SLR^I%0,%0\;LNR^I%0,%0\";
}"
   [(set_attr "length" "22")]
)


> This is conceivably another effect of the same bug, but again it's
> hard to say.  You'd have to look at the generated RTX and see how
> it changes over the various optimization stages (use -da to generate
> RTX dumps after each stage).

Ok, I'll see if I can see something.  Probably easier for me to play
around with the md though.

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-18 13:42                   ` Paul Edwards
@ 2009-09-18 16:08                     ` Ulrich Weigand
  2009-09-19 12:57                       ` Paul Edwards
                                         ` (2 more replies)
  0 siblings, 3 replies; 162+ messages in thread
From: Ulrich Weigand @ 2009-09-18 16:08 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Paul Edwards wrote:

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

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-18 16:08                     ` Ulrich Weigand
@ 2009-09-19 12:57                       ` Paul Edwards
  2009-09-25 10:19                       ` Paul Edwards
  2009-11-04  5:21                       ` i370 port Paul Edwards
  2 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-09-19 12:57 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

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

Ok, I spent today trying to solve this problem.  Although I didn't succeed
in solving it properly, I did at least find a workaround for the one 
instance.
I found that in the failing circumstance, neither of the two things being
compared fell into the "force copy" situation.  I don't know whether that
is right or wrong, but at least I can detect whether a "force copy" was
done.  If no force copy was done, I stop doing the short CLC and let
it do the CLCL instead.  See below where I have introduced the "copy"
variable.  Unfortunately it affects other things, ie good CLCs have been
converted into CLCL also, which is a shame.  However, it may at least
mean the compiler doesn't have a bug as far as the end user is
concerned, ie it generates valid code.

I have a theory that if both displacements in the S-type (ie register plus
displacement) address are non-zero, that something fails.  So the
next thing I will do is see if I can detect just that situation, and stop
it going into the CLC.

Some of these md constructs are beginning to make more sense.  :-)

BFN.  Paul.



;
; cmpmemsi instruction pattern(s).
;

(define_expand "cmpmemsi"
  [(set (match_operand:SI 0 "general_operand" "")
   (compare (match_operand:BLK 1 "general_operand" "")
     (match_operand:BLK 2 "general_operand" "")))
     (use (match_operand:SI 3 "general_operand" ""))
     (use (match_operand:SI 4 "" ""))]
   ""
   "
{
  rtx op1, op2;
  int copy = 0;

  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 = gen_rtx_MEM (BLKmode, copy_to_mode_reg (SImode, op1));
      copy = 1;
    }

  op2 = XEXP (operands[2], 0);
  if (GET_CODE (op2) == REG
      || (GET_CODE (op2) == PLUS && GET_CODE (XEXP (op2, 0)) == REG
   && GET_CODE (XEXP (op2, 1)) == CONST_INT
   && (unsigned) INTVAL (XEXP (op2, 1)) < 4096))
    {
      op2 = operands[2];
    }
  else
    {
      op2 = gen_rtx_MEM (BLKmode, copy_to_mode_reg (SImode, op2));
      copy = 1;
    }

  /* so long as at least one operand was copied, this seems safe */
  if (copy &&
      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],
   gen_rtx_COMPARE (SImode, op1, op2)), /* was VOIDmode */
  gen_rtx_USE (VOIDmode, operands[3]))));
    }
  else
    {
        /* implementation suggested by  Richard Henderson <rth@cygnus.com> 
*/
        rtx reg1 = gen_reg_rtx (DImode);
        rtx reg2 = gen_reg_rtx (DImode);
        rtx result = operands[0];
        rtx mem1 = operands[1];
        rtx mem2 = operands[2];
        rtx len = operands[3];
        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);

        /* Compare! */
        emit_insn (gen_cmpmemsi_1 (result, reg1, reg2));
    }
  DONE;
}")

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

(define_insn ""
  [(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)"
  "*
{
  check_label_emit ();
  mvs_check_page (0, 22, 0);
  return \"CLC %O1(%c3,%R1),%2\;BH *+12\;BL *+6\;SLR %0,%0\;LNR %0,%0\";
}"
   [(set_attr "length" "22")]
)

; Compare a block that is larger than 255 bytes in length.
;        (mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "+d") 
0))
;        (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "+d") 
0))))

(define_insn "cmpmemsi_1"
  [(set (match_operand:SI 0 "register_operand" "+d")
        (compare:SI
        (mem:BLK (match_operand:DI 1 "register_operand" "+d") )
        (mem:BLK (match_operand:DI 2 "register_operand" "+d") )))
   (use (match_dup 1))
   (use (match_dup 2))
   (clobber (match_dup 1))
   (clobber (match_dup 2))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 18, 0);
  return \"LA %0,1(0,0)\;CLCL %1,%2\;BH *+12\;BL *+6\;SLR %0,%0\;LNR 
%0,%0\";
}"
   [(set_attr "length" "18")]
)

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-18 16:08                     ` Ulrich Weigand
  2009-09-19 12:57                       ` Paul Edwards
@ 2009-09-25 10:19                       ` Paul Edwards
  2009-09-25 15:20                         ` Ulrich Weigand
  2009-11-04  5:21                       ` i370 port Paul Edwards
  2 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-09-25 10:19 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

Ulrich, here's one of the workarounds I mentioned.  The other one is
pretty similar to this one as well.

After my investigation, I've come to the conclusion that this never
worked, and was not noticed before, because the optimizer mustn't
have ever used it before.

As such, it's appropriate to simply comment it out (which was my
"workaround").  However, before I do so, do you think this is close
to being correct?  I already made one correction, to put in that
XL1 rather than doing a fullword (which was always zero obviously).


(define_insn "movstrictqi"
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+d"))
  (match_operand:QI 1 "general_operand" "g"))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[1]))
    {
      mvs_check_page (0, 8, 0);
      return \"STC^I%1,\" CONVLO \"(,13)\;IC^I%0,\" CONVLO \"(,13)\";
    }
  mvs_check_page (0, 4, 0);
  return \"IC^I%0,=XL1'%X1'\";
}"
   [(set_attr "length" "8")]
)


The trouble is that when the instruction is active, things like this
happen:

C:\devel\gccnew\gcc>diff -c6 old\alias.s new\alias.s | head -50
*** old\alias.s Tue Sep 22 09:37:45 2009
--- new\alias.s Fri Sep 25 16:38:31 2009
***************
*** 277,290 ****
  L26      EQU   *
           N     2,=XL4'000000FF'
           LA    3,242(0,0)
           CR    2,3
           BE    L30
           BH    L45
!          LA    3,241(0,0)
!          CLR   2,3
           BE    L28
           B     L44
  L45      EQU   *
           LA    3,243(0,0)
           CLR   2,3
           BE    L37
--- 277,289 ----
  L26      EQU   *
           N     2,=XL4'000000FF'
           LA    3,242(0,0)
           CR    2,3
           BE    L30
           BH    L45
!          IC    3,=XL1'F1'
           BE    L28
           B     L44
  L45      EQU   *
           LA    3,243(0,0)
           CLR   2,3
           BE    L37

Which I can clearly see is different.  Specifically, the IC by itself is 
fine,
although I would have preferred to see the LA instruction there, but for
some reason it is dropping the CLR.  That makes it technically
incorrect.

I checked the S/370 reference summary, and IC doesn't set the condition
code, and nor does the instruction pattern mention condition codes
anywhere.  Normally I would be suspicious of the rest of the compiler,
but in this case, I know that the compiler is stable and the i370
target is dubious.  :-)

After resolution of this one way or another, I think it's in a good enough
state for version 1.0 and will start on the preparations for all that.

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-25 10:19                       ` Paul Edwards
@ 2009-09-25 15:20                         ` Ulrich Weigand
  2009-09-30 17:24                           ` i370 port - constructing compile script Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-09-25 15:20 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Paul Edwards wrote:

> As such, it's appropriate to simply comment it out (which was my
> "workaround").  However, before I do so, do you think this is close
> to being correct?  I already made one correction, to put in that
> XL1 rather than doing a fullword (which was always zero obviously).
> 
> 
> (define_insn "movstrictqi"
>   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+d"))
>   (match_operand:QI 1 "general_operand" "g"))]
>   ""
>   "*
> {
>   check_label_emit ();
>   if (REG_P (operands[1]))
>     {
>       mvs_check_page (0, 8, 0);
>       return \"STC^I%1,\" CONVLO \"(,13)\;IC^I%0,\" CONVLO \"(,13)\";
>     }
>   mvs_check_page (0, 4, 0);
>   return \"IC^I%0,=XL1'%X1'\";
> }"
>    [(set_attr "length" "8")]
> )

The one obvious problem I see with this pattern is that the predicate
and constraint for operand 1 allow register, immediate and *memory*
operands, but the body seems to only handle register and immediate
operands correctly.

The STC followed by IC is of course correct, but will cause significant
penalities on all modern machines.  Just about any other way to load
the low byte (e.g. and with mask, then or) would be more efficient ...


> Which I can clearly see is different.  Specifically, the IC by itself is 
> fine,
> although I would have preferred to see the LA instruction there, but for
> some reason it is dropping the CLR.  That makes it technically
> incorrect.

This is odd.  I don't quite see why this would happen.  You should look
into the RTL dump files generated via -da to see where the compare insn
disappears ...

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* i370 port - constructing compile script
  2009-09-25 15:20                         ` Ulrich Weigand
@ 2009-09-30 17:24                           ` Paul Edwards
  2009-09-30 17:36                             ` Richard Henderson
  2009-10-01 14:28                             ` Paul Brook
  0 siblings, 2 replies; 162+ messages in thread
From: Paul Edwards @ 2009-09-30 17:24 UTC (permalink / raw)
  To: gcc

What is the best way to go from this:

Makefile:

C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o 
c-typeck.o \
  c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \

C_OBJS = c-lang.o stub-objc.o $(C_AND_OBJC_OBJS)

OBJS-common = \
^Iinsn-attrtab.o \
^Iinsn-automata.o \
^Iinsn-emit.o \
^Iinsn-extract.o \

to:

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
call stdcomp builtins.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcomp caller-save.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcomp calls.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcomp c-aux-info.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcomp c-common.c %1 %2 %3 %4 %5 %6 %7 %8 %9

and then finally to:

//ALIAS    EXEC ST2CMP,MEMBER=ALIAS
//ALLOC@PO EXEC ST2CMP,MEMBER=ALLOC@PO
//ATTRIBS  EXEC ST2CMP,MEMBER=ATTRIBS
//BB@REORD EXEC ST2CMP,MEMBER=BB@REORD
//BITMAP   EXEC ST2CMP,MEMBER=BITMAP
//BT@LOAD  EXEC ST2CMP,MEMBER=BT@LOAD
//BUILTINS EXEC ST2CMP,MEMBER=BUILTINS
//CALLER@S EXEC ST2CMP,MEMBER=CALLER@S
//CALLS    EXEC ST2CMP,MEMBER=CALLS
//C@AUX@IN EXEC ST2CMP,MEMBER=C@AUX@IN
//C@COMMON EXEC ST2CMP,MEMBER=C@COMMON


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 '@'.

I assume I need a C program to do such a conversion.  I'm happy
to write that C program.  But what's the best way to work with
the existing infrastructure when writing and running that C
program?

One idea I had was to have a target that listed all the variables,
and then just had an "echo" as the rule to make the ".o" from
".c", and then I could just go "make" to get all the object files
listed out, and then I run a separate C program to convert that
into the various scripts.

Note that the objective is to basically get a list (in the above
format) of all necessary C source in order to be able to compile
(to assembler, not .o) C programs.  I will be building a single
executable, ie combining the C front end and i370 back end
into a single executable.  I know that it is possible, because
I already have it working (on 3.4.6).  Now the objective is to do
it properly.  :-)

Also note that I'm not 100% sure what variables to use to get
the minimum required source, although I would guess
GCC_OBJS, C_OBJS plus the individual files listed in
ALL_HOST_OBJS.  This would be something that would be
good to have an explicit variable for - the minimum C files
required in the process of converting C to assembler (even
though in normal configurations, those C files reside in
different executables).  So I would like to define such a
variable prior to doing the above.

Thanks.  Paul.


P.S. Here are the (intrusive) changes I have had to make so far
to get (maybe 3/4 of) GCC 4.4 to compile on a C90-only platform:

Index: gcc/system.h
===================================================================
RCS file: /cvsroot/gcc4/gcc/system.h,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 system.h
180a181
> #ifdef HAVE_SYS_TYPES_H
181a183
> #endif
Index: include/sort.h
===================================================================
RCS file: /cvsroot/gcc4/include/sort.h,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 sort.h
24a25
> #ifdef HAVE_SYS_TYPES_H
25a27
> #endif
Index: libcpp/include/cpplib.h
===================================================================
RCS file: /cvsroot/gcc4/libcpp/include/cpplib.h,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 cpplib.h
26a27
> #ifdef HAVE_SYS_TYPES_H
27a29,30
> #endif
>
542,543c545,546
<   ino_t ino;
<   dev_t dev;
---
>   /* ino_t ino; */
>   /* dev_t dev; */
Index: libiberty/xmemdup.c
===================================================================
RCS file: /cvsroot/gcc4/libiberty/xmemdup.c,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 xmemdup.c
23a24
> #ifdef HAVE_SYS_TYPES_H
24a26
> #endif
Index: libiberty/xstrdup.c
===================================================================
RCS file: /cvsroot/gcc4/libiberty/xstrdup.c,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 xstrdup.c
18a19
> #ifdef HAVE_SYS_TYPES_H
19a21
> #endif

ie very little.

Not sure what the proper way to deal with that ino_t and dev_t is, but in
the past I've simply created my own typedefs:

typedef int ino_t;
typedef int dev_t;

and included them in config.h

But I'll deal with that after I've got a comprehensive list of source files.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-09-30 17:24                           ` i370 port - constructing compile script Paul Edwards
@ 2009-09-30 17:36                             ` Richard Henderson
  2009-09-30 21:40                               ` Paul Edwards
  2009-10-01 14:28                             ` Paul Brook
  1 sibling, 1 reply; 162+ messages in thread
From: Richard Henderson @ 2009-09-30 17:36 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

On 09/30/2009 08:00 AM, Paul Edwards wrote:
> What is the best way to go from this:
>
> Makefile:

The easy way to convert a Makefile to a shell script is "make -n".  That 
will print out all of the commands that make would run.  From there it's 
a Mere Matter of Programming to have perl (or whatever) edit that down 
into your JCL scripts.


r~

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-09-30 17:36                             ` Richard Henderson
@ 2009-09-30 21:40                               ` Paul Edwards
       [not found]                                 ` <mcrpr98x9w8.fsf@dhcp-172-17-9-151.mtv.corp.google.com>
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-09-30 21:40 UTC (permalink / raw)
  To: Richard Henderson; +Cc: gcc

>> What is the best way to go from this:
>>
>> Makefile:
>
> The easy way to convert a Makefile to a shell script is "make -n".  That 
> will print out all of the commands that make would run.  From there it's a 
> Mere Matter of Programming to have perl (or whatever) edit that down into 
> your JCL scripts.

Hi Richard.  Thanks for your reply.

1. That would include a lot of irrelevant commands - compiles and
links of the generator files interspersed with what I actually need
to go into the stage 1 executable on the target machine.

Maybe a variable STAGE1_OBJS would be suitable?

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???


BTW, I remember your name from the i370 md.  Why were you
interested in i370 at the time (probably many years ago)?  Or
was someone else just asking a public question and you
answered it (like now)?

BFN.  Paul.



  else
    {
        /* implementation suggested by  Richard Henderson <rth@cygnus.com> 
*/
        rtx reg1 = gen_reg_rtx (DImode);
        rtx reg2 = gen_reg_rtx (DImode);
        rtx result = operands[0];
        rtx mem1 = operands[1];
        rtx mem2 = operands[2];
        rtx len = operands[3];
        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)),

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

        /* Compare! */
        emit_insn (gen_cmpmemsi_1 (result, reg1, reg2));
    }
  DONE;
}")

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
       [not found]                                 ` <mcrpr98x9w8.fsf@dhcp-172-17-9-151.mtv.corp.google.com>
@ 2009-10-01  0:16                                   ` Joseph S. Myers
  2009-10-01 14:00                                     ` Paul Edwards
  2009-10-02 12:41                                     ` Paul Edwards
  0 siblings, 2 replies; 162+ messages in thread
From: Joseph S. Myers @ 2009-10-01  0:16 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Paul Edwards, Richard Henderson, gcc

On Wed, 30 Sep 2009, Ian Lance Taylor wrote:

> "Paul Edwards" <mutazilah@gmail.com> writes:
> 
> > 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.
> 
> The "normal way to do things" is to use GNU make.  I think you are the
> first person trying to build gcc without it.

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

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-01  0:16                                   ` Joseph S. Myers
@ 2009-10-01 14:00                                     ` Paul Edwards
  2009-10-02 12:41                                     ` Paul Edwards
  1 sibling, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-10-01 14:00 UTC (permalink / raw)
  To: Joseph S. Myers, Ian Lance Taylor; +Cc: Richard Henderson, gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-09-30 17:24                           ` i370 port - constructing compile script Paul Edwards
  2009-09-30 17:36                             ` Richard Henderson
@ 2009-10-01 14:28                             ` Paul Brook
  2009-10-01 16:00                               ` Paul Edwards
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Brook @ 2009-10-01 14:28 UTC (permalink / raw)
  To: gcc; +Cc: 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. My guess is 
that getting gcc hosted in a bizarre environment is much easier than getting 
the gcc build system working. Trying to bootstrap gcc there seems like a lot 
of pain for no real benefit.

Paul

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-01 14:28                             ` Paul Brook
@ 2009-10-01 16:00                               ` Paul Edwards
  2009-10-01 18:36                                 ` Ian Lance Taylor
  2009-10-01 21:10                                 ` David Edelsohn
  0 siblings, 2 replies; 162+ messages in thread
From: Paul Edwards @ 2009-10-01 16:00 UTC (permalink / raw)
  To: Paul Brook, gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-01 16:00                               ` Paul Edwards
@ 2009-10-01 18:36                                 ` Ian Lance Taylor
  2009-10-01 23:43                                   ` Paul Edwards
  2009-10-01 21:10                                 ` David Edelsohn
  1 sibling, 1 reply; 162+ messages in thread
From: Ian Lance Taylor @ 2009-10-01 18:36 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Paul Brook, gcc

"Paul Edwards" <mutazilah@gmail.com> writes:

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

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.

Ian

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-01 16:00                               ` Paul Edwards
  2009-10-01 18:36                                 ` Ian Lance Taylor
@ 2009-10-01 21:10                                 ` David Edelsohn
  2009-10-01 22:22                                   ` Toon Moene
  1 sibling, 1 reply; 162+ messages in thread
From: David Edelsohn @ 2009-10-01 21:10 UTC (permalink / raw)
  To: Paul Edwards; +Cc: GCC Development

On Thu, Oct 1, 2009 at 11:59 AM, Paul Edwards <mutazilah@gmail.com> wrote:

>>> 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 '@'.

Paul,

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.

David

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-01 21:10                                 ` David Edelsohn
@ 2009-10-01 22:22                                   ` Toon Moene
  2009-10-02  0:19                                     ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Toon Moene @ 2009-10-01 22:22 UTC (permalink / raw)
  To: David Edelsohn; +Cc: Paul Edwards, GCC Development

David Edelsohn wrote:

> On Thu, Oct 1, 2009 at 11:59 AM, Paul Edwards <mutazilah@gmail.com> wrote:

>>>> 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 '@'.

> Paul,
> 
> 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.

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

[ 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. ]

-- 
Toon Moene - e-mail: toon@moene.org - phone: +31 346 214290
Saturnushof 14, 3738 XG  Maartensdijk, The Netherlands
At home: http://moene.org/~toon/
Progress of GNU Fortran: http://gcc.gnu.org/gcc-4.5/changes.html

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-01 18:36                                 ` Ian Lance Taylor
@ 2009-10-01 23:43                                   ` Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-10-01 23:43 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Paul Brook, gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-01 22:22                                   ` Toon Moene
@ 2009-10-02  0:19                                     ` Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-10-02  0:19 UTC (permalink / raw)
  To: Toon Moene, David Edelsohn; +Cc: GCC Development

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-01  0:16                                   ` Joseph S. Myers
  2009-10-01 14:00                                     ` Paul Edwards
@ 2009-10-02 12:41                                     ` Paul Edwards
  2009-10-02 16:00                                       ` Ian Lance Taylor
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-10-02 12:41 UTC (permalink / raw)
  To: Joseph S. Myers, Ian Lance Taylor; +Cc: Richard Henderson, gcc

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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-02 12:41                                     ` Paul Edwards
@ 2009-10-02 16:00                                       ` Ian Lance Taylor
  2009-10-02 22:53                                         ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ian Lance Taylor @ 2009-10-02 16:00 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Joseph S. Myers, Richard Henderson, gcc

"Paul Edwards" <mutazilah@gmail.com> writes:

> 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.
* Write a cross-assembler and cross-linker.
* Copy header files and libraries from the host (MVS).

Now you have a complete cross-toolchain running on a supported host
which can produce executables which run on MVS.

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


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


> 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.  They
would copy the files to MVS, run the real assembler and linker, and
copy the output back.  That would be more than 20 lines, but it seems
doable to me.

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.

Ian

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-02 16:00                                       ` Ian Lance Taylor
@ 2009-10-02 22:53                                         ` Paul Edwards
  2009-10-04  4:11                                           ` Ian Lance Taylor
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-10-02 22:53 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Joseph S. Myers, Richard Henderson, gcc

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] != NULL)
+          {
+              cnt++;
+          }
+          if (strcmp(string, "cc1") == 0)
+          {
+              ret_code = toplev_main(cnt, commands[i].argv);
+              if (ret_code != 0) break;
+          }
+       }
+ #else
        /* For some bizarre reason, the second argument of execvp() is
         char *const *, not const char *const *.  */
        commands[i].pid = pexecute (string, (char *const *) 
commands[i].argv,

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-02 22:53                                         ` Paul Edwards
@ 2009-10-04  4:11                                           ` Ian Lance Taylor
  2009-10-04  5:14                                             ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ian Lance Taylor @ 2009-10-04  4:11 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

"Paul Edwards" <mutazilah@gmail.com> writes:

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


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


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


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


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.

Ian

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-04  4:11                                           ` Ian Lance Taylor
@ 2009-10-04  5:14                                             ` Paul Edwards
  2009-10-04  6:04                                               ` Ian Lance Taylor
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-10-04  5:14 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc

>>> * 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 it
will come down to one line of code or one extra configure
parameter, but it'll probably take days of experimentation
to find that.

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-04  5:14                                             ` Paul Edwards
@ 2009-10-04  6:04                                               ` Ian Lance Taylor
  2009-10-04  6:50                                                 ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ian Lance Taylor @ 2009-10-04  6:04 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

"Paul Edwards" <mutazilah@gmail.com> writes:

>>>> * 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.  fputs_unlocked is called by gcc itself, not by target
code; 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.

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.


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

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

gcc has no confusion between the headers on the host system and the
headers on the target system.  I don't know precisely how to map that
onto your comment about the build system and the headers used when
cross-compiling.


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

If you can demonstrate that 20 line configure script change, then we
can certainly discuss it.  I personally am rather skeptical that you
can rewire gcc's build process in 20 lines.

Ian

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-04  6:04                                               ` Ian Lance Taylor
@ 2009-10-04  6:50                                                 ` Paul Edwards
  2009-10-04 15:38                                                   ` Ulrich Weigand
  2009-10-05 13:17                                                   ` Michael Matz
  0 siblings, 2 replies; 162+ messages in thread
From: Paul Edwards @ 2009-10-04  6:50 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc

>>>>> * 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 %7 %8 %9
call stdcompm bb-reorder.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcompm bitmap.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcompm bt-load.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcompm builtins.c %1 %2 %3 %4 %5 %6 %7 %8 %9
call stdcompm caller-save.c %1 %2 %3 %4 %5 %6 %7 %8 %9

stdcompm.bat:
gccmvs -DUSE_MEMMGR -Os -S -ansi -pedantic-errors -DHAVE_CONFIG_H -DIN_GCC 
...

Once I have the assembler code, I zip it up, then use my Linux-generated
JCL and pass it all over to MVS to see if it can assemble a stage 1
executable, which is how I have a 3.4.6 MVS executable.

>> 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.
>
> gcc has no confusion between the headers on the host system and the
> headers on the target system.  I don't know precisely how to map that
> onto your comment about the build system and the headers used when
> cross-compiling.

Ok, I'm lost even further up the process now.

I'm not sure whether to call MVS a target or host.

>> 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.
>
> If you can demonstrate that 20 line configure script change, then we
> can certainly discuss it.  I personally am rather skeptical that you
> can rewire gcc's build process in 20 lines.

It's about 20 lines of intrusive code to combine GCC into a single
executable, bypassing the need for a system() or similar call.

Why would this be any different?

The gcc build process *already* compiles each module.

All I need to do is restrict the list of modules, and add the "-S"
option, and then tell it to not complain about the ".o" not being
generated, because I produced a ".s" instead.

Doesn't sound like a lot of work if I can figure out where to put
it, and the "-S" and a touch of ".o" can go into an external
script to even eliminate that intrusion!  :-)

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-04  6:50                                                 ` Paul Edwards
@ 2009-10-04 15:38                                                   ` Ulrich Weigand
  2009-10-04 22:51                                                     ` Paul Edwards
  2009-10-05 13:17                                                   ` Michael Matz
  1 sibling, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-10-04 15:38 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ian Lance Taylor, gcc

Paul Edwards wrote:

> I'm not sure whether to call MVS a target or host.

Maybe it helps to take a step back and look at how the process
of initially getting a compiler for a system B built, starting
on an existing system A, usually works.

Each of the following steps can be identified by three systems:
- the "build" system (where the compiler build process runs)
- the "host" system (where the resulting compiler will run)
- the "target" system (where executables built by that compiler run)

Using this terminology, we need the following four stages:
(In your case, A would be "Linux on Intel", and B would be "MVS".)

1. build == A, host == A, target == A

This is the compiler you start out with, a native compiler for the A
system.  (You already have that, you do not need to rebuild it.)

2. build == A, host == A, target == B

This is a cross-compiler for B, running on A, which is itself built
on A using the compiler from 1.

3. build == A, host == B, target == B

This is a native B compiler, but it is *built* on A, using the A->B
cross-compiler from 2.  (This way of building a compiler is sometimes
refered to as a "Canadian cross".)

4. build == B, host == B, target == B

This step is optional, but using the native B compiler from 3., you
could now rebuild the compiler once again, this time on B itself.
At this point, B is fully supported and able to bootstrap its compiler
without any assistance from another system.


As there is nothing to do for step 1, and step 4 is optional, the
interesting parts are steps 2 and 3.  These are two separate build steps,
targeting different host systems to run the resulting compiler on.

As the properties of the host system (e.g. does it have "fork"
or "getrusage" or whatever) are detected at build time during
the "configure" step, you need to have a separate configure run
for step 2 and step 3.  Note that configure works but attempting
to compile and/or link small test programs.

In step 2, configure will use the host A compiler (from step 1) to
do these trial compiles.  The host A compiler will use the host A
header files and libaries, and thus configure will detect properties
of system A (which is correct, as in step 2, "host" == A).

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.

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.


I'm not sure if this helps, but I hope this might have at least
clarified a bit some of the terminology being used ...

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-04 15:38                                                   ` Ulrich Weigand
@ 2009-10-04 22:51                                                     ` Paul Edwards
  2009-10-05 13:15                                                       ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-10-04 22:51 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Ian Lance Taylor, gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-04 22:51                                                     ` Paul Edwards
@ 2009-10-05 13:15                                                       ` Ulrich Weigand
  2009-10-06  9:32                                                         ` Paul Edwards
  2009-10-19 14:19                                                         ` Paul Edwards
  0 siblings, 2 replies; 162+ messages in thread
From: Ulrich Weigand @ 2009-10-05 13:15 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ian Lance Taylor, gcc

Paul Edwards wrote:

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

Then you need to build and install the cross-compiler (using
make and make install).   For the subsequent step, you need to
make the cross-compiler available in the PATH.

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

This configure run will then use the i370-mvs-gcc cross-compiler
you built in step 2 in order to detect MVS host properties.

> Or does the configure process attempt to run the executables
> as well?

No, that wouldn't work (the exectuables are for a different architecture
than the build system ...).

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

I don't think GCC needs to know the stack direction of the *host*
system.  (It does need to know the stack direction of the *target*
system, but this is not detected by configure, but determined by
target macro settings from the config/i370/*.h files.)

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-04  6:50                                                 ` Paul Edwards
  2009-10-04 15:38                                                   ` Ulrich Weigand
@ 2009-10-05 13:17                                                   ` Michael Matz
  2009-10-05 13:38                                                     ` Paul Edwards
  1 sibling, 1 reply; 162+ messages in thread
From: Michael Matz @ 2009-10-05 13:17 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ian Lance Taylor, gcc

Hi,

On Sun, 4 Oct 2009, Paul Edwards wrote:

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

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

/tmp/compile will now fill up with the commands to use.  If you don't need 
the various options, also add "ALL_COMPILERFLAGS= ALL_CPPFLAGS=" to the 
make command (might be other variable names in the old 4.x compilers), or 
amend the collect-stuff.sh script to not echo them.

Remember to clean the build dir before doing this as otherwise some .o 
files aren't remade.


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-05 13:17                                                   ` Michael Matz
@ 2009-10-05 13:38                                                     ` Paul Edwards
  2009-10-05 13:46                                                       ` Michael Matz
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-10-05 13:38 UTC (permalink / raw)
  To: Michael Matz, Ulrich Weigand; +Cc: Ian Lance Taylor, gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-05 13:38                                                     ` Paul Edwards
@ 2009-10-05 13:46                                                       ` Michael Matz
  0 siblings, 0 replies; 162+ messages in thread
From: Michael Matz @ 2009-10-05 13:46 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ulrich Weigand, Ian Lance Taylor, gcc

Hi,

On Tue, 6 Oct 2009, Paul Edwards wrote:

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

Add whatever targets you need:

make CC=collect-stuff.sh cc1 xgcc

If you also need some libraries that are normally linked into xgcc or cc1 
(probably at least libiberty and libcpp) do

make CC=collect-stuff.sh -C ../libiberty

too (after having configured everything already).  You'll figure out the 
missing stuff :)


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-05 13:15                                                       ` Ulrich Weigand
@ 2009-10-06  9:32                                                         ` Paul Edwards
  2009-10-06 13:15                                                           ` Ulrich Weigand
  2009-10-19 14:19                                                         ` Paul Edwards
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-10-06  9:32 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Ian Lance Taylor, gcc

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

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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-06  9:32                                                         ` Paul Edwards
@ 2009-10-06 13:15                                                           ` Ulrich Weigand
  2009-10-06 13:38                                                             ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-10-06 13:15 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ian Lance Taylor, gcc

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 <defunct>.
> 
> 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?  For the cross-compiler,
you shouldn't need any of the MVS host-specific patches ...

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

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 <stdio.h>, 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.)


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

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-06 13:15                                                           ` Ulrich Weigand
@ 2009-10-06 13:38                                                             ` Paul Edwards
  2009-10-06 14:01                                                               ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-10-06 13:38 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Ian Lance Taylor, gcc

>> 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 <defunct>.
>> 
>> 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 <stdio.h>, 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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-06 13:38                                                             ` Paul Edwards
@ 2009-10-06 14:01                                                               ` Ulrich Weigand
  2009-10-14 14:33                                                                 ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-10-06 14:01 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ian Lance Taylor, gcc

Paul Edwards wrote:

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

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

Host vs. target confusion again? :-)  You have some patches needed
to support MVS as *target* of compilation.  You have some other
patches needed to support MVS as *host* of the compiler itself.

I'm saying that for the cross-compiler, you need the first set
of patches, but you do not need the second set of patches.

For the native compiler, you'll then need both sets ...

> > However, once you *run* this i370-mvs-gcc, and it processes a source
> > file using #include <stdio.h>, 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.

I'm not sure how this works on MVS, but the C standard says that if
your application uses #include <stdio.h>, this must work and find
the appropriate system header ...

When running the compiler natively on MVS, there may not be a notion
of "directories" in the Unix sense, but I guess those headers must
still come from *somewhere*, right?

For the *cross-compiler*, because it is hosted on a Unix system, it
must provide those same headers in a directory somewhere.  This is
the directory you specify via --with-sysroot.

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-06 14:01                                                               ` Ulrich Weigand
@ 2009-10-14 14:33                                                                 ` Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-10-14 14:33 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Ian Lance Taylor, gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-05 13:15                                                       ` Ulrich Weigand
  2009-10-06  9:32                                                         ` Paul Edwards
@ 2009-10-19 14:19                                                         ` Paul Edwards
  2009-10-19 17:37                                                           ` Ulrich Weigand
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-10-19 14:19 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Ian Lance Taylor, gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-19 14:19                                                         ` Paul Edwards
@ 2009-10-19 17:37                                                           ` Ulrich Weigand
  2009-10-20 14:18                                                             ` Paul Edwards
  2009-11-12 14:03                                                             ` Paul Edwards
  0 siblings, 2 replies; 162+ messages in thread
From: Ulrich Weigand @ 2009-10-19 17:37 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ian Lance Taylor, gcc

Paul Edwards wrote:

> 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 $*

Maybe a more generic way to work around the missing assembler and linker
would be to provide dummy scripts i370-mvspdp-as 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 ...

This would allow usual build processes (including "make") to proceed as
expected.

> > 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!

That should be fine.  (The --with-build-sysroot option may actually not
be required at all when building just a C compiler.)

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

The compiler error output found in the config.log file should hopefully
point to the problem ...

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-19 17:37                                                           ` Ulrich Weigand
@ 2009-10-20 14:18                                                             ` Paul Edwards
  2009-10-20 15:30                                                               ` Ulrich Weigand
  2009-11-12 14:03                                                             ` Paul Edwards
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-10-20 14:18 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

>> ../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 -0000 1.1.1.1
--- configure 20 Oct 2009 12:39:48 -0000 1.8
***************
*** 2463,2470 ****
  /* end confdefs.h.  */
  #include <stdarg.h>
  #include <stdio.h>
! #include <sys/types.h>
! #include <sys/stat.h>
  /* 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 <stdarg.h>
  #include <stdio.h>
! /*#include <sys/types.h>
! #include <sys/stat.h>*/
  /* 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 <sys/types.h>


  int
--- 3377,3383 ----
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  #include "confdefs.h"
! /*#include <sys/types.h>*/


  int
***************
*** 3448,3454 ****
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  #include "confdefs.h"
! #include <sys/types.h>


  int
--- 3448,3454 ----
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  #include "confdefs.h"
! /*#include <sys/types.h>*/


  int
***************
*** 3519,3525 ****
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  #include "confdefs.h"
! #include <sys/types.h>


  int
--- 3519,3525 ----
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  #include "confdefs.h"
! /*#include <sys/types.h>*/


  int
***************
*** 3590,3596 ****
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  #include "confdefs.h"
! #include <sys/types.h>


  int
--- 3590,3596 ----
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  #include "confdefs.h"
! /*#include <sys/types.h>*/


  int
***************
*** 3662,3668 ****
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  #include "confdefs.h"
! #include <sys/types.h>


  int
--- 3662,3668 ----
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  #include "confdefs.h"
! /*#include <sys/types.h>*/


  int
***************
*** 3735,3741 ****
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  #include "confdefs.h"
! #include <sys/types.h>


  int
--- 3735,3741 ----
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  #include "confdefs.h"
! /*#include <sys/types.h>*/


  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 <sys/types.h>
! #include <sys/param.h>
  int
  main ()
  {
--- 6150,6160 ----
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
! /*#include <sys/types.h>
! #include <sys/param.h>*/
! #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 <sys/types.h>
! #include <sys/param.h>
  int
  main ()
  {
--- 6195,6205 ----
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
! /*#include <sys/types.h>
! #include <sys/param.h>*/
! #define BIG_ENDIAN 1
! #define LITTLE_ENDIAN 2
! #define BYTE_ORDER 1
  int
  main ()
  {
***************
*** 6731,6738 ****
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
! #include <sys/types.h>
! #include <inttypes.h>
  int
  main ()
  {
--- 6737,6744 ----
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
! /*#include <sys/types.h>
! #include <inttypes.h>*/
  int
  main ()
  {
***************
*** 7051,7057 ****
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
! #include <sys/types.h>

  _ACEOF
  if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
--- 7057,7063 ----
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
! /*#include <sys/types.h>*/

  _ACEOF
  if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
***************
*** 7093,7099 ****
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  /* Thanks to Mike Rendell for this test.  */
! #include <sys/types.h>
  #define NGID 256
  #undef MAX
  #define MAX(x, y) ((x) > (y) ? (x) : (y))
--- 7099,7105 ----
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  /* Thanks to Mike Rendell for this test.  */
! /*#include <sys/types.h>*/
  #define NGID 256
  #undef MAX
  #define MAX(x, y) ((x) > (y) ? (x) : (y))
***************
*** 7303,7311 ****
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
! #include <sys/types.h>
  #include <sys/mman.h>
! #include <unistd.h>

  #ifndef MAP_ANONYMOUS
  #define MAP_ANONYMOUS MAP_ANON
--- 7309,7317 ----
  cat confdefs.h >>conftest.$ac_ext
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
! /*#include <sys/types.h>
  #include <sys/mman.h>
! #include <unistd.h>*/

  #ifndef MAP_ANONYMOUS
  #define MAP_ANONYMOUS MAP_ANON
***************
*** 7644,7650 ****
  else
    cat >conftest.$ac_ext <<_ACEOF
  /* By Ruediger Kuhlmann. */
!       #include <sys/types.h>
        #if HAVE_UNISTD_H
        # include <unistd.h>
        #endif
--- 7650,7656 ----
  else
    cat >conftest.$ac_ext <<_ACEOF
  /* By Ruediger Kuhlmann. */
!       /*#include <sys/types.h>*/
        #if HAVE_UNISTD_H
        # include <unistd.h>
        #endif
***************
*** 7717,7725 ****
  /* Thanks to Paul Eggert for this test.  */
  #include <stdio.h>
  #include <stdlib.h>
! #include <sys/types.h>
  #include <sys/stat.h>
! #include <sys/wait.h>
  #if HAVE_UNISTD_H
  # include <unistd.h>
  #endif
--- 7723,7731 ----
  /* Thanks to Paul Eggert for this test.  */
  #include <stdio.h>
  #include <stdlib.h>
! /*#include <sys/types.h>
  #include <sys/stat.h>
! #include <sys/wait.h>*/
  #if HAVE_UNISTD_H
  # include <unistd.h>
  #endif
***************
*** 8998,9004 ****
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */

! #include <sys/types.h>
  #ifdef HAVE_SYS_STAT_H
  # include <sys/stat.h>
  #endif
--- 9004,9010 ----
  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */

! /*#include <sys/types.h>*/
  #ifdef HAVE_SYS_STAT_H
  # include <sys/stat.h>
  #endif

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-20 14:18                                                             ` Paul Edwards
@ 2009-10-20 15:30                                                               ` Ulrich Weigand
  0 siblings, 0 replies; 162+ messages in thread
From: Ulrich Weigand @ 2009-10-20 15:30 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Paul Edwards wrote:

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

Ah, you'll probably have to re-run configure and rebuild the cross compiler.
The configure/build process checks for the presence of the cross-assembler
and decides which one to use.

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

Hmm, it seems configure does use a couple of fallbacks to determine
byte order if sys/param.h doesn't exist, but those require a working
cross-assembler ...

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

Generally speaking, the configure process should work on non-POSIX
systems that don't provide those headers.  But it may well be that
something is broken in this case; this will be rarely tested ...

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

See above; you should try to rebuild the cross-compiler first.


> Index: configure
> ===================================================================
> RCS file: /cvsroot/gccnew/gcc/configure,v

For now, just patching configure to see how far you get is of course fine.
Longer term, however, note that configure is a generated file.  You'd have
to make those changes either in configure.ac or possible within the
autoconf machinery that generates the file.

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-18 16:08                     ` Ulrich Weigand
  2009-09-19 12:57                       ` Paul Edwards
  2009-09-25 10:19                       ` Paul Edwards
@ 2009-11-04  5:21                       ` Paul Edwards
  2009-11-04 16:47                         ` Ulrich Weigand
  2 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-11-04  5:21 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-11-04  5:21                       ` i370 port Paul Edwards
@ 2009-11-04 16:47                         ` Ulrich Weigand
  2009-11-09 14:55                           ` Paul Edwards
  2011-08-13  8:34                           ` Paul Edwards
  0 siblings, 2 replies; 162+ messages in thread
From: Ulrich Weigand @ 2009-11-04 16:47 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Paul Edwards wrote:

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

Ah, OK.  That would explain it.

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-11-04 16:47                         ` Ulrich Weigand
@ 2009-11-09 14:55                           ` Paul Edwards
  2009-11-09 15:57                             ` Ian Lance Taylor
  2011-08-13  8:34                           ` Paul Edwards
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-11-09 14:55 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-11-09 14:55                           ` Paul Edwards
@ 2009-11-09 15:57                             ` Ian Lance Taylor
  2009-11-09 23:10                               ` Paul Edwards
                                                 ` (2 more replies)
  0 siblings, 3 replies; 162+ messages in thread
From: Ian Lance Taylor @ 2009-11-09 15:57 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ulrich Weigand, gcc

"Paul Edwards" <mutazilah@gmail.com> writes:

> 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.
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
PURE_ISO_C90 might be right here.

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.

Ian

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-11-09 15:57                             ` Ian Lance Taylor
@ 2009-11-09 23:10                               ` Paul Edwards
  2009-11-10 14:58                               ` Paul Edwards
  2009-11-10 15:51                               ` Paul Edwards
  2 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-11-09 23:10 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Ulrich Weigand, gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-11-09 15:57                             ` Ian Lance Taylor
  2009-11-09 23:10                               ` Paul Edwards
@ 2009-11-10 14:58                               ` Paul Edwards
  2009-11-10 15:36                                 ` Ian Lance Taylor
  2009-11-10 15:51                               ` Paul Edwards
  2 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-11-10 14:58 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Ulrich Weigand, gcc

> 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 -0000      1.2
--- hwint.h     10 Nov 2009 13:38:16 -0000
***************
*** 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];



^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-11-10 14:58                               ` Paul Edwards
@ 2009-11-10 15:36                                 ` Ian Lance Taylor
  0 siblings, 0 replies; 162+ messages in thread
From: Ian Lance Taylor @ 2009-11-10 15:36 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ulrich Weigand, gcc

"Paul Edwards" <mutazilah@gmail.com> writes:

> Another "where" question.  The i370 port can't cope with 64-bit
> integers.

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

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
extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
#  endif
# endif
#endif


Ian

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-11-09 15:57                             ` Ian Lance Taylor
  2009-11-09 23:10                               ` Paul Edwards
  2009-11-10 14:58                               ` Paul Edwards
@ 2009-11-10 15:51                               ` Paul Edwards
  2009-11-10 15:56                                 ` Ian Lance Taylor
  2 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-11-10 15:51 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Ulrich Weigand, gcc

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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-11-10 15:51                               ` Paul Edwards
@ 2009-11-10 15:56                                 ` Ian Lance Taylor
  2009-12-02 22:03                                   ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ian Lance Taylor @ 2009-11-10 15:56 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ulrich Weigand, gcc

"Paul Edwards" <mutazilah@gmail.com> writes:

> and c-parse.c:

That file no longer exists so I don't know how to interpret this.


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


> So would defining a new option be a reasonable solution for any
> target that wants to limit code generation for whatever reason?

No.

Ian

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-10-19 17:37                                                           ` Ulrich Weigand
  2009-10-20 14:18                                                             ` Paul Edwards
@ 2009-11-12 14:03                                                             ` Paul Edwards
  2009-11-12 20:06                                                               ` Ralf Wildenhues
  2009-11-13 12:08                                                               ` Ulrich Weigand
  1 sibling, 2 replies; 162+ messages in thread
From: Paul Edwards @ 2009-11-12 14:03 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Ian Lance Taylor, gcc

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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-12 14:03                                                             ` Paul Edwards
@ 2009-11-12 20:06                                                               ` Ralf Wildenhues
  2009-11-12 20:56                                                                 ` Paul Edwards
  2009-11-13 11:43                                                                 ` Paul Edwards
  2009-11-13 12:08                                                               ` Ulrich Weigand
  1 sibling, 2 replies; 162+ messages in thread
From: Ralf Wildenhues @ 2009-11-12 20:06 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ulrich Weigand, Ian Lance Taylor, gcc

Hello Paul,

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

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.

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.

Thanks,
Ralf

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-12 20:06                                                               ` Ralf Wildenhues
@ 2009-11-12 20:56                                                                 ` Paul Edwards
  2009-11-13 11:43                                                                 ` Paul Edwards
  1 sibling, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-11-12 20:56 UTC (permalink / raw)
  To: Ralf Wildenhues; +Cc: Ulrich Weigand, Ian Lance Taylor, gcc

> * 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 <stdarg.h>
  #include <stdio.h>
+ #if !defined(__MVS__)
  #include <sys/types.h>
  #include <sys/stat.h>
+ #endif

  cat >>conftest.$ac_ext <<_ACEOF
  /* end confdefs.h.  */
  #include "confdefs.h"
+ #if !defined(__MVS__)
  #include <sys/types.h>
+ #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 <sys/types.h>
  #include <sys/param.h>
+ #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 <sys/resource.h>
  #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 <sys/resource.h>
  #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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-12 20:06                                                               ` Ralf Wildenhues
  2009-11-12 20:56                                                                 ` Paul Edwards
@ 2009-11-13 11:43                                                                 ` Paul Edwards
  2009-11-13 12:01                                                                   ` Ulrich Weigand
  2009-11-22  0:46                                                                   ` i370 port - constructing compile script Paolo Bonzini
  1 sibling, 2 replies; 162+ messages in thread
From: Paul Edwards @ 2009-11-13 11:43 UTC (permalink / raw)
  To: Ralf Wildenhues; +Cc: Ulrich Weigand, Ian Lance Taylor, gcc

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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-13 11:43                                                                 ` Paul Edwards
@ 2009-11-13 12:01                                                                   ` Ulrich Weigand
  2009-11-13 12:18                                                                     ` Paul Edwards
  2009-11-22  0:46                                                                   ` i370 port - constructing compile script Paolo Bonzini
  1 sibling, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-11-13 12:01 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ralf Wildenhues, Ian Lance Taylor, gcc

Paul Edwards wrote:

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

This is apparently a bug in the 3.4 version of sched-ebb.c.  This
whole file should be in a #ifdef INSN_SCHEDULING, just like the
other sched-*.c files.  This is fixed in current GCC.

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

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

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-12 14:03                                                             ` Paul Edwards
  2009-11-12 20:06                                                               ` Ralf Wildenhues
@ 2009-11-13 12:08                                                               ` Ulrich Weigand
  1 sibling, 0 replies; 162+ messages in thread
From: Ulrich Weigand @ 2009-11-13 12:08 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ian Lance Taylor, gcc

Paul Edwards:

> 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?

Well, it's sort of the whole point of libiberty to provide
functions that are not available on certain hosts, so that
the rest of GCC can be simplified by assuming they're always
there.  So in principle I guess this should be fine.

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

Note that with current GCC versions, all these flag global
variables are defined by C source code that is automatically
generated from various option parameter files.  This should
make it simpler to change this e.g. to use a struct instead
of many global variables ...

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-13 12:01                                                                   ` Ulrich Weigand
@ 2009-11-13 12:18                                                                     ` Paul Edwards
  2009-11-13 12:57                                                                       ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-11-13 12:18 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Ralf Wildenhues, Ian Lance Taylor, gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-13 12:18                                                                     ` Paul Edwards
@ 2009-11-13 12:57                                                                       ` Ulrich Weigand
  2009-11-14  8:52                                                                         ` Paul Edwards
  2009-11-15 14:22                                                                         ` i370 port - finally building Paul Edwards
  0 siblings, 2 replies; 162+ messages in thread
From: Ulrich Weigand @ 2009-11-13 12:57 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ralf Wildenhues, Ian Lance Taylor, gcc

Paul Edwards wrote:

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

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.

This gets set during the macro call
  AC_REPLACE_FUNCS($funcs)
in configure.ac, which gets replaced by the following code
in configure (GCC 3.4):

for ac_func in $funcs
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
[...]
if test `eval echo '${'$as_ac_var'}'` = yes; then
  cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF

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

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

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

Ah, OK.

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-13 12:57                                                                       ` Ulrich Weigand
@ 2009-11-14  8:52                                                                         ` Paul Edwards
  2009-11-14 10:49                                                                           ` Ralf Wildenhues
  2009-11-15 14:22                                                                         ` i370 port - finally building Paul Edwards
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-11-14  8:52 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Ralf Wildenhues, Ian Lance Taylor, gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-14  8:52                                                                         ` Paul Edwards
@ 2009-11-14 10:49                                                                           ` Ralf Wildenhues
  2009-11-14 11:28                                                                             ` Paul Edwards
  2009-11-18 10:51                                                                             ` Paul Edwards
  0 siblings, 2 replies; 162+ messages in thread
From: Ralf Wildenhues @ 2009-11-14 10:49 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ulrich Weigand, Ian Lance Taylor, gcc

* Paul Edwards wrote on Sat, Nov 14, 2009 at 09:51:39AM CET:
> >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.

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

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

Yes.  The macro that does this is libiberty_AC_FUNC_STRNCMP in
libiberty/aclocal.m4.  In a cross-compile situation, the macro assumes
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
  ../gcc/configure ...

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

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

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

Thanks,
Ralf

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-14 10:49                                                                           ` Ralf Wildenhues
@ 2009-11-14 11:28                                                                             ` Paul Edwards
  2009-11-22  0:51                                                                               ` Paolo Bonzini
  2009-11-18 10:51                                                                             ` Paul Edwards
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-11-14 11:28 UTC (permalink / raw)
  To: Ralf Wildenhues; +Cc: Ulrich Weigand, Ian Lance Taylor, gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - finally building
  2009-11-13 12:57                                                                       ` Ulrich Weigand
  2009-11-14  8:52                                                                         ` Paul Edwards
@ 2009-11-15 14:22                                                                         ` Paul Edwards
  1 sibling, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-11-15 14:22 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Ralf Wildenhues, Ian Lance Taylor, gcc

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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-14 10:49                                                                           ` Ralf Wildenhues
  2009-11-14 11:28                                                                             ` Paul Edwards
@ 2009-11-18 10:51                                                                             ` Paul Edwards
  2009-11-19 14:27                                                                               ` Ulrich Weigand
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-11-18 10:51 UTC (permalink / raw)
  To: Ralf Wildenhues; +Cc: Ulrich Weigand, Ian Lance Taylor, gcc

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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-18 10:51                                                                             ` Paul Edwards
@ 2009-11-19 14:27                                                                               ` Ulrich Weigand
  2009-11-21 13:40                                                                                 ` Paul Edwards
  2009-11-23 10:33                                                                                 ` i370 port - 3.4.6 to 4.4 upgrade attempt Paul Edwards
  0 siblings, 2 replies; 162+ messages in thread
From: Ulrich Weigand @ 2009-11-19 14:27 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ralf Wildenhues, Ian Lance Taylor, gcc

Paul Edwards wrote:

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

> 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?

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

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

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-19 14:27                                                                               ` Ulrich Weigand
@ 2009-11-21 13:40                                                                                 ` Paul Edwards
  2009-11-23 10:33                                                                                 ` i370 port - 3.4.6 to 4.4 upgrade attempt Paul Edwards
  1 sibling, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-11-21 13:40 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Ralf Wildenhues, Ian Lance Taylor, gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-13 11:43                                                                 ` Paul Edwards
  2009-11-13 12:01                                                                   ` Ulrich Weigand
@ 2009-11-22  0:46                                                                   ` Paolo Bonzini
  1 sibling, 0 replies; 162+ messages in thread
From: Paolo Bonzini @ 2009-11-22  0:46 UTC (permalink / raw)
  To: gcc

On 11/13/2009 12:43 PM, Paul Edwards wrote:
> 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.

regex.c is forked from anything else, so I don't think a patch changing 
PREFIX to FUNC_PREFIX will have any objection.

Paolo

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - constructing compile script
  2009-11-14 11:28                                                                             ` Paul Edwards
@ 2009-11-22  0:51                                                                               ` Paolo Bonzini
  0 siblings, 0 replies; 162+ messages in thread
From: Paolo Bonzini @ 2009-11-22  0:51 UTC (permalink / raw)
  To: gcc

On 11/14/2009 12:27 PM, Paul Edwards wrote:
>
> 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.

-Wimplicit -Werror?

Paolo

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - 3.4.6 to 4.4 upgrade attempt
  2009-11-19 14:27                                                                               ` Ulrich Weigand
  2009-11-21 13:40                                                                                 ` Paul Edwards
@ 2009-11-23 10:33                                                                                 ` Paul Edwards
  2009-11-23 10:43                                                                                   ` Andreas Schwab
                                                                                                     ` (2 more replies)
  1 sibling, 3 replies; 162+ messages in thread
From: Paul Edwards @ 2009-11-23 10:33 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Ralf Wildenhues, Ian Lance Taylor, gcc

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");

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

  /* #pragma checkout (mode) -
***************
*** 105,115 ****
     anyone clarify?  */

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

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

--- 108,118 ----
     anyone clarify?  */

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

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

***************
*** 120,127 ****
      BAD ("missing ')' for '#pragma checkout' - ignored");

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

  /* #pragma nomargins
--- 123,130 ----
      BAD ("missing ')' for '#pragma checkout' - ignored");

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

  /* #pragma nomargins
***************
*** 129,136 ****
     We just ignore. */

  void
! i370_pr_skipit (pfile)
!      cpp_reader *pfile ATTRIBUTE_UNUSED;
  {
  }

--- 132,138 ----
     We just ignore. */

  void
! i370_pr_skipit (cpp_reader *pfile ATTRIBUTE_UNUSED)
  {
  }

Index: gcc4/gcc/config/i370/i370.c
diff -c gcc4/gcc/config/i370/i370.c:1.5 gcc4/gcc/config/i370/i370.c:1.6
*** gcc4/gcc/config/i370/i370.c:1.5 Mon Nov 23 22:17:43 2009
--- gcc4/gcc/config/i370/i370.c Mon Nov 23 22:46:22 2009
***************
*** 1,3 ****
--- 1,4 ----
+ /* +++ references to cfun framesize are bogus */
  /* Subroutines for insn-output.c for System/370.
     Copyright (C) 1989, 1993, 1995, 1997, 1998, 1999, 2000, 2002
     Free Software Foundation, Inc.
***************
*** 274,281 ****

    /* We're 370 floating point, not IEEE floating point.  */
    memset (real_format_for_mode, 0, sizeof real_format_for_mode);
!   REAL_MODE_FORMAT (SFmode) = &i370_single_format;
!   REAL_MODE_FORMAT (DFmode) = &i370_double_format;
  }

  static int statfunc = 0;
--- 275,285 ----

    /* We're 370 floating point, not IEEE floating point.  */
    memset (real_format_for_mode, 0, sizeof real_format_for_mode);
!   /*REAL_MODE_FORMAT (SFmode) = &i370_single_format;
!   REAL_MODE_FORMAT (DFmode) = &i370_double_format;*/
!   /* +++ this is wrong */
!   REAL_MODE_FORMAT (SFmode) = &ibm_extended_format;
!   REAL_MODE_FORMAT (DFmode) = &ibm_extended_format;
  }

  static int statfunc = 0;
***************
*** 588,600 ****
                rtx note;
                for (note = REG_NOTES (insn); note;  note = XEXP(note,1))
                  {
                     if (REG_LABEL == REG_NOTE_KIND(note))
                       {
                          rtx label = XEXP (note,0);
                          if (!label || CODE_LABEL != GET_CODE (label)) 
abort ();

                          I370_RECORD_LABEL_REF(label,here);
!                      }
                  }
             }
         }
--- 592,606 ----
                rtx note;
                for (note = REG_NOTES (insn); note;  note = XEXP(note,1))
                  {
+                    /* +++ what is reg_label? */
+                    /*
                     if (REG_LABEL == REG_NOTE_KIND(note))
                       {
                          rtx label = XEXP (note,0);
                          if (!label || CODE_LABEL != GET_CODE (label)) 
abort ();

                          I370_RECORD_LABEL_REF(label,here);
!                      } */
                  }
             }
         }
***************
*** 1048,1059 ****
    ap = (alias_node_t *) xmalloc (sizeof (alias_node_t));
    if (strlen (realname) > MAX_LONG_LABEL_SIZE)
      {
!       warning ("real name is too long - alias ignored");
        return;
      }
    if (strlen (aliasname) > MAX_MVS_LABEL_SIZE)
      {
!       warning ("alias name is too long - alias ignored");
        return;
      }

--- 1054,1065 ----
    ap = (alias_node_t *) xmalloc (sizeof (alias_node_t));
    if (strlen (realname) > MAX_LONG_LABEL_SIZE)
      {
!       warning (0, "real name is too long - alias ignored");
        return;
      }
    if (strlen (aliasname) > MAX_MVS_LABEL_SIZE)
      {
!       warning (0, "alias name is too long - alias ignored");
        return;
      }

***************
*** 1568,1574 ****
    fprintf (f, "* Function %.*s prologue: stack = %ld, args = %d\n",
             nlen, mvs_function_name,
      l,
!     current_function_outgoing_args_size);
  #endif

    if (mvs_first_entry)
--- 1574,1580 ----
    fprintf (f, "* Function %.*s prologue: stack = %ld, args = %d\n",
             nlen, mvs_function_name,
      l,
!     0 /*cfun->machine->frame_size*/);
  #endif

    if (mvs_first_entry)
***************
*** 1594,1607 ****
    fprintf (f, "\tPDPPRLG CINDEX=%d,FRAME=%d,BASER=%d,ENTRY=%s\n",
  #endif
      mvs_page_num,
!     STACK_FRAME_BASE + l + current_function_outgoing_args_size,
      BASE_REGISTER,
      mvs_need_entry ? "YES" : "NO");
    fprintf (f, "\tB\tFEN%d\n", mvs_page_num);
  #ifdef TARGET_DIGNUS
    fprintf (f, "@FRAMESIZE_%d DC F'%d'\n",
      mvs_page_num,
!     STACK_FRAME_BASE + l + current_function_outgoing_args_size);
  #endif
  #ifdef TARGET_PDPMAC
    fprintf (f, "\tLTORG\n");
--- 1600,1613 ----
    fprintf (f, "\tPDPPRLG CINDEX=%d,FRAME=%d,BASER=%d,ENTRY=%s\n",
  #endif
      mvs_page_num,
!     STACK_FRAME_BASE + l + 0 /*cfun->machine->frame_size*/,
      BASE_REGISTER,
      mvs_need_entry ? "YES" : "NO");
    fprintf (f, "\tB\tFEN%d\n", mvs_page_num);
  #ifdef TARGET_DIGNUS
    fprintf (f, "@FRAMESIZE_%d DC F'%d'\n",
      mvs_page_num,
!     STACK_FRAME_BASE + l + cfun->machine->frame_size);
  #endif
  #ifdef TARGET_PDPMAC
    fprintf (f, "\tLTORG\n");
***************
*** 1615,1621 ****
  #ifdef TARGET_LE
    assemble_name (f, mvs_function_name);
    fprintf (f, "\tEDCPRLG USRDSAL=%d,BASEREG=%d\n",
!     STACK_FRAME_BASE + l + current_function_outgoing_args_size,
      BASE_REGISTER);
  #endif

--- 1621,1627 ----
  #ifdef TARGET_LE
    assemble_name (f, mvs_function_name);
    fprintf (f, "\tEDCPRLG USRDSAL=%d,BASEREG=%d\n",
!     STACK_FRAME_BASE + l + cfun->machine->frame_size,
      BASE_REGISTER);
  #endif

***************
*** 1644,1650 ****
    fprintf (f, "\tDS\tD\n");
    fprintf (f, "\tDS\tCL(" HOST_WIDE_INT_PRINT_DEC ")\n",
      STACK_POINTER_OFFSET + l
!     + current_function_outgoing_args_size);
    fprintf (f, "\tORG\tFDSE%03d\n", function_label_index);
    fprintf (f, "\tDS\tCL(120+8)\n");
    fprintf (f, "\tORG\n");
--- 1650,1656 ----
    fprintf (f, "\tDS\tD\n");
    fprintf (f, "\tDS\tCL(" HOST_WIDE_INT_PRINT_DEC ")\n",
      STACK_POINTER_OFFSET + l
!     + cfun->machine->frame_size);
    fprintf (f, "\tORG\tFDSE%03d\n", function_label_index);
    fprintf (f, "\tDS\tCL(120+8)\n");
    fprintf (f, "\tORG\n");
***************
*** 1868,1874 ****
    /* store stack size where we can get to it */
  #ifdef STACK_GROWS_DOWNWARDS
    stackframe_size =
!      STACK_POINTER_OFFSET + current_function_outgoing_args_size + 
frame_size;
  #else /* STACK_GROWS_DOWNWARDS */
    stackframe_size =
       STACK_POINTER_OFFSET + current_function_args_size + frame_size;
--- 1874,1880 ----
    /* store stack size where we can get to it */
  #ifdef STACK_GROWS_DOWNWARDS
    stackframe_size =
!      STACK_POINTER_OFFSET + cfun->machine->frame_size + frame_size;
  #else /* STACK_GROWS_DOWNWARDS */
    stackframe_size =
       STACK_POINTER_OFFSET + current_function_args_size + frame_size;
Index: gcc4/gcc/config/i370/i370.h
diff -c gcc4/gcc/config/i370/i370.h:1.6 gcc4/gcc/config/i370/i370.h:1.7
*** gcc4/gcc/config/i370/i370.h:1.6 Mon Nov 23 22:17:43 2009
--- gcc4/gcc/config/i370/i370.h Mon Nov 23 22:46:22 2009
***************
*** 88,93 ****
--- 88,95 ----

  #define TARGET_64BIT 0

+ #if 0
+ This unused (in mvspdp) stuff is now poisoned
  /* Macro to define tables used to set the flags.  This is a list in braces
     of pairs in braces, each pair being { "NAME", VALUE }
     where VALUE is the bits to set or minus the bits to clear.
***************
*** 99,104 ****
--- 101,107 ----
    { "pickax", 2, "Experimental i370 PIC"}, \
    { "no-pickax", -2, "Disable experimental i370 PIC"}, \
    { "", TARGET_DEFAULT, 0} }
+ #endif

  extern void i370_override_options (void);
  #define OVERRIDE_OPTIONS i370_override_options()
***************
*** 203,211 ****
--- 206,216 ----

  #define MAX_MVS_PAGE_LENGTH 4068

+ #if 0 /* +++ now poisoned */
  #define PREDICATE_CODES \
    {"r_or_s_operand", { REG, SUBREG, MEM }}, \
    {"s_operand", { MEM }},
+ #endif

  /* Conservative page size when considering literals and overhead. */

***************
*** 499,507 ****
     the R1 points at that mem location.
   */

! #ifdef TARGET_PDPMAC
  #define STRUCT_VALUE_REGNUM 0
! #else
  #define STRUCT_VALUE_REGNUM 1
  #endif

--- 504,514 ----
     the R1 points at that mem location.
   */

! #if 0 /*def TARGET_PDPMAC*/
! +++ this variable is now poisoned - check structs still get returned
! properly
  #define STRUCT_VALUE_REGNUM 0
! #elif 0 /*used to be else*/
  #define STRUCT_VALUE_REGNUM 1
  #endif

***************
*** 656,663 ****
     first local allocated.  Otherwise, it is the offset to the BEGINNING
     of the first local allocated.  */

! #define STARTING_FRAME_OFFSET        \
!      (STACK_POINTER_OFFSET + current_function_outgoing_args_size)

  #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = 
STARTING_FRAME_OFFSET

--- 663,670 ----
     first local allocated.  Otherwise, it is the offset to the BEGINNING
     of the first local allocated.  */

! /* +++ used to have a real value */
! #define STARTING_FRAME_OFFSET 0

  #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = 
STARTING_FRAME_OFFSET

***************
*** 807,814 ****
  /* For an arg passed partly in registers and partly in memory, this is the
     number of registers used.  For args passed entirely in registers or
     entirely in memory, zero.  */
!
  #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0

  /* Define if returning from a function call automatically pops the
     arguments described by the number-of-args field in the call.  */
--- 814,823 ----
  /* For an arg passed partly in registers and partly in memory, this is the
     number of registers used.  For args passed entirely in registers or
     entirely in memory, zero.  */
! /* +++ now poisoned */
! #if 0
  #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
+ #endif

  /* Define if returning from a function call automatically pops the
     arguments described by the number-of-args field in the call.  */
***************
*** 848,856 ****
  #define FUNCTION_VALUE_REGNO_P(N) ((N) == 15 || (N) == 16)

  /* This macro definition sets up a default value for `main' to return.  */
!
  #define DEFAULT_MAIN_RETURN  c_expand_return (integer_zero_node)
!

  /* Output assembler code for a block containing the constant parts of a
     trampoline, leaving space for the variable parts.
--- 857,866 ----
  #define FUNCTION_VALUE_REGNO_P(N) ((N) == 15 || (N) == 16)

  /* This macro definition sets up a default value for `main' to return.  */
! /* +++ now poisoned */
! #if 0
  #define DEFAULT_MAIN_RETURN  c_expand_return (integer_zero_node)
! #endif

  /* Output assembler code for a block containing the constant parts of a
     trampoline, leaving space for the variable parts.
***************
*** 1134,1141 ****
  /* ??? Investigate defining STORE_FLAG_VALUE to (-1).  */

  /* When a prototype says `char' or `short', really pass an `int'.  */
!
  #define PROMOTE_PROTOTYPES 1

  /* Don't perform CSE on function addresses.  */

--- 1144,1153 ----
  /* ??? Investigate defining STORE_FLAG_VALUE to (-1).  */

  /* When a prototype says `char' or `short', really pass an `int'.  */
! /* +++ now poisoned */
! #if 0
  #define PROMOTE_PROTOTYPES 1
+ #endif

  /* Don't perform CSE on function addresses.  */

***************
*** 1252,1268 ****
  /* Define standard character escape sequences for non-ASCII targets
     only.  */

- #ifdef TARGET_EBCDIC
- #define TARGET_ESC 39
- #define TARGET_BELL 47
- #define TARGET_BS 22
- #define TARGET_TAB 5
- #define TARGET_NEWLINE 21
- #define TARGET_VT 11
- #define TARGET_FF 12
- #define TARGET_CR 13
- #endif
-
  /* ======================================================== */

  #ifdef TARGET_HLASM
--- 1264,1269 ----
***************
*** 1270,1276 ****
--- 1271,1280 ----
  #define TEXT_SECTION_ASM_OP "* Program text area"
  #define DATA_SECTION_ASM_OP "* Program data area"
  #define INIT_SECTION_ASM_OP "* Program initialization area"
+ /* +++ now poisoned */
+ #if 0
  #define SHARED_SECTION_ASM_OP "* Program shared data"
+ #endif
  #define CTOR_LIST_BEGIN  /* NO OP */
  #define CTOR_LIST_END  /* NO OP */
  #define MAX_MVS_LABEL_SIZE 8

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - 3.4.6 to 4.4 upgrade attempt
  2009-11-23 10:33                                                                                 ` i370 port - 3.4.6 to 4.4 upgrade attempt Paul Edwards
@ 2009-11-23 10:43                                                                                   ` Andreas Schwab
  2009-11-23 15:43                                                                                   ` Paolo Bonzini
  2009-11-24 14:05                                                                                   ` Ulrich Weigand
  2 siblings, 0 replies; 162+ messages in thread
From: Andreas Schwab @ 2009-11-23 10:43 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ulrich Weigand, Ralf Wildenhues, Ian Lance Taylor, gcc

"Paul Edwards" <mutazilah@gmail.com> writes:

> 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

You should send patches for config.{guess,sub} to
<config-patches@gnu.org>.

Andreas.

-- 
Andreas Schwab, schwab@redhat.com
GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84  5EC7 45C6 250E 6F00 984E
"And now for something completely different."

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - 3.4.6 to 4.4 upgrade attempt
  2009-11-23 10:33                                                                                 ` i370 port - 3.4.6 to 4.4 upgrade attempt Paul Edwards
  2009-11-23 10:43                                                                                   ` Andreas Schwab
@ 2009-11-23 15:43                                                                                   ` Paolo Bonzini
  2009-11-24 14:05                                                                                   ` Ulrich Weigand
  2 siblings, 0 replies; 162+ messages in thread
From: Paolo Bonzini @ 2009-11-23 15:43 UTC (permalink / raw)
  To: gcc

On 11/23/2009 11:32 AM, Paul Edwards wrote:
>
> So, given the scope below, can someone please explain what
> 4.4 changes are affecting me and what I need to do to overcome
> them?

I think your best bet is to grep the changelogs for what has changes, 
and see what was done for other ports.  Many target macros have become 
target hooks.  Or, PREDICATE_CODES for example will require you to 
rewrite the r_or_s_operand and s_operand as "define_predicate" RTL; grep 
the ChangeLog for predicates.md.  And so on.

Paolo

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - 3.4.6 to 4.4 upgrade attempt
  2009-11-23 10:33                                                                                 ` i370 port - 3.4.6 to 4.4 upgrade attempt Paul Edwards
  2009-11-23 10:43                                                                                   ` Andreas Schwab
  2009-11-23 15:43                                                                                   ` Paolo Bonzini
@ 2009-11-24 14:05                                                                                   ` Ulrich Weigand
  2009-11-24 14:36                                                                                     ` Paul Edwards
                                                                                                       ` (2 more replies)
  2 siblings, 3 replies; 162+ messages in thread
From: Ulrich Weigand @ 2009-11-24 14:05 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ralf Wildenhues, Ian Lance Taylor, gcc

Paul Edwards wrote:

> So, given the scope below, can someone please explain what
> 4.4 changes are affecting me and what I need to do to overcome
> them?  Note that I have never had to do the machine changes
> myself - in the past I simply waiting for Dave Pitts to do the
> upgrade to the new version, and then with a working 370 code
> generator I would make all the changes necessary for MVS.

Most of the things seem just minor changes, e.g. "warning" got
another argument, or target macros were replaced by targetm
callbacks.

I can see one significant change: the GCC middle-end now no
longer supports base-16 floating point at all.  The old i370
port was the only user of this feature, and some time after
the port was removed, the middle-end support was removed as
well in order to simplify floating-point handling code.

The s390 port uses IEEE float instead of hex float throughout,
so it is not affected by this change.

> + i370-*-mvspdp)
> +     xm_defines='POSIX'  # 'FATAL_EXIT_CODE=12'
> +     xm_file="i370/xm-mvs.h"
> +     tm_file="i370/mvspdp.h i370/i370.h"
> +     tmake_file="i370/t-mvs i370/t-i370"
> +     c_target_objs="i370-c.o"
> +     cxx_target_objs="i370-c.o"
> +     ;;
> + s390-*-linux*)
> +  tm_file="s390/s390.h dbxelf.h elfos.h svr4.h linux.h s390/linux.h"
> +  tmake_file="${tmake_file} t-dfprules s390/t-crtstuff s390/t-linux"
> +  ;;

The s390 lines should not be added here.

> ! /* +++ c_lex has gone. however, we don't use it for anything important 
> anyway */
> ! #define c_lex(a)

Pragma handlers are now apparently supposed to use "pragma_lex" instead,
which is declared in the c-pragma.h header.  See e.g. config/sol2-c.c
for examples of pragma handlers.

>     /* We're 370 floating point, not IEEE floating point.  */
>     memset (real_format_for_mode, 0, sizeof real_format_for_mode);
> !   REAL_MODE_FORMAT (SFmode) = &i370_single_format;
> !   REAL_MODE_FORMAT (DFmode) = &i370_double_format;

This is a problem, see above.

>     /* We're 370 floating point, not IEEE floating point.  */
>     memset (real_format_for_mode, 0, sizeof real_format_for_mode);
> !   /*REAL_MODE_FORMAT (SFmode) = &i370_single_format;
> !   REAL_MODE_FORMAT (DFmode) = &i370_double_format;*/
> !   /* +++ this is wrong */
> !   REAL_MODE_FORMAT (SFmode) = &ibm_extended_format;
> !   REAL_MODE_FORMAT (DFmode) = &ibm_extended_format;

ibm_extended_format is certainly wrong here; that's the
64 + 64 "long double" format used on PowerPC.

>                 for (note = REG_NOTES (insn); note;  note = XEXP(note,1))
>                   {
> +                    /* +++ what is reg_label? */
> +                    /*
>                      if (REG_LABEL == REG_NOTE_KIND(note))
>                        {

Instead of REG_LABEL notes, the middle-end now generates two different
kinds of notes, REG_LABEL_TARGET and REG_LABEL_OPERAND.

REG_LABEL_TARGET is used in JUMP_INSNs to refer to a potential target
of this jump.  REG_LABEL_OPERAND is used in other insns to denote labels
that are used otherwise, e.g. to load the address into a register.

In the context of this code in i370.c, it would appear you're concerned
about the second type of usage here.  This means the REG_LABEL should
probably simply be replaced by REG_LABEL_OPERAND.

> ***************
> *** 1568,1574 ****
>     fprintf (f, "* Function %.*s prologue: stack = %ld, args = %d\n",
>              nlen, mvs_function_name,
>       l,
> !     current_function_outgoing_args_size);
>   #endif

current_function_outgoing_args_size must be replaced by crtl->outgoing_args_size
throughout.  There was no change in semantics, just where the value is stored.

>     fprintf (f, "* Function %.*s prologue: stack = %ld, args = %d\n",
>              nlen, mvs_function_name,
>       l,
> !     0 /*cfun->machine->frame_size*/);
>   #endif

The cfun->machine->frame_size stuff does not seem correct here; use
crtl->outgoing_args_size.

> + #if 0
> + This unused (in mvspdp) stuff is now poisoned
>   /* Macro to define tables used to set the flags.  This is a list in braces
>      of pairs in braces, each pair being { "NAME", VALUE }
>      where VALUE is the bits to set or minus the bits to clear.
> ***************
> *** 99,104 ****
> --- 101,107 ----
>     { "pickax", 2, "Experimental i370 PIC"}, \
>     { "no-pickax", -2, "Disable experimental i370 PIC"}, \
>     { "", TARGET_DEFAULT, 0} }
> + #endif

Command line options are now defined in a .opt file.  If you want to
keep those extra options, you should provide a config/i370/i370.opt
file.  See any of the other targets for examples.

> + #if 0 /* +++ now poisoned */
>   #define PREDICATE_CODES \
>     {"r_or_s_operand", { REG, SUBREG, MEM }}, \
>     {"s_operand", { MEM }},
> + #endif

Predicates must now be defined in a predicates.md file.  Again, see
other targets for examples.

> ! #if 0 /*def TARGET_PDPMAC*/
> ! +++ this variable is now poisoned - check structs still get returned
> ! properly
>   #define STRUCT_VALUE_REGNUM 0
> ! #elif 0 /*used to be else*/
>   #define STRUCT_VALUE_REGNUM 1
>   #endif

If something except the default is needed here, you now have to use the
TARGET_STRUCT_VALUE_RTX targetm callback.

>   /* For an arg passed partly in registers and partly in memory, this is the
>      number of registers used.  For args passed entirely in registers or
>      entirely in memory, zero.  */
> ! /* +++ now poisoned */
> ! #if 0
>   #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
> + #endif

If something except the default is needed here, you now have to use the
TARGET_ARG_PARTIAL_BYTES targetm callback.

>   /* This macro definition sets up a default value for `main' to return.  */
> ! /* +++ now poisoned */
> ! #if 0
>   #define DEFAULT_MAIN_RETURN  c_expand_return (integer_zero_node)
> ! #endif

This is no longer supported.  C99 allows omitting the main return value
by default; in C89 this is not possible any longer.

>   /* When a prototype says `char' or `short', really pass an `int'.  */
> ! /* +++ now poisoned */
> ! #if 0
>   #define PROMOTE_PROTOTYPES 1
> + #endif

If something except the default is needed here, you now have to use the
TARGET_PROMOTE_PROTOTYPES targetm callback.

> - #ifdef TARGET_EBCDIC
> - #define TARGET_ESC 39
> - #define TARGET_BELL 47
> - #define TARGET_BS 22
> - #define TARGET_TAB 5
> - #define TARGET_NEWLINE 21
> - #define TARGET_VT 11
> - #define TARGET_FF 12
> - #define TARGET_CR 13
> - #endif

These are no longer needed now that the parser is charset-aware.

>   #define TEXT_SECTION_ASM_OP "* Program text area"
>   #define DATA_SECTION_ASM_OP "* Program data area"
>   #define INIT_SECTION_ASM_OP "* Program initialization area"
> + /* +++ now poisoned */
> + #if 0
>   #define SHARED_SECTION_ASM_OP "* Program shared data"
> + #endif

This is no longer needed; it was used to support -fshared-data
which is no longer present.


Note that I'd expect that with the above obvious issues fixed,
you may well run into additional problems in moving the port
forward ...  At some point, it will be necessary to be able
to debug the back-end and resolve problems.

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

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - 3.4.6 to 4.4 upgrade attempt
  2009-11-24 14:05                                                                                   ` Ulrich Weigand
@ 2009-11-24 14:36                                                                                     ` Paul Edwards
  2009-11-28 15:14                                                                                     ` i370 port - music/sp - possible generic gcc problem Paul Edwards
  2009-12-07 12:05                                                                                     ` i370 port - 3.4.6 to 4.4 upgrade attempt Paul Edwards
  2 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-11-24 14:36 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Ralf Wildenhues, Ian Lance Taylor, gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* i370 port - music/sp - possible generic gcc problem
  2009-11-24 14:05                                                                                   ` Ulrich Weigand
  2009-11-24 14:36                                                                                     ` Paul Edwards
@ 2009-11-28 15:14                                                                                     ` Paul Edwards
  2009-11-28 16:03                                                                                       ` Richard Guenther
  2009-12-07 12:05                                                                                     ` i370 port - 3.4.6 to 4.4 upgrade attempt Paul Edwards
  2 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-11-28 15:14 UTC (permalink / raw)
  To: gcc

I think I have found a bug in gcc, that still exists in gcc 4.4

I found the problem on 3.2.3 though.

While MVS and VM have basically been working fine, when I did
the port to MUSIC/SP I started getting strange compilation failures.

Initializing the stack to NULs made the problem go away, but I
persisted, and instead initialized the stack to x'01' to try to get
consistent failures.

Even with that, and the malloced memory initialized to consistent
garbage, I still didn't get the desired consistency in failures.
But it was consistent enough that I could just run it 6 times and
see if there were any failures.


Anyway, I tracked down the particular malloc() which gave changed
behaviour depending on whether the malloc() did a memory initialization
to NULs or not.

It's this one (showing 3.2.3):

C:\devel\gcc\gcc>cvs diff -l -c15
cvs diff: Diffing .
Index: ggc-page.c
===================================================================
RCS file: c:\cvsroot/gcc/gcc/ggc-page.c,v
retrieving revision 1.1.1.1
diff -c -1 -5 -r1.1.1.1 ggc-page.c
*** ggc-page.c  15 Feb 2006 10:22:25 -0000      1.1.1.1
--- ggc-page.c  28 Nov 2009 14:13:41 -0000
***************
*** 640,670 ****
  #ifdef USING_MALLOC_PAGE_GROUPS
    else
      {
        /* Allocate a large block of memory and serve out the aligned
         pages therein.  This results in much less memory wastage
         than the traditional implementation of valloc.  */

        char *allocation, *a, *enda;
        size_t alloc_size, head_slop, tail_slop;
        int multiple_pages = (entry_size == G.pagesize);

        if (multiple_pages)
        alloc_size = GGC_QUIRE_SIZE * G.pagesize;
        else
        alloc_size = entry_size + G.pagesize - 1;
!       allocation = xmalloc (alloc_size);

        page = (char *) (((size_t) allocation + G.pagesize - 1) 
& -G.pagesize);
        head_slop = page - allocation;
        if (multiple_pages)
        tail_slop = ((size_t) allocation + alloc_size) & (G.pagesize - 1);
        else
        tail_slop = alloc_size - entry_size - head_slop;
        enda = allocation + alloc_size - tail_slop;

        /* We allocated N pages, which are likely not aligned, leaving
         us with N-1 usable pages.  We plan to place the page_group
         structure somewhere in the slop.  */
        if (head_slop >= sizeof (page_group))
        group = (page_group *)page - 1;
        else
--- 640,670 ----
  #ifdef USING_MALLOC_PAGE_GROUPS
    else
      {
        /* Allocate a large block of memory and serve out the aligned
         pages therein.  This results in much less memory wastage
         than the traditional implementation of valloc.  */

        char *allocation, *a, *enda;
        size_t alloc_size, head_slop, tail_slop;
        int multiple_pages = (entry_size == G.pagesize);

        if (multiple_pages)
        alloc_size = GGC_QUIRE_SIZE * G.pagesize;
        else
        alloc_size = entry_size + G.pagesize - 1;
!       allocation = xcalloc (1, alloc_size);

        page = (char *) (((size_t) allocation + G.pagesize - 1) 
& -G.pagesize);
        head_slop = page - allocation;
        if (multiple_pages)
        tail_slop = ((size_t) allocation + alloc_size) & (G.pagesize - 1);
        else
        tail_slop = alloc_size - entry_size - head_slop;
        enda = allocation + alloc_size - tail_slop;

        /* We allocated N pages, which are likely not aligned, leaving
         us with N-1 usable pages.  We plan to place the page_group
         structure somewhere in the slop.  */
        if (head_slop >= sizeof (page_group))
        group = (page_group *)page - 1;
        else


I suspect that it has stayed hidden for so long because most people
probably have this mmap_anon:

/* Define if mmap can get us zeroed pages using MAP_ANON(YMOUS). */
#undef HAVE_MMAP_ANON


#ifdef HAVE_MMAP_ANON
# undef HAVE_MMAP_DEV_ZERO

# include <sys/mman.h>
# ifndef MAP_FAILED
#  define MAP_FAILED -1
# endif
# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
#  define MAP_ANONYMOUS MAP_ANON
# endif
# define USING_MMAP

#endif

#ifndef USING_MMAP
#define USING_MALLOC_PAGE_GROUPS
#endif


Seems pretty clear that zeroed pages are required.

Looking at the code above and below this block, it uses xcalloc
instead.

It will take a couple of days to confirm that this is the last
presumed bug affecting the MUSIC/SP port.

In the meantime, can someone confirm that this code is wrong,
and that xcalloc is definitely required?

I had a look at the gcc4 code, and it is calling XNEWVEC which
is also using xmalloc instead of xcalloc, so I presume it is still
a problem today, under the right circumstances.

It took about a week to track this one down.  :-)

One problem I have had for years, even on the MVS port, is that
I need to use -Os to get the exact same register selection on the
PC as the mainframe.  -O0 and -O2 get slightly different register
allocations, although all versions of the code are correct.  If I'm
lucky, this fix may make that problem go away, but as I said,
it'll take a couple of days before the results are in, as each build
takes about 2 hours (partly because i need to use -Os for
consistency).

Thanks.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - music/sp - possible generic gcc problem
  2009-11-28 15:14                                                                                     ` i370 port - music/sp - possible generic gcc problem Paul Edwards
@ 2009-11-28 16:03                                                                                       ` Richard Guenther
  2009-11-28 16:35                                                                                         ` Paul Edwards
                                                                                                           ` (2 more replies)
  0 siblings, 3 replies; 162+ messages in thread
From: Richard Guenther @ 2009-11-28 16:03 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

On Sat, Nov 28, 2009 at 4:13 PM, Paul Edwards <mutazilah@gmail.com> wrote:
> I think I have found a bug in gcc, that still exists in gcc 4.4
>
> I found the problem on 3.2.3 though.
>
> While MVS and VM have basically been working fine, when I did
> the port to MUSIC/SP I started getting strange compilation failures.
>
> Initializing the stack to NULs made the problem go away, but I
> persisted, and instead initialized the stack to x'01' to try to get
> consistent failures.
>
> Even with that, and the malloced memory initialized to consistent
> garbage, I still didn't get the desired consistency in failures.
> But it was consistent enough that I could just run it 6 times and
> see if there were any failures.
>
>
> Anyway, I tracked down the particular malloc() which gave changed
> behaviour depending on whether the malloc() did a memory initialization
> to NULs or not.

Well, GC hands out non-zeroed memory - the callers are responsible
for initializing it.  So the fix below is not a fix but papering over an
issue elswhere.

Richard.

> It's this one (showing 3.2.3):
>
> C:\devel\gcc\gcc>cvs diff -l -c15
> cvs diff: Diffing .
> Index: ggc-page.c
> ===================================================================
> RCS file: c:\cvsroot/gcc/gcc/ggc-page.c,v
> retrieving revision 1.1.1.1
> diff -c -1 -5 -r1.1.1.1 ggc-page.c
> *** ggc-page.c  15 Feb 2006 10:22:25 -0000      1.1.1.1
> --- ggc-page.c  28 Nov 2009 14:13:41 -0000
> ***************
> *** 640,670 ****
>  #ifdef USING_MALLOC_PAGE_GROUPS
>   else
>     {
>       /* Allocate a large block of memory and serve out the aligned
>        pages therein.  This results in much less memory wastage
>        than the traditional implementation of valloc.  */
>
>       char *allocation, *a, *enda;
>       size_t alloc_size, head_slop, tail_slop;
>       int multiple_pages = (entry_size == G.pagesize);
>
>       if (multiple_pages)
>       alloc_size = GGC_QUIRE_SIZE * G.pagesize;
>       else
>       alloc_size = entry_size + G.pagesize - 1;
> !       allocation = xmalloc (alloc_size);
>
>       page = (char *) (((size_t) allocation + G.pagesize - 1) &
> -G.pagesize);
>       head_slop = page - allocation;
>       if (multiple_pages)
>       tail_slop = ((size_t) allocation + alloc_size) & (G.pagesize - 1);
>       else
>       tail_slop = alloc_size - entry_size - head_slop;
>       enda = allocation + alloc_size - tail_slop;
>
>       /* We allocated N pages, which are likely not aligned, leaving
>        us with N-1 usable pages.  We plan to place the page_group
>        structure somewhere in the slop.  */
>       if (head_slop >= sizeof (page_group))
>       group = (page_group *)page - 1;
>       else
> --- 640,670 ----
>  #ifdef USING_MALLOC_PAGE_GROUPS
>   else
>     {
>       /* Allocate a large block of memory and serve out the aligned
>        pages therein.  This results in much less memory wastage
>        than the traditional implementation of valloc.  */
>
>       char *allocation, *a, *enda;
>       size_t alloc_size, head_slop, tail_slop;
>       int multiple_pages = (entry_size == G.pagesize);
>
>       if (multiple_pages)
>       alloc_size = GGC_QUIRE_SIZE * G.pagesize;
>       else
>       alloc_size = entry_size + G.pagesize - 1;
> !       allocation = xcalloc (1, alloc_size);
>
>       page = (char *) (((size_t) allocation + G.pagesize - 1) &
> -G.pagesize);
>       head_slop = page - allocation;
>       if (multiple_pages)
>       tail_slop = ((size_t) allocation + alloc_size) & (G.pagesize - 1);
>       else
>       tail_slop = alloc_size - entry_size - head_slop;
>       enda = allocation + alloc_size - tail_slop;
>
>       /* We allocated N pages, which are likely not aligned, leaving
>        us with N-1 usable pages.  We plan to place the page_group
>        structure somewhere in the slop.  */
>       if (head_slop >= sizeof (page_group))
>       group = (page_group *)page - 1;
>       else
>
>
> I suspect that it has stayed hidden for so long because most people
> probably have this mmap_anon:
>
> /* Define if mmap can get us zeroed pages using MAP_ANON(YMOUS). */
> #undef HAVE_MMAP_ANON
>
>
> #ifdef HAVE_MMAP_ANON
> # undef HAVE_MMAP_DEV_ZERO
>
> # include <sys/mman.h>
> # ifndef MAP_FAILED
> #  define MAP_FAILED -1
> # endif
> # if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
> #  define MAP_ANONYMOUS MAP_ANON
> # endif
> # define USING_MMAP
>
> #endif
>
> #ifndef USING_MMAP
> #define USING_MALLOC_PAGE_GROUPS
> #endif
>
>
> Seems pretty clear that zeroed pages are required.
>
> Looking at the code above and below this block, it uses xcalloc
> instead.
>
> It will take a couple of days to confirm that this is the last
> presumed bug affecting the MUSIC/SP port.
>
> In the meantime, can someone confirm that this code is wrong,
> and that xcalloc is definitely required?
>
> I had a look at the gcc4 code, and it is calling XNEWVEC which
> is also using xmalloc instead of xcalloc, so I presume it is still
> a problem today, under the right circumstances.
>
> It took about a week to track this one down.  :-)
>
> One problem I have had for years, even on the MVS port, is that
> I need to use -Os to get the exact same register selection on the
> PC as the mainframe.  -O0 and -O2 get slightly different register
> allocations, although all versions of the code are correct.  If I'm
> lucky, this fix may make that problem go away, but as I said,
> it'll take a couple of days before the results are in, as each build
> takes about 2 hours (partly because i need to use -Os for
> consistency).
>
> Thanks.  Paul.
>
>

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - music/sp - possible generic gcc problem
  2009-11-28 16:03                                                                                       ` Richard Guenther
@ 2009-11-28 16:35                                                                                         ` Paul Edwards
  2009-11-28 17:03                                                                                           ` Richard Guenther
  2010-05-26 14:40                                                                                         ` i370 port - status Paul Edwards
  2021-03-14  5:55                                                                                         ` negative indexes Paul Edwards
  2 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-11-28 16:35 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - music/sp - possible generic gcc problem
  2009-11-28 16:35                                                                                         ` Paul Edwards
@ 2009-11-28 17:03                                                                                           ` Richard Guenther
  2009-11-28 23:44                                                                                             ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Richard Guenther @ 2009-11-28 17:03 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

On Sat, Nov 28, 2009 at 5:35 PM, Paul Edwards <mutazilah@gmail.com> wrote:
>>> 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

I can't see what you are refering to.

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

Richard.

> Thanks.  Paul.
>
>

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - music/sp - possible generic gcc problem
  2009-11-28 17:03                                                                                           ` Richard Guenther
@ 2009-11-28 23:44                                                                                             ` Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-11-28 23:44 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc

>> 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 9999 9999 9999 9999
/SYS REGION=9999,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
<stdin>: In function `acos':
<stdin>:137: Internal compiler error in ?, at <stdin>:724
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL: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 <stdin> converted into a
PC filename first.

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-11-10 15:56                                 ` Ian Lance Taylor
@ 2009-12-02 22:03                                   ` Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-12-02 22:03 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Ulrich Weigand, gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - 3.4.6 to 4.4 upgrade attempt
  2009-11-24 14:05                                                                                   ` Ulrich Weigand
  2009-11-24 14:36                                                                                     ` Paul Edwards
  2009-11-28 15:14                                                                                     ` i370 port - music/sp - possible generic gcc problem Paul Edwards
@ 2009-12-07 12:05                                                                                     ` Paul Edwards
  2009-12-08 13:55                                                                                       ` Ulrich Weigand
  2 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-12-07 12:05 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Ralf Wildenhues, Ian Lance Taylor, gcc

Well I have good news to report.

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

<built-in>: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.5999999...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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - 3.4.6 to 4.4 upgrade attempt
  2009-12-07 12:05                                                                                     ` i370 port - 3.4.6 to 4.4 upgrade attempt Paul Edwards
@ 2009-12-08 13:55                                                                                       ` Ulrich Weigand
  0 siblings, 0 replies; 162+ messages in thread
From: Ulrich Weigand @ 2009-12-08 13:55 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ralf Wildenhues, Ian Lance Taylor, gcc

Paul Edwards wrote:

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

Well, there's two main points where lack of hex float support
in the compiler may cause problems.  The one is if you were
to rely on the compiler to convert float constants into the
binary representation.  But from your sample above it seems
that you're instead asking the assembler to do this, so it
should not be an issue.

The second problem is that whenever the compiler performs
compile-time computations of floating point values, it will
use the IEEE semantics, which means it might arrive at 
different results than what target code running on the
mainframe would.  This can manifest in the same source code
leading to different results when compiled with optimizations
as compared to without optimizations, for example.

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port - status
  2009-11-28 16:03                                                                                       ` Richard Guenther
  2009-11-28 16:35                                                                                         ` Paul Edwards
@ 2010-05-26 14:40                                                                                         ` Paul Edwards
  2021-03-14  5:55                                                                                         ` negative indexes Paul Edwards
  2 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2010-05-26 14:40 UTC (permalink / raw)
  To: gcc; +Cc: Richard Guenther

> 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" <richard.guenther@gmail.com>
To: "Paul Edwards" <mutazilah@gmail.com>
Cc: <gcc@gcc.gnu.org>
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 <mutazilah@gmail.com> wrote:
> I think I have found a bug in gcc, that still exists in gcc 4.4
>
> I found the problem on 3.2.3 though.
>
> While MVS and VM have basically been working fine, when I did
> the port to MUSIC/SP I started getting strange compilation failures.
>
> Initializing the stack to NULs made the problem go away, but I
> persisted, and instead initialized the stack to x'01' to try to get
> consistent failures.
>
> Even with that, and the malloced memory initialized to consistent
> garbage, I still didn't get the desired consistency in failures.
> But it was consistent enough that I could just run it 6 times and
> see if there were any failures.
>
>
> Anyway, I tracked down the particular malloc() which gave changed
> behaviour depending on whether the malloc() did a memory initialization
> to NULs or not.

Well, GC hands out non-zeroed memory - the callers are responsible
for initializing it.  So the fix below is not a fix but papering over an
issue elswhere.

Richard.

> It's this one (showing 3.2.3):
>
> C:\devel\gcc\gcc>cvs diff -l -c15
> cvs diff: Diffing .
> Index: ggc-page.c
> ===================================================================
> RCS file: c:\cvsroot/gcc/gcc/ggc-page.c,v
> retrieving revision 1.1.1.1
> diff -c -1 -5 -r1.1.1.1 ggc-page.c
> *** ggc-page.c 15 Feb 2006 10:22:25 -0000 1.1.1.1
> --- ggc-page.c 28 Nov 2009 14:13:41 -0000
> ***************
> *** 640,670 ****
> #ifdef USING_MALLOC_PAGE_GROUPS
> else
> {
> /* Allocate a large block of memory and serve out the aligned
> pages therein. This results in much less memory wastage
> than the traditional implementation of valloc. */
>
> char *allocation, *a, *enda;
> size_t alloc_size, head_slop, tail_slop;
> int multiple_pages = (entry_size == G.pagesize);
>
> if (multiple_pages)
> alloc_size = GGC_QUIRE_SIZE * G.pagesize;
> else
> alloc_size = entry_size + G.pagesize - 1;
> ! allocation = xmalloc (alloc_size);
>
> page = (char *) (((size_t) allocation + G.pagesize - 1) &
> -G.pagesize);
> head_slop = page - allocation;
> if (multiple_pages)
> tail_slop = ((size_t) allocation + alloc_size) & (G.pagesize - 1);
> else
> tail_slop = alloc_size - entry_size - head_slop;
> enda = allocation + alloc_size - tail_slop;
>
> /* We allocated N pages, which are likely not aligned, leaving
> us with N-1 usable pages. We plan to place the page_group
> structure somewhere in the slop. */
> if (head_slop >= sizeof (page_group))
> group = (page_group *)page - 1;
> else
> --- 640,670 ----
> #ifdef USING_MALLOC_PAGE_GROUPS
> else
> {
> /* Allocate a large block of memory and serve out the aligned
> pages therein. This results in much less memory wastage
> than the traditional implementation of valloc. */
>
> char *allocation, *a, *enda;
> size_t alloc_size, head_slop, tail_slop;
> int multiple_pages = (entry_size == G.pagesize);
>
> if (multiple_pages)
> alloc_size = GGC_QUIRE_SIZE * G.pagesize;
> else
> alloc_size = entry_size + G.pagesize - 1;
> ! allocation = xcalloc (1, alloc_size);
>
> page = (char *) (((size_t) allocation + G.pagesize - 1) &
> -G.pagesize);
> head_slop = page - allocation;
> if (multiple_pages)
> tail_slop = ((size_t) allocation + alloc_size) & (G.pagesize - 1);
> else
> tail_slop = alloc_size - entry_size - head_slop;
> enda = allocation + alloc_size - tail_slop;
>
> /* We allocated N pages, which are likely not aligned, leaving
> us with N-1 usable pages. We plan to place the page_group
> structure somewhere in the slop. */
> if (head_slop >= sizeof (page_group))
> group = (page_group *)page - 1;
> else
>
>
> I suspect that it has stayed hidden for so long because most people
> probably have this mmap_anon:
>
> /* Define if mmap can get us zeroed pages using MAP_ANON(YMOUS). */
> #undef HAVE_MMAP_ANON
>
>
> #ifdef HAVE_MMAP_ANON
> # undef HAVE_MMAP_DEV_ZERO
>
> # include <sys/mman.h>
> # ifndef MAP_FAILED
> # define MAP_FAILED -1
> # endif
> # if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
> # define MAP_ANONYMOUS MAP_ANON
> # endif
> # define USING_MMAP
>
> #endif
>
> #ifndef USING_MMAP
> #define USING_MALLOC_PAGE_GROUPS
> #endif
>
>
> Seems pretty clear that zeroed pages are required.
>
> Looking at the code above and below this block, it uses xcalloc
> instead.
>
> It will take a couple of days to confirm that this is the last
> presumed bug affecting the MUSIC/SP port.
>
> In the meantime, can someone confirm that this code is wrong,
> and that xcalloc is definitely required?
>
> I had a look at the gcc4 code, and it is calling XNEWVEC which
> is also using xmalloc instead of xcalloc, so I presume it is still
> a problem today, under the right circumstances.
>
> It took about a week to track this one down. :-)
>
> One problem I have had for years, even on the MVS port, is that
> I need to use -Os to get the exact same register selection on the
> PC as the mainframe. -O0 and -O2 get slightly different register
> allocations, although all versions of the code are correct. If I'm
> lucky, this fix may make that problem go away, but as I said,
> it'll take a couple of days before the results are in, as each build
> takes about 2 hours (partly because i need to use -Os for
> consistency).
>
> Thanks. Paul.
>
>

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-11-04 16:47                         ` Ulrich Weigand
  2009-11-09 14:55                           ` Paul Edwards
@ 2011-08-13  8:34                           ` Paul Edwards
  2011-08-15 14:32                             ` Ulrich Weigand
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2011-08-13  8:34 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

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 <URL: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)
        return 1;
    }
  return 0;
}

Now because I know that it is MEM and REG_P, I can actually
put in a check to detect that and abort it.

But that then causes more inefficient code to be generated
in other circumstances:

<          L     2,12(4)
<          MVC   104(24,13),0(2)
---
>          LA    4,104(,13)
>          LA    5,24(0,0)
>          L     2,12(6)
>          LR    3,5
>          MVCL  4,2

Any idea what can be done?

Thanks.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2011-08-13  8:34                           ` Paul Edwards
@ 2011-08-15 14:32                             ` Ulrich Weigand
  2011-08-15 15:26                               ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2011-08-15 14:32 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Paul Edwards wrote:

> 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:

That's right.  It is not good to have a constraint that accepts
more than the predicate, since reload will at this point only
consider the constraint.  Adding a more restricted constraint
should be the proper fix for this problem.

> 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:

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.

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2011-08-15 14:32                             ` Ulrich Weigand
@ 2011-08-15 15:26                               ` Paul Edwards
  2011-08-15 17:23                                 ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2011-08-15 15:26 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

> 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:

LR    9,13
AR    9,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
<          ST    2,128(13)
<          ST    3,4+128(13)
<          ST    2,136(13)
<          ST    3,4+136(13)
<          ST    2,144(13)
<          ST    3,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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2011-08-15 15:26                               ` Paul Edwards
@ 2011-08-15 17:23                                 ` Ulrich Weigand
  2011-08-16 11:20                                   ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2011-08-15 17:23 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Paul Edwards wrote:

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

That's weird.  What does the reload dump (.greg) say?
 
> And it had a knock-on effect too, producing bad code elsewhere:
> 
> <          SLR   2,2
> <          SLR   3,3
> <          ST    2,128(13)
> <          ST    3,4+128(13)
> <          ST    2,136(13)
> <          ST    3,4+136(13)
> <          ST    2,144(13)
> <          ST    3,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.

It seems the literal is not marked as being doubleword.  That might
be related to the fact that const_int's do not carry a mode, so you
cannot just look at the literal's mode to determine the required
size, but have to take the full instruction into account ...

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2011-08-15 17:23                                 ` Ulrich Weigand
@ 2011-08-16 11:20                                   ` Paul Edwards
  2011-08-16 13:26                                     ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2011-08-16 11:20 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

>> Unfortunately it's not quite right, seemingly not loading R9 properly:
>>
>> LR    9,13
>> AR    9,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)
         ST    2,92(13)
         LA    1,88(,13)
         L     15,=V(PRINTF)
         BALR  14,15
         LR    3,13           <========= probably wrong
         AR    3,13           <========= else this is wrong
         MVC   0(10,3),0(2)

Thanks.  Paul.



#include <stdio.h>
#include <string.h>

#define MAXBLKSZ 32767

typedef struct { int ipldev; } PDOS;

typedef struct {
    char ds1dsnam[44]; /* dataset name */
    char ds1fmtid; /* must be set to '1' */
    char startcchh[4];
} DSCB1;



int pdosLoadExe(PDOS *pdos, char *prog, char *parm)
{
    char *raw;
    char *initial;
    char *load;
    /* Standard C programs can start at a predictable offset */
    int entry;
    int cyl;
    int head;
    int rec;
    int i;
    int j;
    char tbuf[MAXBLKSZ];
    char srchprog[FILENAME_MAX+10]; /* give an extra space */
    int cnt = -1;
    int lastcnt = 0;
    int ret = 0;
    DSCB1 dscb1;
    int pe = 0;
    int exeLen;

    /* try to find the load module's location */

    printf("in pdosLoadExe with %.8s\n", prog);
    /* +++ replace this 8 with some constant */
    memcpy(srchprog, prog, 10);
    printf("srchprog now %.8s\n", srchprog);
    srchprog[8] = ' ';
    *strchr(srchprog, ' ') = '\0';
    strcat(srchprog, ".EXE "); /* extra space deliberate */
    printf("going to search for %s\n", srchprog);

    /* read VOL1 record */
    cnt = rdblock(pdos->ipldev, 0, 0, 3, tbuf, MAXBLKSZ);
    if (cnt >= 20)
    {
        cyl = head = rec = 0;
        /* +++ probably time to create some macros for this */
        memcpy((char *)&cyl + sizeof(int) - 2, tbuf + 15, 2);
        memcpy((char *)&head + sizeof(int) - 2, tbuf + 17, 2);
        memcpy((char *)&rec + sizeof(int) - 1, tbuf + 19, 1);

        while ((cnt =
               rdblock(pdos->ipldev, cyl, head, rec, &dscb1, sizeof dscb1))
               > 0)
        {
            if (cnt >= sizeof dscb1)
            {
                if (dscb1.ds1fmtid == '1')
                {
                    dscb1.ds1fmtid = ' '; /* for easy comparison */
                    if (memcmp(dscb1.ds1dsnam,
                               srchprog,
                               strlen(srchprog)) == 0)
                    {
                        cyl = head = 0;
                        rec = 1;
                        /* +++ more macros needed here */
                        memcpy((char *)&cyl + sizeof(int) - 2,
                               dscb1.startcchh, 2);
                        memcpy((char *)&head + sizeof(int) - 2,
                               dscb1.startcchh + 2, 2);
                        break;
                    }
                }
            }
            rec++;
        }
    }

    if (cnt <= 0)
    {
        printf("about to zap %s\n", srchprog);
        *strchr(srchprog, ' ') = '\0';
        printf("executable %s not found!\n", srchprog);
        return (-1);
    }

    return (ret);
}




         COPY  PDPTOP
         CSECT
* Program text area
LC0      EQU   *
         DC    C'in pdosLoadExe with %.8s'
         DC    X'15'
         DC    X'0'
LC1      EQU   *
         DC    C'srchprog now %.8s'
         DC    X'15'
         DC    X'0'
LC2      EQU   *
         DC    C'.EXE '
         DC    X'0'
LC3      EQU   *
         DC    C'going to search for %s'
         DC    X'15'
         DC    X'0'
LC4      EQU   *
         DC    C'about to zap %s'
         DC    X'15'
         DC    X'0'
LC5      EQU   *
         DC    C'executable %s not found!'
         DC    X'15'
         DC    X'0'
         DS    0F
* X-func pdosLoadExe prologue
PDOSLOAD PDPPRLG CINDEX=0,FRAME=33224,BASER=12,ENTRY=YES
         B     FEN0
         LTORG
FEN0     EQU   *
         DROP  12
         BALR  12,0
         USING *,12
PG0      EQU   *
         LR    11,1
         L     10,=A(PGT0)
* Function pdosLoadExe code
         L     2,4(11)
         MVC   88(4,13),=A(LC0)
         ST    2,92(13)
         LA    1,88(,13)
         L     15,=V(PRINTF)
         BALR  14,15
         LR    3,13
         AR    3,13
         MVC   0(10,3),0(2)
         MVC   88(4,13),=A(LC1)
         L     2,=F'32880'
         AR    2,13
         ST    2,92(13)
         LA    1,88(,13)
         L     15,=V(PRINTF)
         BALR  14,15
         L     2,=F'32768'
         LA    3,64(0,0)
         STC   3,120(2,13)
         L     2,=F'32880'
         AR    2,13
         ST    2,88(13)
         MVC   92(4,13),=F'64'
         LA    1,88(,13)
         L     15,=V(STRCHR)
         BALR  14,15
         MVI   0(15),0
         ST    2,88(13)
         MVC   92(4,13),=A(LC2)
         LA    1,88(,13)
         L     15,=V(STRCAT)
         BALR  14,15
         MVC   88(4,13),=A(LC3)
         ST    2,92(13)
         LA    1,88(,13)
         L     15,=V(PRINTF)
         BALR  14,15
         L     3,0(11)
         MVC   88(4,13),0(3)
         MVC   92(4,13),=F'0'
         MVC   96(4,13),=F'0'
         MVC   100(4,13),=F'3'
         LA    2,112(,13)
         ST    2,104(13)
         MVC   108(4,13),=F'32767'
         LA    1,88(,13)
         L     15,=V(RDBLOCK)
         BALR  14,15
         LR    6,15
         LA    3,19(0,0)
         CR    15,3
         BNH   L2
         L     2,=F'33216'
         AR    2,13
         MVC   0(4,2),=F'0'
         L     9,=F'33212'
         AR    9,13
         MVC   0(4,9),=F'0'
         L     8,=F'33208'
         AR    8,13
         MVC   0(4,8),=F'0'
         MVC   2(2,8),127(13)
         MVC   2(2,9),129(13)
         MVC   3(1,2),131(13)
         B     L3
L8       EQU   *
         LA    2,48(0,0)
         CLR   6,2
         BNH   L5
         L     3,=F'33040'
         IC    2,156(3,13)
         CLM   2,1,=XL1'F1'
         BNE   L5
         LA    2,64(0,0)
         STC   2,156(3,13)
         L     3,=F'32880'
         AR    3,13
         ST    3,88(13)
         LA    1,88(,13)
         L     15,=V(STRLEN)
         BALR  14,15
         LA    4,112(,13)
         A     4,=F'33040'
         LR    5,15
         LA    2,112(,13)
         A     2,=F'32768'
         LR    3,15
         LA    15,1(0,0)
         CLCL  4,2
         BH    *+12
         BL    *+6
         SLR   15,15
         LNR   15,15
         LTR   15,15
         BE    L10
L5       EQU   *
         L     2,0(7)
         A     2,=F'1'
         ST    2,0(7)
L3       EQU   *
         L     3,0(11)
         MVC   88(4,13),0(3)
         MVC   92(4,13),0(8)
         MVC   96(4,13),0(9)
         L     7,=F'33216'
         AR    7,13
         MVC   100(4,13),0(7)
         LR    2,13
         A     2,=F'33152'
         ST    2,104(13)
         MVC   108(4,13),=F'49'
         LA    1,88(,13)
         L     15,=V(RDBLOCK)
         BALR  14,15
         LR    6,15
         LTR   15,15
         BH    L8
L2       EQU   *
         SLR   15,15
         LTR   6,6
         BH    L1
         MVC   88(4,13),=A(LC4)
         L     2,=F'32880'
         AR    2,13
         ST    2,92(13)
         LA    1,88(,13)
         L     15,=V(PRINTF)
         BALR  14,15
         ST    2,88(13)
         MVC   92(4,13),=F'64'
         LA    1,88(,13)
         L     15,=V(STRCHR)
         BALR  14,15
         MVI   0(15),0
         MVC   88(4,13),=A(LC5)
         ST    2,92(13)
         LA    1,88(,13)
         L     15,=V(PRINTF)
         BALR  14,15
         L     15,=F'-1'
         B     L1
L10      EQU   *
         ST    15,0(9)
         ST    15,0(8)
         MVC   0(4,7),=F'1'
         L     2,=F'33085'
         LH    2,112(2,13)
         STH   2,2(8)
         L     2,=F'33087'
         LH    2,112(2,13)
         STH   2,2(9)
         B     L2
L1       EQU   *
* Function pdosLoadExe epilogue
         PDPEPIL
* Function pdosLoadExe literal pool
         DS    0F
         LTORG
* Function pdosLoadExe page table
         DS    0F
PGT0     EQU   *
         DC    A(PG0)
         END




;; Function pdosLoadExe

;; 12 regs to allocate: 74 (2) 73 (2) 66 41 63 25 106 100 105 47 90 26
;; 25 conflicts: 25 41 11
;; 25 preferences: 15
;; 26 conflicts: 26 27 41 46 47 63 64 66 70 73 74 90 100 105 106 111 2 11 15
;; 27 conflicts: 26 27 47 90 2 11 15
;; 41 conflicts: 25 26 41 47 63 64 66 70 73 74 79 82 90 100 105 106 2 11 15
;; 46 conflicts: 26 46 47 90 2 11
;; 47 conflicts: 26 27 41 46 47 63 64 66 70 73 74 90 100 105 106 111 2 11 15
;; 63 conflicts: 26 41 47 63 64 90 100 105 106 2 11
;; 64 conflicts: 26 41 47 63 64 90 100 105 106 2 11
;; 66 conflicts: 26 41 47 66 73 74 90 100 105 106 11
;; 70 conflicts: 26 41 47 70 73 74 90 100 105 106 11 15
;; 73 conflicts: 26 41 47 66 70 73 74 90 100 105 106 11 15
;; 74 conflicts: 26 41 47 66 70 73 74 90 100 105 106 11 15
;; 79 conflicts: 41 79 100 105 2 11
;; 82 conflicts: 41 82 105 2 11
;; 84 conflicts: 84 2 11 15
;; 90 conflicts: 26 27 41 46 47 63 64 66 70 73 74 90 100 105 106 111 2 11 15
;; 100 conflicts: 26 41 47 63 64 66 70 73 74 79 90 100 105 106 111 2 11 15
;; 105 conflicts: 26 41 47 63 64 66 70 73 74 79 82 90 100 105 106 111 2 11 
15
;; 106 conflicts: 26 41 47 63 64 66 70 73 74 90 100 105 106 2 11 15
;; 111 conflicts: 26 47 90 100 105 111 2 11

Spilling for insn 3.
Spilling for insn 4.
Spilling for insn 32.
Spilling for insn 33.
Spilling for insn 38.
Using reg 3 for reload 0
Using reg 3 for reload 1
Spilling for insn 41.
Spilling for insn 43.
Using reg 2 for reload 1
Spilling for insn 47.
Using reg 3 for reload 1
Spilling for insn 50.
Using reg 2 for reload 1
Spilling for insn 51.
Spilling for insn 54.
Spilling for insn 57.
Using reg 2 for reload 1
Spilling for insn 58.
Spilling for insn 61.
Spilling for insn 63.
Using reg 2 for reload 1
Spilling for insn 66.
Using reg 2 for reload 0
Spilling for insn 67.
Spilling for insn 68.
Spilling for insn 69.
Spilling for insn 70.
Using reg 2 for reload 1
Spilling for insn 71.
Spilling for insn 75.
Using reg 2 for reload 0
Spilling for insn 80.
Spilling for insn 81.
Spilling for insn 82.
Spilling for insn 86.
Spilling for insn 90.
Spilling for insn 94.
Spilling for insn 114.
Using reg 2 for reload 0
Spilling for insn 120.
Spilling for insn 127.
Using reg 2 for reload 1
Spilling for insn 132.
Using reg 2 for reload 1
Spilling for insn 139.
Spilling for insn 143.
Spilling for insn 173.
Using reg 2 for reload 0
Spilling for insn 98.
Using reg 2 for reload 0
Spilling for insn 99.
Spilling for insn 100.
Spilling for insn 101.
Spilling for insn 103.
Using reg 2 for reload 0
Spilling for insn 104.
Spilling for insn 189.
Spilling for insn 191.
Spilling for insn 195.
Spilling for insn 196.
Spilling for insn 199.
Spilling for insn 201.
Spilling for insn 203.
Spilling for insn 151.
Spilling for insn 152.
Spilling for insn 154.
Spilling for insn 159.
Spilling for insn 164.

Reloads for insn # 4
Reload 0: reload_in (SI) = (mem/f:SI (plus:SI (reg/f:SI 11 11)
                                                        (const_int 4 [0x4])) 
[3 prog+0 S4 A32])
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 1), optional
         reload_in_reg: (mem/f:SI (plus:SI (reg/f:SI 11 11)
                                                        (const_int 4 [0x4])) 
[3 prog+0 S4 A32])

Reloads for insn # 32
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])

Reloads for insn # 33
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])

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)

Reloads for insn # 41
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])

Reloads for insn # 43
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
Reload 1: reload_in (SI) = (plus:SI (reg/f:SI 13 13)
                                                    (const_int 32880 
[0x8070]))
         ALL_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (plus:SI (reg/f:SI 13 13)
                                                    (const_int 32880 
[0x8070]))
         reload_reg_rtx: (reg:SI 2 2)

Reloads for insn # 47
Reload 0: reload_out (QI) = (mem/s:QI (plus:SI (plus:SI (reg/f:SI 13 13)
                                                            (reg:SI 2 2 
[46]))
                                                        (const_int 120 
[0x78])) [0 srchprog+8 S1 A64])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/s:QI (plus:SI (plus:SI (reg/f:SI 13 13)
                                                            (reg:SI 2 2 
[46]))
                                                        (const_int 120 
[0x78])) [0 srchprog+8 S1 A64])
Reload 1: reload_in (QI) = (const_int 64 [0x40])
         ADDR_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (const_int 64 [0x40])
         reload_reg_rtx: (reg:QI 3 3)

Reloads for insn # 50
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
Reload 1: reload_in (SI) = (plus:SI (reg/f:SI 13 13)
                                                    (const_int 32880 
[0x8070]))
         ALL_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (plus:SI (reg/f:SI 13 13)
                                                    (const_int 32880 
[0x8070]))
         reload_reg_rtx: (reg:SI 2 2)

Reloads for insn # 51
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])

Reloads for insn # 54
Reload 0: reload_out (QI) = (mem:QI (reg:SI 15 15) [0 S1 A8])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem:QI (reg:SI 15 15) [0 S1 A8])

Reloads for insn # 57
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
Reload 1: reload_in (SI) = (plus:SI (reg/f:SI 13 13)
                                                    (const_int 32880 
[0x8070]))
         ALL_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (plus:SI (reg/f:SI 13 13)
                                                    (const_int 32880 
[0x8070]))
         reload_reg_rtx: (reg:SI 2 2)

Reloads for insn # 58
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])

Reloads for insn # 61
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])

Reloads for insn # 63
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
Reload 1: reload_in (SI) = (plus:SI (reg/f:SI 13 13)
                                                    (const_int 32880 
[0x8070]))
         ALL_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (plus:SI (reg/f:SI 13 13)
                                                    (const_int 32880 
[0x8070]))
         reload_reg_rtx: (reg:SI 2 2)

Reloads for insn # 66
Reload 0: reload_in (SI) = (reg/v/f:SI 26 [ pdos ])
         ADDR_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 1)
         reload_in_reg: (reg/v/f:SI 26 [ pdos ])
         reload_reg_rtx: (reg:SI 3 3)
Reload 1: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])

Reloads for insn # 67
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])

Reloads for insn # 68
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 96 
[0x60])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 96 
[0x60])) [0 S4 A32])

Reloads for insn # 69
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 100 
[0x64])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 100 
[0x64])) [0 S4 A32])

Reloads for insn # 70
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 104 
[0x68])) [0 S4 A32])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 104 
[0x68])) [0 S4 A32])
Reload 1: reload_in (SI) = (plus:SI (reg/f:SI 13 13)
                                                    (const_int 112 [0x70]))
         ALL_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (plus:SI (reg/f:SI 13 13)
                                                    (const_int 112 [0x70]))
         reload_reg_rtx: (reg:SI 2 2)

Reloads for insn # 71
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 108 
[0x6c])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 108 
[0x6c])) [0 S4 A32])

Reloads for insn # 75
Reload 0: reload_in (SI) = (const_int 19 [0x13])
         ADDR_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (const_int 19 [0x13])
         reload_reg_rtx: (reg:SI 3 3)

Reloads for insn # 80
Reload 0: reload_out (SI) = (mem/f:SI (reg/f:SI 2 2 [111]) [4 S4 A8])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (reg/f:SI 2 2 [111]) [4 S4 A8])

Reloads for insn # 81
Reload 0: reload_out (SI) = (mem/f:SI (reg/f:SI 9 9 [105]) [4 S4 A8])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (reg/f:SI 9 9 [105]) [4 S4 A8])

Reloads for insn # 82
Reload 0: reload_out (SI) = (mem/f:SI (reg/f:SI 8 8 [100]) [4 S4 A8])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (reg/f:SI 8 8 [100]) [4 S4 A8])

Reloads for insn # 86
Reload 0: reload_out (HI) = (mem:HI (plus:SI (reg/f:SI 8 8 [100])
                                                        (const_int 2 [0x2])) 
[0 S2 A16])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem:HI (plus:SI (reg/f:SI 8 8 [100])
                                                        (const_int 2 [0x2])) 
[0 S2 A16])

Reloads for insn # 90
Reload 0: reload_out (HI) = (mem:HI (plus:SI (reg/f:SI 9 9 [105])
                                                        (const_int 2 [0x2])) 
[0 S2 A16])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem:HI (plus:SI (reg/f:SI 9 9 [105])
                                                        (const_int 2 [0x2])) 
[0 S2 A16])

Reloads for insn # 94
Reload 0: reload_out (QI) = (mem:QI (plus:SI (reg/f:SI 2 2 [111])
                                                        (const_int 3 [0x3])) 
[0 S1 A8])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem:QI (plus:SI (reg/f:SI 2 2 [111])
                                                        (const_int 3 [0x3])) 
[0 S1 A8])

Reloads for insn # 114
Reload 0: reload_in (SI) = (const_int 48 [0x30])
         ADDR_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (const_int 48 [0x30])
         reload_reg_rtx: (reg:SI 2 2)

Reloads for insn # 120
Reload 0: reload_in (QI) = (mem/s:QI (plus:SI (plus:SI (reg/f:SI 13 13)
                                                            (reg:SI 3 3 
[63]))
                                                        (const_int 156 
[0x9c])) [0 dscb1.ds1fmtid+0 S1 A32])
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 1), optional
         reload_in_reg: (mem/s:QI (plus:SI (plus:SI (reg/f:SI 13 13)
                                                            (reg:SI 3 3 
[63]))
                                                        (const_int 156 
[0x9c])) [0 dscb1.ds1fmtid+0 S1 A32])

Reloads for insn # 127
Reload 0: reload_out (QI) = (mem/s:QI (plus:SI (plus:SI (reg/f:SI 13 13)
                                                            (reg:SI 3 3 
[63]))
                                                        (const_int 156 
[0x9c])) [0 dscb1.ds1fmtid+0 S1 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/s:QI (plus:SI (plus:SI (reg/f:SI 13 13)
                                                            (reg:SI 3 3 
[63]))
                                                        (const_int 156 
[0x9c])) [0 dscb1.ds1fmtid+0 S1 A32])
Reload 1: reload_in (QI) = (const_int 64 [0x40])
         ADDR_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (const_int 64 [0x40])
         reload_reg_rtx: (reg:QI 2 2)

Reloads for insn # 132
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
Reload 1: reload_in (SI) = (plus:SI (reg/f:SI 13 13)
                                                    (const_int 32880 
[0x8070]))
         ALL_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (plus:SI (reg/f:SI 13 13)
                                                    (const_int 32880 
[0x8070]))
         reload_reg_rtx: (reg:SI 3 3)

Reloads for insn # 139
Reload 0: reload_in (SI) = (plus:SI (reg/f:SI 13 13)
                                                    (const_int 112 [0x70]))
         reload_out (SI) = (reg:SI 4 4)
         DATA_REGS, RELOAD_OTHER (opnum = 0)
         reload_in_reg: (plus:SI (reg/f:SI 13 13)
                                                    (const_int 112 [0x70]))
         reload_out_reg: (subreg:SI (reg:DI 4 4 [73]) 0)
         reload_reg_rtx: (reg:SI 4 4)

Reloads for insn # 143
Reload 0: reload_in (SI) = (plus:SI (reg/f:SI 13 13)
                                                    (const_int 112 [0x70]))
         reload_out (SI) = (reg:SI 2 2)
         DATA_REGS, RELOAD_OTHER (opnum = 0)
         reload_in_reg: (plus:SI (reg/f:SI 13 13)
                                                    (const_int 112 [0x70]))
         reload_out_reg: (subreg:SI (reg:DI 2 2 [74]) 0)
         reload_reg_rtx: (reg:SI 2 2)

Reloads for insn # 173
Reload 0: reload_in (SI) = (mem/f:SI (reg/f:SI 7 7 [106]) [4 rec+0 S4 A32])
         reload_out (SI) = (mem/f:SI (reg/f:SI 7 7 [106]) [4 rec+0 S4 A32])
         DATA_REGS, RELOAD_OTHER (opnum = 0)
         reload_in_reg: (mem/f:SI (reg/f:SI 7 7 [106]) [4 rec+0 S4 A32])
         reload_out_reg: (mem/f:SI (reg/f:SI 7 7 [106]) [4 rec+0 S4 A32])
         reload_reg_rtx: (reg:SI 2 2)

Reloads for insn # 98
Reload 0: reload_in (SI) = (reg/v/f:SI 26 [ pdos ])
         ADDR_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 1)
         reload_in_reg: (reg/v/f:SI 26 [ pdos ])
         reload_reg_rtx: (reg:SI 3 3)
Reload 1: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])

Reloads for insn # 99
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])

Reloads for insn # 100
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 96 
[0x60])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 96 
[0x60])) [0 S4 A32])

Reloads for insn # 101
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 100 
[0x64])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 100 
[0x64])) [0 S4 A32])

Reloads for insn # 103
Reload 0: reload_in (SI) = (reg/f:SI 13 13)
         reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 104 
[0x68])) [0 S4 A32])
         DATA_REGS, RELOAD_OTHER (opnum = 0)
         reload_in_reg: (reg/f:SI 13 13)
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 104 
[0x68])) [0 S4 A32])
         reload_reg_rtx: (reg:SI 2 2)

Reloads for insn # 104
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 108 
[0x6c])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 108 
[0x6c])) [0 S4 A32])

Reloads for insn # 189
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])

Reloads for insn # 191
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])

Reloads for insn # 195
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])

Reloads for insn # 196
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])

Reloads for insn # 199
Reload 0: reload_out (QI) = (mem:QI (reg:SI 15 15) [0 S1 A8])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem:QI (reg:SI 15 15) [0 S1 A8])

Reloads for insn # 201
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])

Reloads for insn # 203
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])

Reloads for insn # 151
Reload 0: reload_out (SI) = (mem/f:SI (reg/f:SI 9 9 [105]) [4 head+0 S4 
A32])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (reg/f:SI 9 9 [105]) [4 head+0 S4 A32])

Reloads for insn # 152
Reload 0: reload_out (SI) = (mem/f:SI (reg/f:SI 8 8 [100]) [4 cyl+0 S4 A32])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (reg/f:SI 8 8 [100]) [4 cyl+0 S4 A32])

Reloads for insn # 154
Reload 0: reload_out (SI) = (mem/f:SI (reg/f:SI 7 7 [106]) [4 rec+0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (reg/f:SI 7 7 [106]) [4 rec+0 S4 A32])

Reloads for insn # 159
Reload 0: reload_out (HI) = (mem:HI (plus:SI (reg/f:SI 8 8 [100])
                                                        (const_int 2 [0x2])) 
[0 S2 A16])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0)
         reload_out_reg: (mem:HI (plus:SI (reg/f:SI 8 8 [100])
                                                        (const_int 2 [0x2])) 
[0 S2 A16])
         reload_reg_rtx: (reg:HI 2 2)
Reload 1: reload_in (HI) = (mem:HI (plus:SI (plus:SI (reg/f:SI 13 13)
                                                            (reg:SI 2 2 
[79]))
                                                        (const_int 112 
[0x70])) [0 S2 A8])
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 1), optional
         reload_in_reg: (mem:HI (plus:SI (plus:SI (reg/f:SI 13 13)
                                                            (reg:SI 2 2 
[79]))
                                                        (const_int 112 
[0x70])) [0 S2 A8])

Reloads for insn # 164
Reload 0: reload_out (HI) = (mem:HI (plus:SI (reg/f:SI 9 9 [105])
                                                        (const_int 2 [0x2])) 
[0 S2 A16])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0)
         reload_out_reg: (mem:HI (plus:SI (reg/f:SI 9 9 [105])
                                                        (const_int 2 [0x2])) 
[0 S2 A16])
         reload_reg_rtx: (reg:HI 2 2)
Reload 1: reload_in (HI) = (mem:HI (plus:SI (plus:SI (reg/f:SI 13 13)
                                                            (reg:SI 2 2 
[82]))
                                                        (const_int 112 
[0x70])) [0 S2 A8])
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 1), optional
         reload_in_reg: (mem:HI (plus:SI (plus:SI (reg/f:SI 13 13)
                                                            (reg:SI 2 2 
[82]))
                                                        (const_int 112 
[0x70])) [0 S2 A8])
;; Register dispositions:
25 in 15  27 in 2  41 in 6  46 in 2  63 in 3  64 in 2
66 in 15  70 in 15  73 in 4  74 in 2  79 in 2  82 in 2
84 in 2  100 in 8  105 in 9  106 in 7  111 in 2

;; Hard regs used:  2 3 4 5 6 7 8 9 11 13 15

(note 2 0 227 NOTE_INSN_DELETED)

;; Start of basic block 0, registers live: 11 [11] 13 [13]
(note 227 2 3 0 [bb 0] NOTE_INSN_BASIC_BLOCK)

(note 3 227 4 0 NOTE_INSN_DELETED)

(insn 4 3 6 0 (set (reg/v/f:SI 2 2 [orig:27 prog ] [27])
        (mem/f:SI (plus:SI (reg/f:SI 11 11)
                (const_int 4 [0x4])) [3 prog+0 S4 A32])) 15 {movsi} (nil)
    (expr_list:REG_EQUIV (mem/f:SI (plus:SI (reg/f:SI 11 11)
                (const_int 4 [0x4])) [3 prog+0 S4 A32])
        (nil)))

(note 6 4 32 0 NOTE_INSN_FUNCTION_BEG)

(insn 32 6 33 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 88 [0x58])) [0 S4 A32])
        (symbol_ref/f:SI ("*LC0") [flags 0x2] <string_cst 7d494c>)) 15 
{movsi} (nil)
    (nil))

(insn 33 32 34 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 92 [0x5c])) [0 S4 A32])
        (reg/v/f:SI 2 2 [orig:27 prog ] [27])) 15 {movsi} (insn_list 4 
(nil))
    (nil))

(call_insn 34 33 244 0 (set (reg:SI 15 15)
        (call (mem:QI (symbol_ref/v:SI ("printf") [flags 0x41] 
<function_decl 7729b4 printf>) [0 S1 A8])
            (const_int 8 [0x8]))) 132 {*i370.md:4869} (nil)
    (nil)
    (nil))

(note 244 34 37 0 NOTE_INSN_DELETED)

(note 37 244 271 0 NOTE_INSN_DELETED)

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

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

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

(insn 41 38 275 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 88 [0x58])) [0 S4 A32])
        (symbol_ref/f:SI ("*LC1") [flags 0x2] <string_cst 7d49d8>)) 15 
{movsi} (nil)
    (nil))

(insn 275 41 43 0 (set (reg:SI 2 2)
        (plus:SI (reg/f:SI 13 13)
            (const_int 32880 [0x8070]))) 40 {*i370.md:2127} (nil)
    (nil))

(insn 43 275 44 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 92 [0x5c])) [0 S4 A32])
        (reg:SI 2 2)) 15 {movsi} (nil)
    (nil))

(call_insn 44 43 269 0 (set (reg:SI 15 15)
        (call (mem:QI (symbol_ref/v:SI ("printf") [flags 0x41] 
<function_decl 7729b4 printf>) [0 S1 A8])
            (const_int 8 [0x8]))) 132 {*i370.md:4869} (nil)
    (nil)
    (nil))

(insn 269 44 276 0 (set (reg:SI 2 2 [46])
        (const_int 32768 [0x8000])) 15 {movsi} (nil)
    (expr_list:REG_EQUIV (const_int 32768 [0x8000])
        (nil)))

(insn 276 269 47 0 (set (reg:QI 3 3)
        (const_int 64 [0x40])) 18 {*i370.md:1098} (nil)
    (nil))

(insn 47 276 277 0 (set (mem/s:QI (plus:SI (plus:SI (reg/f:SI 13 13)
                    (reg:SI 2 2 [46]))
                (const_int 120 [0x78])) [0 srchprog+8 S1 A64])
        (reg:QI 3 3)) 19 {movqi} (insn_list 36 (nil))
    (nil))

(insn 277 47 50 0 (set (reg:SI 2 2)
        (plus:SI (reg/f:SI 13 13)
            (const_int 32880 [0x8070]))) 40 {*i370.md:2127} (nil)
    (nil))

(insn 50 277 51 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 88 [0x58])) [0 S4 A32])
        (reg:SI 2 2)) 15 {movsi} (nil)
    (nil))

(insn 51 50 52 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 92 [0x5c])) [0 S4 A32])
        (const_int 64 [0x40])) 15 {movsi} (nil)
    (nil))

(call_insn 52 51 53 0 (set (reg:SI 15 15)
        (call (mem:QI (symbol_ref/v:SI ("strchr") [flags 0x41] 
<function_decl 7b3654 strchr>) [0 S1 A8])
            (const_int 8 [0x8]))) 132 {*i370.md:4869} (nil)
    (nil)
    (nil))

(note 53 52 54 0 NOTE_INSN_DELETED)

(insn 54 53 57 0 (set (mem:QI (reg:SI 15 15) [0 S1 A8])
        (const_int 0 [0x0])) 18 {*i370.md:1098} (insn_list 52 (nil))
    (nil))

(insn 57 54 58 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 88 [0x58])) [0 S4 A32])
        (reg:SI 2 2)) 15 {movsi} (nil)
    (nil))

(insn 58 57 59 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 92 [0x5c])) [0 S4 A32])
        (symbol_ref/f:SI ("*LC2") [flags 0x2] <string_cst 7d4a8c>)) 15 
{movsi} (nil)
    (nil))

(call_insn 59 58 61 0 (set (reg:SI 15 15)
        (call (mem:QI (symbol_ref/v:SI ("strcat") [flags 0x41] 
<function_decl 7b1654 strcat>) [0 S1 A8])
            (const_int 8 [0x8]))) 132 {*i370.md:4869} (nil)
    (nil)
    (nil))

(insn 61 59 63 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 88 [0x58])) [0 S4 A32])
        (symbol_ref/f:SI ("*LC3") [flags 0x2] <string_cst 7d4adc>)) 15 
{movsi} (nil)
    (nil))

(insn 63 61 64 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 92 [0x5c])) [0 S4 A32])
        (reg:SI 2 2)) 15 {movsi} (nil)
    (nil))

(call_insn 64 63 278 0 (set (reg:SI 15 15)
        (call (mem:QI (symbol_ref/v:SI ("printf") [flags 0x41] 
<function_decl 7729b4 printf>) [0 S1 A8])
            (const_int 8 [0x8]))) 132 {*i370.md:4869} (nil)
    (nil)
    (nil))

(insn 278 64 66 0 (set (reg:SI 3 3)
        (mem/f:SI (reg/f:SI 11 11) [2 pdos+0 S4 A32])) 15 {movsi} (nil)
    (nil))

(insn 66 278 67 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 88 [0x58])) [0 S4 A32])
        (mem/s:SI (reg:SI 3 3) [4 <variable>.ipldev+0 S4 A32])) 15 {movsi} 
(insn_list 3 (nil))
    (nil))

(insn 67 66 68 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 92 [0x5c])) [0 S4 A32])
        (const_int 0 [0x0])) 15 {movsi} (nil)
    (nil))

(insn 68 67 69 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 96 [0x60])) [0 S4 A32])
        (const_int 0 [0x0])) 15 {movsi} (nil)
    (nil))

(insn 69 68 279 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 100 [0x64])) [0 S4 A32])
        (const_int 3 [0x3])) 15 {movsi} (nil)
    (nil))

(insn 279 69 70 0 (set (reg:SI 2 2)
        (plus:SI (reg/f:SI 13 13)
            (const_int 112 [0x70]))) 39 {*i370.md:2110} (nil)
    (nil))

(insn 70 279 71 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 104 [0x68])) [0 S4 A32])
        (reg:SI 2 2)) 15 {movsi} (insn_list 244 (nil))
    (nil))

(insn 71 70 72 0 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 108 [0x6c])) [0 S4 A32])
        (const_int 32767 [0x7fff])) 15 {movsi} (nil)
    (nil))

(call_insn 72 71 73 0 (set (reg:SI 15 15)
        (call (mem:QI (symbol_ref/v:SI ("rdblock") [flags 0x41] 
<function_decl 7bb21c rdblock>) [0 S1 A8])
            (const_int 24 [0x18]))) 132 {*i370.md:4869} (nil)
    (nil)
    (nil))

(insn 73 72 280 0 (set (reg/v:SI 6 6 [orig:41 cnt ] [41])
        (reg:SI 15 15)) 15 {movsi} (insn_list 72 (nil))
    (nil))

(insn 280 73 75 0 (set (reg:SI 3 3)
        (const_int 19 [0x13])) 15 {movsi} (nil)
    (nil))

(insn:QI 75 280 76 0 (set (cc0)
        (compare (reg/v:SI 6 6 [orig:41 cnt ] [41])
            (reg:SI 3 3))) 5 {cmpsi} (insn_list 73 (nil))
    (nil))

(jump_insn 76 75 228 0 (set (pc)
        (if_then_else (le (cc0)
                (const_int 0 [0x0]))
            (label_ref 182)
            (pc))) 112 {ble} (nil)
    (expr_list:REG_BR_PROB (const_int 5000 [0x1388])
        (nil)))
;; End of basic block 0, registers live:
11 [11] 13 [13] 26 41 47 90

;; Start of basic block 1, registers live: 11 [11] 13 [13] 26 47 90
(note 228 76 265 1 [bb 1] NOTE_INSN_BASIC_BLOCK)

(insn 265 228 80 1 (set (reg/f:SI 2 2 [111])
        (plus:SI (reg/f:SI 13 13)
            (const_int 33216 [0x81c0]))) 40 {*i370.md:2127} (nil)
    (expr_list:REG_EQUIV (plus:SI (reg/f:SI 13 13)
            (const_int 33216 [0x81c0]))
        (nil)))

(insn 80 265 259 1 (set (mem/f:SI (reg/f:SI 2 2 [111]) [4 S4 A8])
        (const_int 0 [0x0])) 15 {movsi} (insn_list 265 (nil))
    (nil))

(insn 259 80 81 1 (set (reg/f:SI 9 9 [105])
        (plus:SI (reg/f:SI 13 13)
            (const_int 33212 [0x81bc]))) 40 {*i370.md:2127} (nil)
    (expr_list:REG_EQUIV (plus:SI (reg/f:SI 13 13)
            (const_int 33212 [0x81bc]))
        (nil)))

(insn 81 259 254 1 (set (mem/f:SI (reg/f:SI 9 9 [105]) [4 S4 A8])
        (const_int 0 [0x0])) 15 {movsi} (insn_list 259 (nil))
    (nil))

(insn 254 81 82 1 (set (reg/f:SI 8 8 [100])
        (plus:SI (reg/f:SI 13 13)
            (const_int 33208 [0x81b8]))) 40 {*i370.md:2127} (nil)
    (expr_list:REG_EQUIV (plus:SI (reg/f:SI 13 13)
            (const_int 33208 [0x81b8]))
        (nil)))

(insn 82 254 85 1 (set (mem/f:SI (reg/f:SI 8 8 [100]) [4 S4 A8])
        (const_int 0 [0x0])) 15 {movsi} (insn_list 254 (nil))
    (nil))

(note 85 82 86 1 NOTE_INSN_DELETED)

(insn 86 85 89 1 (set (mem:HI (plus:SI (reg/f:SI 8 8 [100])
                (const_int 2 [0x2])) [0 S2 A16])
        (mem:HI (plus:SI (reg/f:SI 13 13)
                (const_int 127 [0x7f])) [0 S2 A8])) 16 {*i370.md:1004} (nil)
    (nil))

(note 89 86 90 1 NOTE_INSN_DELETED)

(insn 90 89 93 1 (set (mem:HI (plus:SI (reg/f:SI 9 9 [105])
                (const_int 2 [0x2])) [0 S2 A16])
        (mem:HI (plus:SI (reg/f:SI 13 13)
                (const_int 129 [0x81])) [0 S2 A8])) 16 {*i370.md:1004} (nil)
    (nil))

(note 93 90 94 1 NOTE_INSN_DELETED)

(insn 94 93 96 1 (set (mem:QI (plus:SI (reg/f:SI 2 2 [111])
                (const_int 3 [0x3])) [0 S1 A8])
        (mem:QI (plus:SI (reg/f:SI 13 13)
                (const_int 131 [0x83])) [0 S1 A8])) 18 {*i370.md:1098} (nil)
    (nil))

(note 96 94 176 1 NOTE_INSN_LOOP_BEG)

(jump_insn 176 96 177 1 (set (pc)
        (label_ref 97)) 126 {jump} (nil)
    (nil))
;; End of basic block 1, registers live:
11 [11] 13 [13] 26 47 90 100 105

(barrier 177 176 175)

;; Start of basic block 2, registers live: 11 [11] 13 [13] 26 41 47 90 100 
105 106
(code_label 175 177 229 2 8 "" [1 uses])

(note 229 175 281 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(insn 281 229 114 2 (set (reg:SI 2 2)
        (const_int 48 [0x30])) 15 {movsi} (nil)
    (nil))

(insn:QI 114 281 115 2 (set (cc0)
        (compare (reg/v:SI 6 6 [orig:41 cnt ] [41])
            (reg:SI 2 2))) 5 {cmpsi} (nil)
    (nil))

(jump_insn 115 114 230 2 (set (pc)
        (if_then_else (leu (cc0)
                (const_int 0 [0x0]))
            (label_ref 170)
            (pc))) 113 {bleu} (nil)
    (expr_list:REG_BR_PROB (const_int 5000 [0x1388])
        (nil)))
;; End of basic block 2, registers live:
11 [11] 13 [13] 26 41 47 90 100 105 106

;; Start of basic block 3, registers live: 11 [11] 13 [13] 26 41 47 90 100 
105 106
(note 230 115 119 3 [bb 3] NOTE_INSN_BASIC_BLOCK)

(insn 119 230 120 3 (set (reg:SI 3 3 [63])
        (const_int 33040 [0x8110])) 15 {movsi} (nil)
    (expr_list:REG_EQUIV (const_int 33040 [0x8110])
        (nil)))

(insn 120 119 121 3 (set (reg:QI 2 2 [orig:64 dscb1.ds1fmtid ] [64])
        (mem/s:QI (plus:SI (plus:SI (reg/f:SI 13 13)
                    (reg:SI 3 3 [63]))
                (const_int 156 [0x9c])) [0 dscb1.ds1fmtid+0 S1 A32])) 18 
{*i370.md:1098} (insn_list 119 (nil))
    (expr_list:REG_EQUIV (mem/s:QI (plus:SI (plus:SI (reg/f:SI 13 13)
                    (reg:SI 3 3 [63]))
                (const_int 156 [0x9c])) [0 dscb1.ds1fmtid+0 S1 A32])
        (expr_list:REG_EQUAL (mem/s:QI (plus:SI (reg/f:SI 13 13)
                    (const_int 33196 [0x81ac])) [0 dscb1.ds1fmtid+0 S1 A32])
            (nil))))

(insn:QI 121 120 122 3 (set (cc0)
        (compare (reg:QI 2 2 [orig:64 dscb1.ds1fmtid ] [64])
            (const_int -15 [0xfffffff1]))) 7 {*i370.md:517} (insn_list 120 
(nil))
    (nil))

(jump_insn 122 121 231 3 (set (pc)
        (if_then_else (ne (cc0)
                (const_int 0 [0x0]))
            (label_ref 170)
            (pc))) 105 {bne} (nil)
    (expr_list:REG_BR_PROB (const_int 8510 [0x213e])
        (nil)))
;; End of basic block 3, registers live:
11 [11] 13 [13] 26 41 47 63 90 100 105 106

;; Start of basic block 4, registers live: 11 [11] 13 [13] 26 41 47 63 90 
100 105 106
(note 231 122 282 4 [bb 4] NOTE_INSN_BASIC_BLOCK)

(insn 282 231 127 4 (set (reg:QI 2 2)
        (const_int 64 [0x40])) 18 {*i370.md:1098} (nil)
    (nil))

(insn 127 282 283 4 (set (mem/s:QI (plus:SI (plus:SI (reg/f:SI 13 13)
                    (reg:SI 3 3 [63]))
                (const_int 156 [0x9c])) [0 dscb1.ds1fmtid+0 S1 A32])
        (reg:QI 2 2)) 19 {movqi} (nil)
    (nil))

(insn 283 127 132 4 (set (reg:SI 3 3)
        (plus:SI (reg/f:SI 13 13)
            (const_int 32880 [0x8070]))) 40 {*i370.md:2127} (nil)
    (nil))

(insn 132 283 133 4 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 88 [0x58])) [0 S4 A32])
        (reg:SI 3 3)) 15 {movsi} (nil)
    (nil))

(call_insn 133 132 134 4 (set (reg:SI 15 15)
        (call (mem:QI (symbol_ref/v:SI ("strlen") [flags 0x41] 
<function_decl 7b557c strlen>) [0 S1 A8])
            (const_int 8 [0x8]))) 132 {*i370.md:4869} (nil)
    (nil)
    (nil))

(insn 134 133 284 4 (set (reg:SI 15 15 [70])
        (reg:SI 15 15)) 15 {movsi} (insn_list 133 (nil))
    (nil))

(insn 284 134 139 4 (set (reg:SI 4 4)
        (plus:SI (reg/f:SI 13 13)
            (const_int 112 [0x70]))) 39 {*i370.md:2110} (nil)
    (nil))

(insn 139 284 285 4 (set (reg:SI 4 4)
        (plus:SI (reg:SI 4 4)
            (const_int 33040 [0x8110]))) 41 {addsi3} (insn_list 137 (nil))
    (nil))

(insn 285 139 140 4 (set (reg:SI 4 4)
        (reg:SI 4 4)) 15 {movsi} (nil)
    (nil))

(insn 140 285 286 4 (set (reg:SI 5 5 [orig:73+4 ] [73])
        (reg:SI 15 15 [70])) 15 {movsi} (insn_list 134 (insn_list 139 
(nil)))
    (nil))

(insn 286 140 143 4 (set (reg:SI 2 2)
        (plus:SI (reg/f:SI 13 13)
            (const_int 112 [0x70]))) 39 {*i370.md:2110} (nil)
    (nil))

(insn 143 286 287 4 (set (reg:SI 2 2)
        (plus:SI (reg:SI 2 2)
            (const_int 32768 [0x8000]))) 41 {addsi3} (insn_list 141 (nil))
    (nil))

(insn 287 143 144 4 (set (reg:SI 2 2)
        (reg:SI 2 2)) 15 {movsi} (nil)
    (nil))

(insn 144 287 145 4 (set (reg:SI 3 3 [orig:74+4 ] [74])
        (reg:SI 15 15 [70])) 15 {movsi} (insn_list 143 (nil))
    (nil))

(insn 145 144 146 4 (parallel [
            (set (reg:SI 15 15 [66])
                (compare:SI (mem:BLK (reg:DI 4 4 [73]) [0 A8])
                    (mem:BLK (reg:DI 2 2 [74]) [0 A8])))
            (use (reg:DI 4 4 [73]))
            (use (reg:DI 2 2 [74]))
            (clobber (reg:DI 4 4 [73]))
            (clobber (reg:DI 2 2 [74]))
        ]) 12 {cmpmemsi_1} (insn_list 140 (insn_list 144 (nil)))
    (nil))

(insn:QI 146 145 147 4 (set (cc0)
        (reg:SI 15 15 [66])) 1 {tstsi} (insn_list 145 (nil))
    (nil))

(jump_insn 147 146 170 4 (set (pc)
        (if_then_else (eq (cc0)
                (const_int 0 [0x0]))
            (label_ref/s 268)
            (pc))) 104 {beq} (nil)
    (expr_list:REG_BR_PROB (const_int 500 [0x1f4])
        (nil)))
;; End of basic block 4, registers live:
11 [11] 13 [13] 26 41 47 66 90 100 105 106

;; Start of basic block 5, registers live: 11 [11] 13 [13] 26 47 90 100 105 
106
(code_label 170 147 235 5 5 "" [2 uses])

(note 235 170 172 5 [bb 5] NOTE_INSN_BASIC_BLOCK)

(note 172 235 288 5 NOTE_INSN_DELETED)

(insn 288 172 173 5 (set (reg:SI 2 2)
        (mem/f:SI (reg/f:SI 7 7 [106]) [4 rec+0 S4 A32])) 15 {movsi} (nil)
    (nil))

(insn 173 288 289 5 (set (reg:SI 2 2)
        (plus:SI (reg:SI 2 2)
            (const_int 1 [0x1]))) 41 {addsi3} (nil)
    (nil))

(insn 289 173 174 5 (set (mem/f:SI (reg/f:SI 7 7 [106]) [4 rec+0 S4 A32])
        (reg:SI 2 2)) 15 {movsi} (nil)
    (nil))
;; End of basic block 5, registers live:
11 [11] 13 [13] 26 47 90 100 105

(note 174 289 97 NOTE_INSN_LOOP_CONT)

;; Start of basic block 6, registers live: 11 [11] 13 [13] 26 47 90 100 105
(code_label 97 174 236 6 3 "" [1 uses])

(note 236 97 290 6 [bb 6] NOTE_INSN_BASIC_BLOCK)

(insn 290 236 98 6 (set (reg:SI 3 3)
        (mem/f:SI (reg/f:SI 11 11) [2 pdos+0 S4 A32])) 15 {movsi} (nil)
    (nil))

(insn 98 290 99 6 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 88 [0x58])) [0 S4 A32])
        (mem/s:SI (reg:SI 3 3) [4 <variable>.ipldev+0 S4 A32])) 15 {movsi} 
(nil)
    (nil))

(insn 99 98 100 6 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 92 [0x5c])) [0 S4 A32])
        (mem/f:SI (reg/f:SI 8 8 [100]) [4 cyl+0 S4 A32])) 15 {movsi} (nil)
    (nil))

(insn 100 99 260 6 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 96 [0x60])) [0 S4 A32])
        (mem/f:SI (reg/f:SI 9 9 [105]) [4 head+0 S4 A32])) 15 {movsi} (nil)
    (nil))

(insn 260 100 101 6 (set (reg/f:SI 7 7 [106])
        (plus:SI (reg/f:SI 13 13)
            (const_int 33216 [0x81c0]))) 40 {*i370.md:2127} (nil)
    (expr_list:REG_EQUIV (plus:SI (reg/f:SI 13 13)
            (const_int 33216 [0x81c0]))
        (nil)))

(insn 101 260 291 6 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 100 [0x64])) [0 S4 A32])
        (mem/f:SI (reg/f:SI 7 7 [106]) [4 rec+0 S4 A32])) 15 {movsi} 
(insn_list 260 (nil))
    (nil))

(insn 291 101 103 6 (set (reg:SI 2 2)
        (reg/f:SI 13 13)) 15 {movsi} (nil)
    (nil))

(insn 103 291 292 6 (set (reg:SI 2 2)
        (plus:SI (reg:SI 2 2)
            (const_int 33152 [0x8180]))) 41 {addsi3} (nil)
    (nil))

(insn 292 103 104 6 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 104 [0x68])) [0 S4 A32])
        (reg:SI 2 2)) 15 {movsi} (nil)
    (nil))

(insn 104 292 105 6 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 108 [0x6c])) [0 S4 A32])
        (const_int 49 [0x31])) 15 {movsi} (nil)
    (nil))

(call_insn 105 104 106 6 (set (reg:SI 15 15)
        (call (mem:QI (symbol_ref/v:SI ("rdblock") [flags 0x41] 
<function_decl 7bb21c rdblock>) [0 S1 A8])
            (const_int 24 [0x18]))) 132 {*i370.md:4869} (nil)
    (nil)
    (nil))

(insn 106 105 108 6 (set (reg/v:SI 6 6 [orig:41 cnt ] [41])
        (reg:SI 15 15)) 15 {movsi} (insn_list 105 (nil))
    (nil))

(insn:QI 108 106 109 6 (set (cc0)
        (reg/v:SI 6 6 [orig:41 cnt ] [41])) 1 {tstsi} (insn_list 106 (nil))
    (nil))

(jump_insn 109 108 180 6 (set (pc)
        (if_then_else (le (cc0)
                (const_int 0 [0x0]))
            (pc)
            (label_ref 175))) 122 {*i370.md:4516} (nil)
    (expr_list:REG_BR_PROB (const_int 9500 [0x251c])
        (nil)))
;; End of basic block 6, registers live:
11 [11] 13 [13] 26 41 47 90 100 105 106

(note 180 109 182 NOTE_INSN_LOOP_END)

;; Start of basic block 7, registers live: 11 [11] 13 [13] 41
(code_label 182 180 239 7 2 "" [2 uses])

(note 239 182 216 7 [bb 7] NOTE_INSN_BASIC_BLOCK)

(insn 216 239 184 7 (set (reg:SI 15 15 [orig:25 <result> ] [25])
        (const_int 0 [0x0])) 15 {movsi} (nil)
    (nil))

(insn:QI 184 216 185 7 (set (cc0)
        (reg/v:SI 6 6 [orig:41 cnt ] [41])) 1 {tstsi} (nil)
    (nil))

(jump_insn 185 184 240 7 (set (pc)
        (if_then_else (gt (cc0)
                (const_int 0 [0x0]))
            (label_ref 222)
            (pc))) 106 {bgt} (nil)
    (expr_list:REG_BR_PROB (const_int 9953 [0x26e1])
        (nil)))
;; End of basic block 7, registers live:
11 [11] 13 [13] 25

;; Start of basic block 8, registers live: 11 [11] 13 [13]
(note 240 185 189 8 [bb 8] NOTE_INSN_BASIC_BLOCK)

(insn 189 240 190 8 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 88 [0x58])) [0 S4 A32])
        (symbol_ref/f:SI ("*LC4") [flags 0x2] <string_cst 7d4d48>)) 15 
{movsi} (nil)
    (nil))

(insn 190 189 191 8 (set (reg/f:SI 2 2 [84])
        (plus:SI (reg/f:SI 13 13)
            (const_int 32880 [0x8070]))) 40 {*i370.md:2127} (nil)
    (expr_list:REG_EQUIV (plus:SI (reg/f:SI 13 13)
            (const_int 32880 [0x8070]))
        (nil)))

(insn 191 190 192 8 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 92 [0x5c])) [0 S4 A32])
        (reg/f:SI 2 2 [84])) 15 {movsi} (insn_list 190 (nil))
    (nil))

(call_insn 192 191 195 8 (set (reg:SI 15 15)
        (call (mem:QI (symbol_ref/v:SI ("printf") [flags 0x41] 
<function_decl 7729b4 printf>) [0 S1 A8])
            (const_int 8 [0x8]))) 132 {*i370.md:4869} (nil)
    (nil)
    (nil))

(insn 195 192 196 8 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 88 [0x58])) [0 S4 A32])
        (reg/f:SI 2 2 [84])) 15 {movsi} (nil)
    (nil))

(insn 196 195 197 8 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 92 [0x5c])) [0 S4 A32])
        (const_int 64 [0x40])) 15 {movsi} (nil)
    (nil))

(call_insn 197 196 198 8 (set (reg:SI 15 15)
        (call (mem:QI (symbol_ref/v:SI ("strchr") [flags 0x41] 
<function_decl 7b3654 strchr>) [0 S1 A8])
            (const_int 8 [0x8]))) 132 {*i370.md:4869} (nil)
    (nil)
    (nil))

(note 198 197 199 8 NOTE_INSN_DELETED)

(insn 199 198 201 8 (set (mem:QI (reg:SI 15 15) [0 S1 A8])
        (const_int 0 [0x0])) 18 {*i370.md:1098} (insn_list 197 (nil))
    (nil))

(insn 201 199 203 8 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 88 [0x58])) [0 S4 A32])
        (symbol_ref/f:SI ("*LC5") [flags 0x2] <string_cst 7d4d98>)) 15 
{movsi} (nil)
    (nil))

(insn 203 201 204 8 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 92 [0x5c])) [0 S4 A32])
        (reg/f:SI 2 2 [84])) 15 {movsi} (nil)
    (nil))

(call_insn 204 203 209 8 (set (reg:SI 15 15)
        (call (mem:QI (symbol_ref/v:SI ("printf") [flags 0x41] 
<function_decl 7729b4 printf>) [0 S1 A8])
            (const_int 8 [0x8]))) 132 {*i370.md:4869} (nil)
    (nil)
    (nil))

(insn 209 204 210 8 (set (reg:SI 15 15 [orig:25 <result> ] [25])
        (const_int -1 [0xffffffff])) 15 {movsi} (nil)
    (expr_list:REG_EQUAL (const_int -1 [0xffffffff])
        (nil)))

(jump_insn 210 209 211 8 (set (pc)
        (label_ref 222)) 126 {jump} (nil)
    (nil))
;; End of basic block 8, registers live:
11 [11] 13 [13] 25

(barrier 211 210 268)

;; Start of basic block 9, registers live: 11 [11] 13 [13] 41 66 100 105 106
(code_label 268 211 232 9 10 "" [1 uses])

(note 232 268 151 9 [bb 9] NOTE_INSN_BASIC_BLOCK)

(insn 151 232 152 9 (set (mem/f:SI (reg/f:SI 9 9 [105]) [4 head+0 S4 A32])
        (reg:SI 15 15 [66])) 15 {movsi} (nil)
    (nil))

(insn 152 151 154 9 (set (mem/f:SI (reg/f:SI 8 8 [100]) [4 cyl+0 S4 A32])
        (reg:SI 15 15 [66])) 15 {movsi} (nil)
    (nil))

(insn 154 152 157 9 (set (mem/f:SI (reg/f:SI 7 7 [106]) [4 rec+0 S4 A32])
        (const_int 1 [0x1])) 15 {movsi} (nil)
    (nil))

(note 157 154 158 9 NOTE_INSN_DELETED)

(insn 158 157 159 9 (set (reg:SI 2 2 [79])
        (const_int 33085 [0x813d])) 15 {movsi} (nil)
    (expr_list:REG_EQUIV (const_int 33085 [0x813d])
        (nil)))

(insn 159 158 293 9 (set (reg:HI 2 2)
        (mem:HI (plus:SI (plus:SI (reg/f:SI 13 13)
                    (reg:SI 2 2 [79]))
                (const_int 112 [0x70])) [0 S2 A8])) 16 {*i370.md:1004} 
(insn_list 158 (nil))
    (nil))

(insn 293 159 162 9 (set (mem:HI (plus:SI (reg/f:SI 8 8 [100])
                (const_int 2 [0x2])) [0 S2 A16])
        (reg:HI 2 2)) 16 {*i370.md:1004} (nil)
    (nil))

(note 162 293 163 9 NOTE_INSN_DELETED)

(insn 163 162 164 9 (set (reg:SI 2 2 [82])
        (const_int 33087 [0x813f])) 15 {movsi} (nil)
    (expr_list:REG_EQUIV (const_int 33087 [0x813f])
        (nil)))

(insn 164 163 294 9 (set (reg:HI 2 2)
        (mem:HI (plus:SI (plus:SI (reg/f:SI 13 13)
                    (reg:SI 2 2 [82]))
                (const_int 112 [0x70])) [0 S2 A8])) 16 {*i370.md:1004} 
(insn_list 163 (nil))
    (nil))

(insn 294 164 166 9 (set (mem:HI (plus:SI (reg/f:SI 9 9 [105])
                (const_int 2 [0x2])) [0 S2 A16])
        (reg:HI 2 2)) 16 {*i370.md:1004} (nil)
    (nil))

(jump_insn 166 294 167 9 (set (pc)
        (label_ref 182)) 126 {jump} (nil)
    (nil))
;; End of basic block 9, registers live:
11 [11] 13 [13] 41

(barrier 167 166 220)

(note 220 167 222 NOTE_INSN_FUNCTION_END)

;; Start of basic block 10, registers live: 11 [11] 13 [13] 25
(code_label 222 220 243 10 1 "" [2 uses])

(note 243 222 223 10 [bb 10] NOTE_INSN_BASIC_BLOCK)

(insn 223 243 226 10 (set (reg/i:SI 15 15 [ <result> ])
        (reg:SI 15 15 [orig:25 <result> ] [25])) 15 {movsi} (nil)
    (nil))

(insn 226 223 270 10 (use (reg/i:SI 15 15 [ <result> ])) -1 (insn_list 223 
(nil))
    (nil))
;; End of basic block 10, registers live:
11 [11] 13 [13] 15 [15]

(note 270 226 0 NOTE_INSN_DELETED)

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2011-08-16 11:20                                   ` Paul Edwards
@ 2011-08-16 13:26                                     ` Ulrich Weigand
  2011-08-18 12:15                                       ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2011-08-16 13:26 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Paul Edwards wrote:
> >> Unfortunately it's not quite right, seemingly not loading R9 properly:
> >>
> >> LR    9,13
> >> AR    9,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)
>          ST    2,92(13)
>          LA    1,88(,13)
>          L     15,=V(PRINTF)
>          BALR  14,15
>          LR    3,13           <========= probably wrong
>          AR    3,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 this is if the machine
         has a three-operand ADD insn that accepts the required operands.

         The simplest approach is to try to generate such an insn and see if it
         is recognized and matches its constraints.  If so, it can be used.

         It might be better not to actually emit the insn unless it is valid,
         but we need to pass the insn as an operand to `recog' and
         `extract_insn' and it is simpler to emit and then delete the insn if
         not valid than to dummy things up.  */

      rtx op0, op1, tem, insn;
      int code;

      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.  */

      if (GET_CODE (XEXP (in, 1)) == REG
          && REGNO (out) == REGNO (XEXP (in, 1)))
        tem = op0, op0 = op1, op1 = tem;

      if (op0 != XEXP (in, 0) || op1 != XEXP (in, 1))
        in = gen_rtx_PLUS (GET_MODE (in), op0, op1);

      insn = emit_insn (gen_rtx_SET (VOIDmode, out, in));
      code = recog_memoized (insn);

Note how this actually performs the check whether to swap operands
for commutativity.

Can you debug this and find out why this doesn't work in your case?

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2011-08-16 13:26                                     ` Ulrich Weigand
@ 2011-08-18 12:15                                       ` Paul Edwards
  2011-08-18 13:14                                         ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2011-08-18 12:15 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

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:
> >>
> >> LR    9,13
> >> AR    9,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)
>          ST    2,92(13)
>          LA    1,88(,13)
>          L     15,=V(PRINTF)
>          BALR  14,15
>          LR    3,13           <========= probably wrong
>          AR    3,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 this is if the machine
         has a three-operand ADD insn that accepts the required operands.

         The simplest approach is to try to generate such an insn and see if 
it
         is recognized and matches its constraints.  If so, it can be used.

         It might be better not to actually emit the insn unless it is 
valid,
         but we need to pass the insn as an operand to `recog' and
         `extract_insn' and it is simpler to emit and then delete the insn 
if
         not valid than to dummy things up.  */

      rtx op0, op1, tem, insn;
      int code;

      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.  */

      if (GET_CODE (XEXP (in, 1)) == REG
          && REGNO (out) == REGNO (XEXP (in, 1)))
        tem = op0, op0 = op1, op1 = tem;

      if (op0 != XEXP (in, 0) || op1 != XEXP (in, 1))
        in = gen_rtx_PLUS (GET_MODE (in), op0, op1);

      insn = emit_insn (gen_rtx_SET (VOIDmode, out, in));
      code = recog_memoized (insn);

Note how this actually performs the check whether to swap operands
for commutativity.

Can you debug this and find out why this doesn't work in your case?

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2011-08-18 12:15                                       ` Paul Edwards
@ 2011-08-18 13:14                                         ` Ulrich Weigand
  2011-08-18 14:18                                           ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2011-08-18 13:14 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

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.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2011-08-18 13:14                                         ` Ulrich Weigand
@ 2011-08-18 14:18                                           ` Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2011-08-18 14:18 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

Well done!  That generated sensible code:

L     15,=V(PRINTF)
BALR  14,15
L     3,=F'32880'
AR    3,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.Weigand@de.ibm.com 

^ permalink raw reply	[flat|nested] 162+ messages in thread

* negative indexes
  2009-11-28 16:03                                                                                       ` Richard Guenther
  2009-11-28 16:35                                                                                         ` Paul Edwards
  2010-05-26 14:40                                                                                         ` i370 port - status Paul Edwards
@ 2021-03-14  5:55                                                                                         ` Paul Edwards
  2021-03-14  8:05                                                                                           ` Richard Biener
  2 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2021-03-14  5:55 UTC (permalink / raw)
  To: gcc

If I have code like this:

char foo(char *p)
{
    return (p[-1]);
}

It generates a negative index, like this:

* Function foo code
         L     2,=F'-1'
         L     3,0(11)
         SLR   15,15
         IC    15,0(2,3)
* Function foo epilogue

See that (2,3) - that is adding both R2 + R3.
R3 is a pointer to a location in 4 GiB space.
R2 is now 0xFFFFFFFF

In 64-bit mode, both of those values are added
together and there is no address wrap, so it
accesses memory above the 4 GiB boundary
(between 4 GiB and 8 GiB to be precise)
which I don't have access to.

Is there a way of constraining index registers to positive
values?

I want it to instead generate
ALR 3,2
to add these two values together using 32-bit arithmetic,
causing truncation at 32 bits, then it can do
IC 15,0(3)
(ie no index)

I'm using GCC 3.2.3 using the i370 target if it makes a difference.

Thanks. Paul.


^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: negative indexes
  2021-03-14  5:55                                                                                         ` negative indexes Paul Edwards
@ 2021-03-14  8:05                                                                                           ` Richard Biener
  2021-03-14  8:12                                                                                             ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Richard Biener @ 2021-03-14  8:05 UTC (permalink / raw)
  To: Paul Edwards, Paul Edwards via Gcc, gcc

On March 14, 2021 6:55:32 AM GMT+01:00, Paul Edwards via Gcc <gcc@gcc.gnu.org> wrote:
>If I have code like this:
>
>char foo(char *p)
>{
>    return (p[-1]);
>}
>
>It generates a negative index, like this:
>
>* Function foo code
>         L     2,=F'-1'
>         L     3,0(11)
>         SLR   15,15
>         IC    15,0(2,3)
>* Function foo epilogue
>
>See that (2,3) - that is adding both R2 + R3.
>R3 is a pointer to a location in 4 GiB space.
>R2 is now 0xFFFFFFFF
>
>In 64-bit mode, both of those values are added
>together and there is no address wrap, so it
>accesses memory above the 4 GiB boundary
>(between 4 GiB and 8 GiB to be precise)
>which I don't have access to.
>
>Is there a way of constraining index registers to positive
>values?
>
>I want it to instead generate
>ALR 3,2
>to add these two values together using 32-bit arithmetic,
>causing truncation at 32 bits, then it can do
>IC 15,0(3)
>(ie no index)
>
>I'm using GCC 3.2.3 using the i370 target if it makes a difference.

You are likely missing a fix that sign extends offsets on Pmode!=ptr_mode targets. 3.2.3 is really old now ;) 

Richard. 

>Thanks. Paul.


^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: negative indexes
  2021-03-14  8:05                                                                                           ` Richard Biener
@ 2021-03-14  8:12                                                                                             ` Paul Edwards
  2021-03-14 13:37                                                                                               ` Richard Biener
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2021-03-14  8:12 UTC (permalink / raw)
  To: gcc, Richard Biener

Hi Richard. Thanks for your reply, but if I understand
you correctly, you are saying this fix is for situations
where the size of an integer is different from the size
of a pointer?

That is not my issue. The size is the same. Absolutely
everything is 32-bits in the program (long, int, char *,
void *, code addresses).

However, since I am running as AMODE 64, if someone
attempts to do an index by adding two 32-bit registers
together in a single instruction, that reference will
actually take effect, and go up into the 4 GiB to 8 GiB
region.

Is your answer still applicable (I don't really understand
your answer. :-) ).

Thanks. Paul.




-----Original Message----- 
From: Richard Biener
Sent: Sunday, March 14, 2021 7:05 PM
To: Paul Edwards ; Paul Edwards via Gcc ; gcc@gcc.gnu.org
Subject: Re: negative indexes

On March 14, 2021 6:55:32 AM GMT+01:00, Paul Edwards via Gcc 
<gcc@gcc.gnu.org> wrote:
>If I have code like this:
>
>char foo(char *p)
>{
>    return (p[-1]);
>}
>
>It generates a negative index, like this:
>
>* Function foo code
>         L     2,=F'-1'
>         L     3,0(11)
>         SLR   15,15
>         IC    15,0(2,3)
>* Function foo epilogue
>
>See that (2,3) - that is adding both R2 + R3.
>R3 is a pointer to a location in 4 GiB space.
>R2 is now 0xFFFFFFFF
>
>In 64-bit mode, both of those values are added
>together and there is no address wrap, so it
>accesses memory above the 4 GiB boundary
>(between 4 GiB and 8 GiB to be precise)
>which I don't have access to.
>
>Is there a way of constraining index registers to positive
>values?
>
>I want it to instead generate
>ALR 3,2
>to add these two values together using 32-bit arithmetic,
>causing truncation at 32 bits, then it can do
>IC 15,0(3)
>(ie no index)
>
>I'm using GCC 3.2.3 using the i370 target if it makes a difference.

You are likely missing a fix that sign extends offsets on Pmode!=ptr_mode 
targets. 3.2.3 is really old now ;)

Richard.

>Thanks. Paul. 


^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: negative indexes
  2021-03-14  8:12                                                                                             ` Paul Edwards
@ 2021-03-14 13:37                                                                                               ` Richard Biener
       [not found]                                                                                                 ` <755065BE2A0B4B508DD3A262B2A83801@DESKTOP0OKG1VA>
  0 siblings, 1 reply; 162+ messages in thread
From: Richard Biener @ 2021-03-14 13:37 UTC (permalink / raw)
  To: Paul Edwards, gcc

On March 14, 2021 9:12:01 AM GMT+01:00, Paul Edwards <mutazilah@gmail.com> wrote:
>Hi Richard. Thanks for your reply, but if I understand
>you correctly, you are saying this fix is for situations
>where the size of an integer is different from the size
>of a pointer?
>
>That is not my issue. The size is the same. Absolutely
>everything is 32-bits in the program (long, int, char *,
>void *, code addresses).
>
>However, since I am running as AMODE 64, if someone
>attempts to do an index by adding two 32-bit registers
>together in a single instruction, that reference will
>actually take effect, and go up into the 4 GiB to 8 GiB
>region.

And that's exactly what I said. Pmode is DImode but ptr_mode is SImode. 

>
>Is your answer still applicable (I don't really understand
>your answer. :-) ).
>
>Thanks. Paul.
>
>
>
>
>-----Original Message----- 
>From: Richard Biener
>Sent: Sunday, March 14, 2021 7:05 PM
>To: Paul Edwards ; Paul Edwards via Gcc ; gcc@gcc.gnu.org
>Subject: Re: negative indexes
>
>On March 14, 2021 6:55:32 AM GMT+01:00, Paul Edwards via Gcc 
><gcc@gcc.gnu.org> wrote:
>>If I have code like this:
>>
>>char foo(char *p)
>>{
>>    return (p[-1]);
>>}
>>
>>It generates a negative index, like this:
>>
>>* Function foo code
>>         L     2,=F'-1'
>>         L     3,0(11)
>>         SLR   15,15
>>         IC    15,0(2,3)
>>* Function foo epilogue
>>
>>See that (2,3) - that is adding both R2 + R3.
>>R3 is a pointer to a location in 4 GiB space.
>>R2 is now 0xFFFFFFFF
>>
>>In 64-bit mode, both of those values are added
>>together and there is no address wrap, so it
>>accesses memory above the 4 GiB boundary
>>(between 4 GiB and 8 GiB to be precise)
>>which I don't have access to.
>>
>>Is there a way of constraining index registers to positive
>>values?
>>
>>I want it to instead generate
>>ALR 3,2
>>to add these two values together using 32-bit arithmetic,
>>causing truncation at 32 bits, then it can do
>>IC 15,0(3)
>>(ie no index)
>>
>>I'm using GCC 3.2.3 using the i370 target if it makes a difference.
>
>You are likely missing a fix that sign extends offsets on
>Pmode!=ptr_mode 
>targets. 3.2.3 is really old now ;)
>
>Richard.
>
>>Thanks. Paul. 


^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: negative indexes
       [not found]                                                                                                 ` <755065BE2A0B4B508DD3A262B2A83801@DESKTOP0OKG1VA>
@ 2021-03-15  9:22                                                                                                   ` Richard Biener
  2021-03-15 13:55                                                                                                     ` extended segments on 80386 Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Richard Biener @ 2021-03-15  9:22 UTC (permalink / raw)
  To: Paul Edwards, GCC Development

On Sun, Mar 14, 2021 at 3:20 PM Paul Edwards <mutazilah@gmail.com> wrote:
>
> Thanks Richard.
>
> Based on what you said I made this change:
>
> C:\devel\gcc\gcc\config\i370>cvs diff
> cvs diff: Diffing .
> Index: i370.h
> ===================================================================
> RCS file: c:\cvsroot/gcc/gcc/config/i370/i370.h,v
> retrieving revision 1.51
> diff -r1.51 i370.h
> 1156c1156
> < #define Pmode SImode
> ---
> > #define Pmode DImode
>
> and I was really excited to see if it fixed the problem, but
> unfortunately the generated code is exactly the same.
>
> I looked further at the gcc source code but I don't really
> know what I'm doing. Do you have any further hints?

The above is likely not enough.  Give it was SImode
(I expected DImode) the backend is likely lying to the
middle-end in a lot more places and maybe not set up
to deal with 64bit address registers at all.


> Thanks. Paul.
>
>
>
>
> -----Original Message-----
> From: Richard Biener
> Sent: Monday, March 15, 2021 12:37 AM
> To: Paul Edwards ; gcc@gcc.gnu.org
> Subject: Re: negative indexes
>
> On March 14, 2021 9:12:01 AM GMT+01:00, Paul Edwards <mutazilah@gmail.com>
> wrote:
> >Hi Richard. Thanks for your reply, but if I understand
> >you correctly, you are saying this fix is for situations
> >where the size of an integer is different from the size
> >of a pointer?
> >
> >That is not my issue. The size is the same. Absolutely
> >everything is 32-bits in the program (long, int, char *,
> >void *, code addresses).
> >
> >However, since I am running as AMODE 64, if someone
> >attempts to do an index by adding two 32-bit registers
> >together in a single instruction, that reference will
> >actually take effect, and go up into the 4 GiB to 8 GiB
> >region.
>
> And that's exactly what I said. Pmode is DImode but ptr_mode is SImode.
>
> >
> >Is your answer still applicable (I don't really understand
> >your answer. :-) ).
> >
> >Thanks. Paul.
> >
> >
> >
> >
> >-----Original Message-----
> >From: Richard Biener
> >Sent: Sunday, March 14, 2021 7:05 PM
> >To: Paul Edwards ; Paul Edwards via Gcc ; gcc@gcc.gnu.org
> >Subject: Re: negative indexes
> >
> >On March 14, 2021 6:55:32 AM GMT+01:00, Paul Edwards via Gcc
> ><gcc@gcc.gnu.org> wrote:
> >>If I have code like this:
> >>
> >>char foo(char *p)
> >>{
> >>    return (p[-1]);
> >>}
> >>
> >>It generates a negative index, like this:
> >>
> >>* Function foo code
> >>         L     2,=F'-1'
> >>         L     3,0(11)
> >>         SLR   15,15
> >>         IC    15,0(2,3)
> >>* Function foo epilogue
> >>
> >>See that (2,3) - that is adding both R2 + R3.
> >>R3 is a pointer to a location in 4 GiB space.
> >>R2 is now 0xFFFFFFFF
> >>
> >>In 64-bit mode, both of those values are added
> >>together and there is no address wrap, so it
> >>accesses memory above the 4 GiB boundary
> >>(between 4 GiB and 8 GiB to be precise)
> >>which I don't have access to.
> >>
> >>Is there a way of constraining index registers to positive
> >>values?
> >>
> >>I want it to instead generate
> >>ALR 3,2
> >>to add these two values together using 32-bit arithmetic,
> >>causing truncation at 32 bits, then it can do
> >>IC 15,0(3)
> >>(ie no index)
> >>
> >>I'm using GCC 3.2.3 using the i370 target if it makes a difference.
> >
> >You are likely missing a fix that sign extends offsets on
> >Pmode!=ptr_mode
> >targets. 3.2.3 is really old now ;)
> >
> >Richard.
> >
> >>Thanks. Paul.
>

^ permalink raw reply	[flat|nested] 162+ messages in thread

* extended segments on 80386
  2021-03-15  9:22                                                                                                   ` Richard Biener
@ 2021-03-15 13:55                                                                                                     ` Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2021-03-15 13:55 UTC (permalink / raw)
  To: GCC Development

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.


^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 15:03     ` Joseph S. Myers
  2009-06-05 15:24       ` Paul Edwards
@ 2017-03-31 10:34       ` Paul Edwards
  1 sibling, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2017-03-31 10:34 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc

Hi Joseph. (reviving a thread from 2009)

I have been streamlining the execution
of MVS (i370) via my "runmvs" script
recently, and now it only takes a few
seconds to do a test on MVS because
I have taken out all the unnecessary
pauses and made lots of other
improvements, and bypassing bugs
in Hercules.

Numerous other i370 bugs have been
fixed in GCC 3.2.3 too.

So I decided it was time to take a look
at the test suite to see what state that
was in.

With the aid of a script (below), I got
the following results:

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

C:\devel\gcc\gcc\config\i370\test>grep passed results.txt   | wc
    516    1032   10278

C:\devel\gcc\gcc\config\i370\test>grep failed results.txt   | wc
    117     234    2373

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


I looked at the first few errors. One
was deficiencies with "long long"
which is currently in the "too hard"
basket.

Some were ASCII assumptions (the
i370 port is EBCDIC).

And there was a genuine bug which I
have passed on to Dave Pitts for
analysis.

Regarding the ASCII errors, here’s an
example:

C:\devel\gcc\gcc\testsuite\gcc.c-torture\execute>type 20000412-3.c
typedef struct {
  char y;
  char x[32];
} X;

int z (void)
{
  X xxx;
  xxx.x[0] =
  xxx.x[31] = '0';
  xxx.y = 0xf;
  return f (xxx, xxx);
}

int main (void)
{
  int val;

  val = z ();
  if (val != 0x60)
    abort ();
  exit (0);
}

int f(X x, X y)
{
  if (x.y != y.y)
    return 'F';

  return x.x[0] + y.x[0];
}


They have assumed that '0' is 0x30,
but on EBCDIC it is 0xf0.

The documentation says:

C:\devel\gcc\gcc\testsuite>grep PORTABLE readme.gcc
DO NOT PUT NON-PORTABLE TESTCASES IN gcc.c-torture.


So what do you suggest I do with this class
of error?

The choices seem to be:

1. Remove/ignore it as it is non-portable so
shouldn't be there in the first place.

2. Create a new internal define like __EBCDIC__
and if that is set, do something different.

3. Create a user-define like -DEBCDIC to be
tested.

4. Do something like:

#if '0' == 0x30

(untested)

5. Use an existing define, like __MVS__
and if that is set, do something-or-other.


Any suggestions?

I know 3.2.3 is very old, but this is a very
long road, and this is where the most
stable i370.md environment is.

BTW, I saw someone mention something
about a "compile farm". MVS/380 is a
freely available i370 platform which
allows you to run tests on MVS pretty
easily, if a time comes when people
want to run tests on MVS to see if
their code works on EBCDIC as C90
allows.

Here is what it looks like on my system:

Just call this script:

call mvsgccr cprog.c output.txt

and it produces an output file that
includes:

07.28.30 JOB    1  $HASP373 MVSGCCR  STARTED - INIT  3 - CLASS C - SYS BSP1
07.28.30 JOB    1  IEF403I MVSGCCR - STARTED - TIME=07.28.30
07.28.30 JOB    1  IEFACTRT - Stepname  Procstep  Program   Retcode
07.28.31 JOB    1  MVSGCCR    S1        CREATE    IEFBR14   RC= 0000
07.28.31 JOB    1 *IEF233A M 401,PCTOMF,,MVSGCCR,COMP
07.28.32 JOB    1  MVSGCCR    S1        COMP      GCCNOMM   RC= 0000
07.28.33 JOB    1  MVSGCCR    S1        ASM       ASMA90    RC= 0000
07.28.33 JOB    1  MVSGCCR    S1        LKED      IEWL      RC= 0000
07.28.33 JOB    1  MVSGCCR    S1        EXECC     CPROG     RC= 0000
07.28.33 JOB    1  IEF404I MVSGCCR - ENDED - TIME=07.28.33
07.28.33 JOB    1  $HASP395 MVSGCCR  ENDED

On a failure of a test case, this line:

07.28.33 JOB    1  MVSGCCR    S1        EXECC     CPROG     RC= 0000

changes to:

07.28.33 JOB    1  MVSGCCR    S1        EXECC     CPROG     RC= 0012


MVS is a very interesting environment
in my opinion, and it's cool to have
code working there too.

I was thinking that maybe for people
who don't wish to install MVS/380
or TK4- on their system, there could
be some sort of hacked ftp so that
people could go:

ftp some.site
put cprog.c
put go.txt (this hangs while the C
program is compiled)
get output.txt
bye

Or for the more generic case:
ftp some.different.site
put in.jcl
put in.zip
put go.txt (hangs possibly 10 minutes)
get output.txt
get out.zip
bye

(for when you wish to build an entire
application, like "sed", on MVS).

go.txt could have the required runmvs
command, such as:

runmvs in.jcl output.txt in.zip out.zip


Usage here:

C:\mvs380>runmvs
Usage runmvs jcl.file print.file [aux_input.file|none] 
[aux_output.file|none] [ascii|binary|rdwund|rdwvar|vart] [ascii|binary] 
[awstap.file|none]
e.g. runmvs compile.jcl output.txt world.c world.s ascii ascii
or runmvs buildgcc.jcl output.txt source.zip xmit.dat
default is for files (if provided) to be binary


BTW, is that the main testsuite I should
be running? There's 633 C files there. Is
that enough, given that I'm only building
and testing C, or should I also compile
the stuff in the "compile" directory at the
same level as "execute"?

Thanks. Paul.





C:\devel\gcc\gcc\config\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= 0000" 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 20000112-1.c
call onecomp 20000113-1.c
call onecomp 20000121-1.c
call onecomp 20000205-1.c
call onecomp 20000217-1.c
call onecomp 20000223-1.c
call onecomp 20000224-1.c
call onecomp 20000225-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
joseph@codesourcery.com 

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
@ 2014-02-13  4:23 Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2014-02-13  4:23 UTC (permalink / raw)
  To: gcc

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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2012-04-08 17:43 ` Ulrich Weigand
@ 2014-02-11 17:01   ` Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2014-02-11 17:01 UTC (permalink / raw)
  To: gcc

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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2012-04-07  5:45 Paul Edwards
@ 2012-04-08 17:43 ` Ulrich Weigand
  2014-02-11 17:01   ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2012-04-08 17:43 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Hi Paul,

> 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?

Well, sure, but this code is just the expander.  If you check the
RTL dumps, you'll notice that after the expand step, there will
indeed be just a single base register.

The problem is that RTL optimization steps *after* expand may
modify the generated RTX.  In particular reload will do so, and
it will be guided by the constraints to tell it which modifications
are allowed for this insn.  If the actual insn pattern (not the
expander) has a generic "m" constraint, reload will feel free to
replace the address with any generally valid address pattern for
the machine, including those that use an index registers, if it
considers this replacement profitable.

This is exactly the reason why you need a constraint letter
that accepts only addresses without index register, instead of
just using plain "m".

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
@ 2012-04-07  5:45 Paul Edwards
  2012-04-08 17:43 ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2012-04-07  5:45 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2012-04-06 18:16 ` Ulrich Weigand
@ 2012-04-07  4:12   ` Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2012-04-07  4:12 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

> 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 <rth@cygnus.com> */
        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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2012-04-06 12:49 Paul Edwards
@ 2012-04-06 18:16 ` Ulrich Weigand
  2012-04-07  4:12   ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2012-04-06 18:16 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Paul Edwards wrote:

> I've managed to isolate the problem to a small test program.
> 
> Any suggestions on how to debug this?

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

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

The "LA" pattern you showed accepts only "(certain) single register
+ constant", which doesn't match the pattern above "register +
register + constant".

The difficulty is now that while "LA" *does* actually support adding
base + index + displacement, you cannot simply add a pattern 
expressing that, because LA only does a 31-bit add, so it must only
be used to add addresses, not when adding general 32-bit SImode
values.

The way I handle this in the s390 port is to provide a "forced"
LA instruction pattern using a magic marker that prevents the
pattern from being matched by regular instructions, and then add
a secondary reload to emit that "forced" LA when reload needs
to load an address.

Here's the relevant snippets from the 3.4 s390 back-end:

/* We need a secondary reload when loading a PLUS which is
   not a valid operand for LOAD ADDRESS.  */
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN)   \
  s390_secondary_input_reload_class ((CLASS), (MODE), (IN))

(define_insn "*la_31"
  [(set (match_operand:SI 0 "register_operand" "=d,d")
        (match_operand:QI 1 "address_operand" "U,W"))]
  "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
  "@
   la\t%0,%a1
   lay\t%0,%a1"
  [(set_attr "op_type"  "RX,RXY")
   (set_attr "type"     "la")])

(define_insn "force_la_31"
  [(set (match_operand:SI 0 "register_operand" "=d,d")
        (match_operand:QI 1 "address_operand" "U,W"))
   (use (const_int 0))]
  "!TARGET_64BIT"
  "@
   la\t%0,%a1
   lay\t%0,%a1"
  [(set_attr "op_type"  "RX")
   (set_attr "type"     "la")])

(define_expand "reload_insi"
  [(parallel [(match_operand:SI 0 "register_operand" "=a")
              (match_operand:SI 1 "s390_plus_operand" "")
              (match_operand:SI 2 "register_operand" "=&a")])]
  "!TARGET_64BIT"
{
  s390_expand_plus_operand (operands[0], operands[1], operands[2]);
  DONE;
})

(and of course the functions in s390.c called by these.)

You ought to be able to do something similar in your backend ...


Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2012-04-05 13:32   ` Paul Edwards
@ 2012-04-06 18:13     ` Ulrich Weigand
  0 siblings, 0 replies; 162+ messages in thread
From: Ulrich Weigand @ 2012-04-06 18:13 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Paul Edwards wrote:

> 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'00000000");
>     } else {
>        fprintf (FILE, "=XL8'FFFFFFFF");
>     }
>     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.

Well, even on 32-bit you may get 64-bit integer constants,
e.g. via the "long long" data type:

  long long x = 0x123456789abcdefLL;

However, the real question in your case is whether those are
represented as CONST_INT.  This is only true if HOST_WIDE_INT
is a 64-bit type; otherwise, such constants would be represented
as a CONST_DOUBLE.

Whether or not HOST_WIDE_INT is a 64-bit type now depends on
which *host* you're building GCC as a cross-compiler on.  If
you only ever support 32-bit hosts, then HOST_WIDE_INT will
always be a 32-bit type, and the code above should be fine.

If you want to support 64-bit hosts as well, however, you
will need to handle 64-bit CONST_INT values too.

> 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?

Yes, exactly.

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
@ 2012-04-06 12:49 Paul Edwards
  2012-04-06 18:16 ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2012-04-06 12:49 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

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 -0000       1.23
--- i370.md     6 Apr 2012 04:03:21 -0000       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'0000000000000000'
1796c1796
<          MVC   120(8,13),=F'0'
---
>          MVC   120(8,13),=XL8'0000000000000000'




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 <URL: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_page (0, 2, 0);
;      return \"AR^I%0,%2\";
;    }
;  if (GET_CODE (operands[2]) == CONST_INT)
;    {
;      if (INTVAL (operands[2]) == -1)
;^I{
;          CC_STATUS_INIT;  /* add assumes CC but BCTR doesn't set CC */
;^I  mvs_check_page (0, 2, 0);
;^I  return \"BCTR^I%0,0\";
;^I}
;    }
;  mvs_check_page (0, 4, 0);
;  return \"A^I%0,%2\";
;}"
;   [(set_attr "length" "4")]
;)


But that seemed to invoke some sort of bug in the main compiler:

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

C:\devel\gcc\gcc>gdb --args
gccmvs -DUSE_MEMMGR -Os -S -DHAVE_CONFIG_H -DIN_GCC
-DPUREISO -I ../../pdos/pdpclib -I . -I config/i370 -I ../include
alias.
c
GNU gdb 6.5.50.20060706-cvs (cygwin-special)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "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, 10000);
  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'00000000");
    } else {
       fprintf (FILE, "=XL8'FFFFFFFF");
    }
    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.Weigand@de.ibm.com 

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
@ 2012-04-06  5:51 Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2012-04-06  5:51 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

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 -0000       1.23
--- i370.md     6 Apr 2012 04:03:21 -0000       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'0000000000000000'
1796c1796
<          MVC   120(8,13),=F'0'
---
>          MVC   120(8,13),=XL8'0000000000000000'




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 <URL: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_page (0, 2, 0);
;      return \"AR^I%0,%2\";
;    }
;  if (GET_CODE (operands[2]) == CONST_INT)
;    {
;      if (INTVAL (operands[2]) == -1)
;^I{
;          CC_STATUS_INIT;  /* add assumes CC but BCTR doesn't set CC */
;^I  mvs_check_page (0, 2, 0);
;^I  return \"BCTR^I%0,0\";
;^I}
;    }
;  mvs_check_page (0, 4, 0);
;  return \"A^I%0,%2\";
;}"
;   [(set_attr "length" "4")]
;)


But that seemed to invoke some sort of bug in the main compiler:

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

C:\devel\gcc\gcc>gdb --args 
gccmvs -DUSE_MEMMGR -Os -S -DHAVE_CONFIG_H -DIN_GCC
-DPUREISO -I ../../pdos/pdpclib -I . -I config/i370 -I ../include 
alias.
c
GNU gdb 6.5.50.20060706-cvs (cygwin-special)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain 
conditions.
Type "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, 10000);
  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'00000000");
    } else {
       fprintf (FILE, "=XL8'FFFFFFFF");
    }
    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.Weigand@de.ibm.com 

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2011-08-22 12:23 ` Ulrich Weigand
@ 2012-04-05 13:32   ` Paul Edwards
  2012-04-06 18:13     ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2012-04-05 13:32 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

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'00000000");
    } else {
       fprintf (FILE, "=XL8'FFFFFFFF");
    }
    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.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2011-08-20 12:15 Paul Edwards
@ 2011-08-22 12:23 ` Ulrich Weigand
  2012-04-05 13:32   ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2011-08-22 12:23 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

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.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
@ 2011-08-20 12:15 Paul Edwards
  2011-08-22 12:23 ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2011-08-20 12:15 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

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.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
@ 2011-08-20 10:09 Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2011-08-20 10:09 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

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
         DS    0F
* 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   *
         LR    11,1
         L     10,=A(PGT0)
* Function foo code
         MVC 112(8,13),=F'0'
         SLR   8,8
         SLR   9,9
         LR    6,8
         LR    7,9
         L     3,0(11)
         L     2,8(11)
         LH    4,0(3)
         N     4,=XL4'0000FFFF'
         ST    4,104(13)
         LA    5,110(0,0)
         CLR   4,5
         BE    L3
         BH    L6
         LA    15,109(0,0)
         CLR   4,15
         BE    L4
         B     L7
L6       EQU   *
         L     5,104(13)
         LA    4,112(0,0)
         CLR   5,4
         BE    L5
         B     L7
L3       EQU   *
         A     2,=F'1'
         L     15,4(11)
         ST    15,116(13)
         L     4,112(13)
         L     5,4+112(13)
         MR    4,2
         ST    4,112(13)
         ST    5,4+112(13)
         LR    2,5
         B     L2
L4       EQU   *
         X     2,=F'-1'
         L     9,4(11)
         MR    8,2
         LR    2,9
         B     L2
L5       EQU   *
         L     7,4(11)
         MR    6,2
         LR    2,7
L2       EQU   *
         LTR   2,2
         BE    L7
         MVC   88(4,13),=F'0'
         ST    2,92(13)
         LA    1,88(,13)
         L     15,=V(ZZZ@947)
         BALR  14,15
         MVC   88(4,13),=F'88'
         SLR   5,5
         IC    5,2(3)
         ST    5,92(13)
         MVC   96(4,13),4(3)
         ST    15,100(13)
         LA    1,88(,13)
         L     15,=V(ZZZ@957)
         BALR  14,15
         LR    3,15
         B     L8
L7       EQU   *
         L     3,4(3)
L8       EQU   *
         LR    15,3
* Function foo epilogue
         PDPEPIL
* Function foo literal pool
         DS    0F
         LTORG
* Function foo page table
         DS    0F
PGT0     EQU   *
         DC    A(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 [ size ])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (reg:DI 31 [ size ])

Reloads for insn # 3
Reload 0: reload_in (SI) = (mem/f:SI (reg/f:SI 11 11) [2 addr+0 S4 A32])
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 1), optional
         reload_in_reg: (mem/f:SI (reg/f:SI 11 11) [2 addr+0 S4 A32])

Reloads for insn # 5
Reload 0: reload_in (SI) = (mem/f:SI (plus:SI (reg/f:SI 11 11)
                                                        (const_int 8 [0x8])) 
[3 n_refs+0 S4 A32])
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 1), optional
         reload_in_reg: (mem/f:SI (plus:SI (reg/f:SI 11 11)
                                                        (const_int 8 [0x8])) 
[3 n_refs+0 S4 A32])

Reloads for insn # 45
Reload 0: reload_in (HI) = (mem/s:HI (reg/v/f:SI 3 3 [orig:26 addr ] [26]) 
[4 S2 A32])
         reload_out (SI) = (reg:SI 37)
         DATA_REGS, RELOAD_OTHER (opnum = 0)
         reload_in_reg: (mem/s:HI (reg/v/f:SI 3 3 [orig:26 addr ] [26]) [4 
S2 A32])
         reload_out_reg: (reg:SI 37)
         reload_reg_rtx: (reg:SI 4 4)

Reloads for insn # 46
Reload 0: reload_in (SI) = (reg:SI 37)
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 0)
         reload_in_reg: (reg:SI 37)
         reload_reg_rtx: (reg:SI 4 4)
Reload 1: reload_in (SI) = (const_int 110 [0x6e])
         ADDR_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (const_int 110 [0x6e])
         reload_reg_rtx: (reg:SI 5 5)

Reloads for insn # 48
Reload 0: reload_in (SI) = (reg:SI 37)
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 0)
         reload_in_reg: (reg:SI 37)
         reload_reg_rtx: (reg:SI 4 4)
Reload 1: reload_in (SI) = (const_int 110 [0x6e])
         ADDR_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (const_int 110 [0x6e])
         reload_reg_rtx: (reg:SI 5 5)

Reloads for insn # 50
Reload 0: reload_in (SI) = (reg:SI 37)
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 0)
         reload_in_reg: (reg:SI 37)
         reload_reg_rtx: (reg:SI 4 4)
Reload 1: reload_in (SI) = (const_int 109 [0x6d])
         ADDR_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (const_int 109 [0x6d])
         reload_reg_rtx: (reg:SI 15 15)

Reloads for insn # 55
Reload 0: reload_in (SI) = (reg:SI 37)
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 0)
         reload_in_reg: (reg:SI 37)
         reload_reg_rtx: (reg:SI 5 5)
Reload 1: reload_in (SI) = (const_int 112 [0x70])
         ADDR_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (const_int 112 [0x70])
         reload_reg_rtx: (reg:SI 4 4)

Reloads for insn # 19
Reload 0: reload_out (SI) = (subreg:SI (reg:DI 31 [ size ]) 4)
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0)
         reload_out_reg: (subreg:SI (reg:DI 31 [ size ]) 4)
         reload_reg_rtx: (reg:SI 15 15)
Reload 1: reload_in (SI) = (reg/v:SI 27 [ size ])
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 1), optional
         reload_in_reg: (reg/v:SI 27 [ size ])

Reloads for insn # 20
Reload 0: reload_in (DI) = (reg:DI 31 [ size ])
         reload_out (DI) = (reg:DI 31 [ size ])
         DATA_REGS, RELOAD_OTHER (opnum = 0)
         reload_in_reg: (reg:DI 31 [ size ])
         reload_out_reg: (reg:DI 31 [ size ])
         reload_reg_rtx: (reg:DI 4 4)

Reloads for insn # 21
Reload 0: reload_in (SI) = (subreg:SI (reg:DI 31 [ size ]) 4)
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 1)
         reload_in_reg: (subreg:SI (reg:DI 31 [ size ]) 4)
         reload_reg_rtx: (reg:SI 5 5)

Reloads for insn # 29
Reload 0: reload_in (SI) = (reg/v:SI 27 [ size ])
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 1), optional
         reload_in_reg: (reg/v:SI 27 [ size ])

Reloads for insn # 37
Reload 0: reload_in (SI) = (reg/v:SI 27 [ size ])
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 1), optional
         reload_in_reg: (reg/v:SI 27 [ size ])

Reloads for insn # 63
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])

Reloads for insn # 64
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])

Reloads for insn # 67
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 88 
[0x58])) [0 S4 A32])

Reloads for insn # 71
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
         DATA_REGS, RELOAD_OTHER (opnum = 0)
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 92 
[0x5c])) [0 S4 A32])
         reload_reg_rtx: (reg:SI 5 5)

Reloads for insn # 72
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 96 
[0x60])) [0 S4 A32])
         NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 96 
[0x60])) [0 S4 A32])

Reloads for insn # 73
Reload 0: reload_out (SI) = (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 100 
[0x64])) [0 S4 A32])
         DATA_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
         reload_out_reg: (mem/f:SI (plus:SI (reg/f:SI 13 13)
                                                        (const_int 100 
[0x64])) [0 S4 A32])

Reloads for insn # 80
Reload 0: reload_in (SI) = (mem/s:SI (plus:SI (reg/v/f:SI 3 3 [orig:26 
addr ] [26])
                                                        (const_int 4 [0x4])) 
[0 <variable>.rtx+0 S4 A32])
         DATA_REGS, RELOAD_FOR_INPUT (opnum = 1), optional
         reload_in_reg: (mem/s:SI (plus:SI (reg/v/f:SI 3 3 [orig:26 addr ] 
[26])
                                                        (const_int 4 [0x4])) 
[0 <variable>.rtx+0 S4 A32])
;; Register dispositions:
26 in 3  28 in 2  29 in 2  34 in 8  35 in 6

;; Hard regs used:  2 3 4 5 6 7 8 9 11 13 15

(note 2 0 96 NOTE_INSN_DELETED)

;; Start of basic block 0, registers live: 11 [11] 13 [13]
(note 96 2 113 0 [bb 0] NOTE_INSN_BASIC_BLOCK)

(insn 113 96 114 0 (set (mem:DI (plus:SI (reg/f:SI 13 13)
                (const_int 112 [0x70])) [22 S8 A8])
        (const_int 0 [0x0])) 13 {*i370.md:786} (nil)
    (nil))

(insn 114 113 115 0 (set (reg:DI 8 8 [orig:34 size ] [34])
        (const_int 0 [0x0])) 13 {*i370.md:786} (nil)
    (nil))

(insn 115 114 3 0 (set (reg:DI 6 6 [orig:35 size ] [35])
        (const_int 0 [0x0])) 13 {*i370.md:786} (nil)
    (nil))

(insn 3 115 4 0 (set (reg/v/f:SI 3 3 [orig:26 addr ] [26])
        (mem/f:SI (reg/f:SI 11 11) [2 addr+0 S4 A32])) 15 {movsi} (nil)
    (expr_list:REG_EQUIV (mem/f:SI (reg/f:SI 11 11) [2 addr+0 S4 A32])
        (nil)))

(note 4 3 5 0 NOTE_INSN_DELETED)

(insn 5 4 6 0 (set (reg/v:SI 2 2 [orig:28 n_refs ] [28])
        (mem/f:SI (plus:SI (reg/f:SI 11 11)
                (const_int 8 [0x8])) [3 n_refs+0 S4 A32])) 15 {movsi} (nil)
    (expr_list:REG_EQUIV (mem/f:SI (plus:SI (reg/f:SI 11 11)
                (const_int 8 [0x8])) [3 n_refs+0 S4 A32])
        (nil)))

(note 6 5 44 0 NOTE_INSN_FUNCTION_BEG)

(note 44 6 117 0 NOTE_INSN_DELETED)

(insn 117 44 45 0 alias.c:15 (set (reg:HI 4 4)
        (mem/s:HI (reg/v/f:SI 3 3 [orig:26 addr ] [26]) [4 S2 A32])) 16 
{*i370.md:1004} (nil)
    (nil))

(insn 45 117 118 0 alias.c:15 (set (reg:SI 4 4)
        (zero_extend:SI (reg:HI 4 4))) 30 {zero_extendhisi2} (insn_list 3 
(nil))
    (nil))

(insn 118 45 119 0 alias.c:15 (set (mem:SI (plus:SI (reg/f:SI 13 13)
                (const_int 104 [0x68])) [21 S4 A8])
        (reg:SI 4 4)) 15 {movsi} (nil)
    (nil))

(insn 119 118 46 0 alias.c:15 (set (reg:SI 5 5)
        (const_int 110 [0x6e])) 15 {movsi} (nil)
    (nil))

(insn:QI 46 119 47 0 alias.c:15 (set (cc0)
        (compare (reg:SI 4 4)
            (reg:SI 5 5))) 5 {cmpsi} (insn_list 45 (nil))
    (nil))

(jump_insn 47 46 97 0 alias.c:15 (set (pc)
        (if_then_else (eq (cc0)
                (const_int 0 [0x0]))
            (label_ref 16)
            (pc))) 104 {beq} (nil)
    (expr_list:REG_BR_PROB (const_int 2900 [0xb54])
        (nil)))
;; End of basic block 0, registers live:
11 [11] 13 [13] 26 27 28 31 34 35 37

;; Start of basic block 1, registers live: 11 [11] 13 [13] 26 27 28 34 35 37
(note 97 47 48 1 [bb 1] NOTE_INSN_BASIC_BLOCK)

(insn:QI 48 97 49 1 alias.c:15 (set (cc0)
        (compare (reg:SI 4 4)
            (reg:SI 5 5))) 5 {cmpsi} (nil)
    (nil))

(jump_insn 49 48 98 1 alias.c:15 (set (pc)
        (if_then_else (gtu (cc0)
                (const_int 0 [0x0]))
            (label_ref 54)
            (pc))) 107 {bgtu} (nil)
    (expr_list:REG_BR_PROB (const_int 5000 [0x1388])
        (nil)))
;; End of basic block 1, registers live:
11 [11] 13 [13] 26 27 28 34 35 37

;; Start of basic block 2, registers live: 11 [11] 13 [13] 26 27 28 34 37
(note 98 49 120 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(insn 120 98 50 2 alias.c:15 (set (reg:SI 15 15)
        (const_int 109 [0x6d])) 15 {movsi} (nil)
    (nil))

(insn:QI 50 120 51 2 alias.c:15 (set (cc0)
        (compare (reg:SI 4 4)
            (reg:SI 15 15))) 5 {cmpsi} (nil)
    (nil))

(jump_insn 51 50 99 2 alias.c:15 (set (pc)
        (if_then_else (eq (cc0)
                (const_int 0 [0x0]))
            (label_ref 25)
            (pc))) 104 {beq} (nil)
    (expr_list:REG_BR_PROB (const_int 2900 [0xb54])
        (nil)))
;; End of basic block 2, registers live:
11 [11] 13 [13] 26 27 28 34

;; Start of basic block 3, registers live: 11 [11] 13 [13] 26
(note 99 51 52 3 [bb 3] NOTE_INSN_BASIC_BLOCK)

(jump_insn 52 99 53 3 alias.c:15 (set (pc)
        (label_ref 78)) 126 {jump} (nil)
    (nil))
;; End of basic block 3, registers live:
11 [11] 13 [13] 26

(barrier 53 52 54)

;; Start of basic block 4, registers live: 11 [11] 13 [13] 26 27 28 35 37
(code_label 54 53 100 4 6 "" [1 uses])

(note 100 54 121 4 [bb 4] NOTE_INSN_BASIC_BLOCK)

(insn 121 100 122 4 alias.c:15 (set (reg:SI 5 5)
        (mem:SI (plus:SI (reg/f:SI 13 13)
                (const_int 104 [0x68])) [21 S4 A8])) 15 {movsi} (nil)
    (nil))

(insn 122 121 55 4 alias.c:15 (set (reg:SI 4 4)
        (const_int 112 [0x70])) 15 {movsi} (nil)
    (nil))

(insn:QI 55 122 56 4 alias.c:15 (set (cc0)
        (compare (reg:SI 5 5)
            (reg:SI 4 4))) 5 {cmpsi} (nil)
    (nil))

(jump_insn 56 55 101 4 alias.c:15 (set (pc)
        (if_then_else (eq (cc0)
                (const_int 0 [0x0]))
            (label_ref 35)
            (pc))) 104 {beq} (nil)
    (expr_list:REG_BR_PROB (const_int 2900 [0xb54])
        (nil)))
;; End of basic block 4, registers live:
11 [11] 13 [13] 26 27 28 35

;; Start of basic block 5, registers live: 11 [11] 13 [13] 26
(note 101 56 57 5 [bb 5] NOTE_INSN_BASIC_BLOCK)

(jump_insn 57 101 58 5 alias.c:15 (set (pc)
        (label_ref 78)) 126 {jump} (nil)
    (nil))
;; End of basic block 5, registers live:
11 [11] 13 [13] 26

(barrier 58 57 16)

;; Start of basic block 6, registers live: 11 [11] 13 [13] 26 27 28 31
(code_label 16 58 102 6 3 "" [1 uses])

(note 102 16 17 6 [bb 6] NOTE_INSN_BASIC_BLOCK)

(note 17 102 18 6 ("alias.c") 15)

(insn 18 17 19 6 alias.c:15 (set (reg/v:SI 2 2 [orig:28 n_refs ] [28])
        (plus:SI (reg/v:SI 2 2 [orig:28 n_refs ] [28])
            (const_int 1 [0x1]))) 41 {addsi3} (nil)
    (nil))

(insn 19 18 123 6 alias.c:15 (set (reg:SI 15 15)
        (mem/f:SI (plus:SI (reg/f:SI 11 11)
                (const_int 4 [0x4])) [3 size+0 S4 A32])) 15 {movsi} (nil)
    (nil))

(insn 123 19 124 6 alias.c:15 (set (mem:SI (plus:SI (reg/f:SI 13 13)
                (const_int 116 [0x74])) [22 S4 A8])
        (reg:SI 15 15)) 15 {movsi} (nil)
    (nil))

(insn 124 123 20 6 alias.c:15 (set (reg:DI 4 4)
        (mem:DI (plus:SI (reg/f:SI 13 13)
                (const_int 112 [0x70])) [22 S8 A8])) 13 {*i370.md:786} (nil)
    (nil))

(insn 20 124 125 6 alias.c:15 (set (reg:DI 4 4)
        (mult:DI (reg:DI 4 4)
            (reg/v:SI 2 2 [orig:28 n_refs ] [28]))) 53 {*i370.md:2604} 
(insn_list 18 (insn_list 19 (nil)))
    (nil))

(insn 125 20 21 6 alias.c:15 (set (mem:DI (plus:SI (reg/f:SI 13 13)
                (const_int 112 [0x70])) [22 S8 A8])
        (reg:DI 4 4)) 13 {*i370.md:786} (nil)
    (nil))

(insn 21 125 22 6 alias.c:15 (set (reg/v:SI 2 2 [orig:29 offset ] [29])
        (reg:SI 5 5)) 15 {movsi} (insn_list 20 (nil))
    (expr_list:REG_EQUAL (mult:SI (reg:SI 30)
            (mem/f:SI (plus:SI (reg/f:SI 11 11)
                    (const_int 4 [0x4])) [3 size+0 S4 A32]))
        (nil)))

(note 22 21 23 6 ("alias.c") 16)

(jump_insn 23 22 24 6 alias.c:16 (set (pc)
        (label_ref 43)) 126 {jump} (nil)
    (nil))
;; End of basic block 6, registers live:
11 [11] 13 [13] 26 29

(barrier 24 23 25)

;; Start of basic block 7, registers live: 11 [11] 13 [13] 26 27 28 34
(code_label 25 24 103 7 4 "" [1 uses])

(note 103 25 26 7 [bb 7] NOTE_INSN_BASIC_BLOCK)

(note 26 103 27 7 ("alias.c") 18)

(note 27 26 28 7 NOTE_INSN_DELETED)

(insn 28 27 29 7 alias.c:18 (set (reg/v:SI 2 2 [orig:28 n_refs ] [28])
        (not:SI (reg/v:SI 2 2 [orig:28 n_refs ] [28]))) 86 {*i370.md:3685} 
(nil)
    (nil))

(insn 29 28 30 7 alias.c:18 (set (reg:SI 9 9 [orig:34 size+4 ] [34])
        (mem/f:SI (plus:SI (reg/f:SI 11 11)
                (const_int 4 [0x4])) [3 size+0 S4 A32])) 15 {movsi} (nil)
    (nil))

(insn 30 29 31 7 alias.c:18 (set (reg:DI 8 8 [orig:34 size ] [34])
        (mult:DI (reg:DI 8 8 [orig:34 size ] [34])
            (reg/v:SI 2 2 [orig:28 n_refs ] [28]))) 53 {*i370.md:2604} 
(insn_list 28 (insn_list 29 (nil)))
    (nil))

(insn 31 30 32 7 alias.c:18 (set (reg/v:SI 2 2 [orig:29 offset ] [29])
        (reg:SI 9 9 [orig:34 size+4 ] [34])) 15 {movsi} (insn_list 30 (nil))
    (expr_list:REG_EQUAL (mult:SI (reg:SI 33)
            (mem/f:SI (plus:SI (reg/f:SI 11 11)
                    (const_int 4 [0x4])) [3 size+0 S4 A32]))
        (nil)))

(note 32 31 33 7 ("alias.c") 19)

(jump_insn 33 32 34 7 alias.c:19 (set (pc)
        (label_ref 43)) 126 {jump} (nil)
    (nil))
;; End of basic block 7, registers live:
11 [11] 13 [13] 26 29

(barrier 34 33 35)

;; Start of basic block 8, registers live: 11 [11] 13 [13] 26 27 28 35
(code_label 35 34 104 8 5 "" [1 uses])

(note 104 35 36 8 [bb 8] NOTE_INSN_BASIC_BLOCK)

(note 36 104 37 8 ("alias.c") 21)

(insn 37 36 38 8 alias.c:21 (set (reg:SI 7 7 [orig:35 size+4 ] [35])
        (mem/f:SI (plus:SI (reg/f:SI 11 11)
                (const_int 4 [0x4])) [3 size+0 S4 A32])) 15 {movsi} (nil)
    (nil))

(insn 38 37 39 8 alias.c:21 (set (reg:DI 6 6 [orig:35 size ] [35])
        (mult:DI (reg:DI 6 6 [orig:35 size ] [35])
            (reg/v:SI 2 2 [orig:28 n_refs ] [28]))) 53 {*i370.md:2604} 
(insn_list 37 (nil))
    (nil))

(insn 39 38 40 8 alias.c:21 (set (reg/v:SI 2 2 [orig:29 offset ] [29])
        (reg:SI 7 7 [orig:35 size+4 ] [35])) 15 {movsi} (insn_list 38 (nil))
    (expr_list:REG_EQUAL (mult:SI (reg/v:SI 2 2 [orig:28 n_refs ] [28])
            (mem/f:SI (plus:SI (reg/f:SI 11 11)
                    (const_int 4 [0x4])) [3 size+0 S4 A32]))
        (nil)))
;; End of basic block 8, registers live:
11 [11] 13 [13] 26 29

(note 40 39 43 ("alias.c") 22)

;; Start of basic block 9, registers live: 11 [11] 13 [13] 26 29
(code_label 43 40 105 9 2 "" [2 uses])

(note 105 43 60 9 [bb 9] NOTE_INSN_BASIC_BLOCK)

(insn:QI 60 105 61 9 alias.c:22 (set (cc0)
        (reg/v:SI 2 2 [orig:29 offset ] [29])) 1 {tstsi} (nil)
    (nil))

(jump_insn 61 60 106 9 alias.c:22 (set (pc)
        (if_then_else (eq (cc0)
                (const_int 0 [0x0]))
            (label_ref 78)
            (pc))) 104 {beq} (nil)
    (expr_list:REG_BR_PROB (const_int 7000 [0x1b58])
        (nil)))
;; End of basic block 9, registers live:
11 [11] 13 [13] 26 29

;; Start of basic block 10, registers live: 11 [11] 13 [13] 26 29
(note 106 61 63 10 [bb 10] NOTE_INSN_BASIC_BLOCK)

(insn 63 106 64 10 alias.c:22 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 88 [0x58])) [0 S4 A32])
        (const_int 0 [0x0])) 15 {movsi} (nil)
    (nil))

(insn 64 63 65 10 alias.c:22 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 92 [0x5c])) [0 S4 A32])
        (reg/v:SI 2 2 [orig:29 offset ] [29])) 15 {movsi} (nil)
    (nil))

(call_insn 65 64 66 10 alias.c:22 (set (reg:SI 15 15)
        (call (mem:QI (symbol_ref/v:SI ("ZZZ_947") [flags 0x41] 
<function_decl c8c000 ZZZ_947>) [0 S1 A8])
            (const_int 8 [0x8]))) 132 {*i370.md:4869} (nil)
    (nil)
    (nil))

(note 66 65 67 10 NOTE_INSN_DELETED)

(insn 67 66 68 10 alias.c:22 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 88 [0x58])) [0 S4 A32])
        (const_int 88 [0x58])) 15 {movsi} (nil)
    (nil))

(note 68 67 69 10 NOTE_INSN_DELETED)

(note 69 68 70 10 NOTE_INSN_DELETED)

(note 70 69 71 10 NOTE_INSN_DELETED)

(insn 71 70 126 10 alias.c:22 (set (reg:SI 5 5)
        (zero_extend:SI (mem/s:QI (plus:SI (reg/v/f:SI 3 3 [orig:26 addr ] 
[26])
                    (const_int 2 [0x2])) [4 S1 A16]))) 31 {zero_extendqisi2} 
(nil)
    (nil))

(insn 126 71 72 10 alias.c:22 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 92 [0x5c])) [0 S4 A32])
        (reg:SI 5 5)) 15 {movsi} (nil)
    (nil))

(insn 72 126 73 10 alias.c:22 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 96 [0x60])) [0 S4 A32])
        (mem/s:SI (plus:SI (reg/v/f:SI 3 3 [orig:26 addr ] [26])
                (const_int 4 [0x4])) [0 <variable>.rtx+0 S4 A32])) 15 
{movsi} (nil)
    (nil))

(insn 73 72 74 10 alias.c:22 (set (mem/f:SI (plus:SI (reg/f:SI 13 13)
                (const_int 100 [0x64])) [0 S4 A32])
        (reg:SI 15 15)) 15 {movsi} (insn_list 65 (nil))
    (nil))

(call_insn 74 73 75 10 alias.c:22 (set (reg:SI 15 15)
        (call (mem:QI (symbol_ref/v:SI ("ZZZ_957") [flags 0x41] 
<function_decl c63af8 ZZZ_957>) [0 S1 A8])
            (const_int 16 [0x10]))) 132 {*i370.md:4869} (nil)
    (nil)
    (nil))

(insn 75 74 76 10 alias.c:22 (set (reg/v/f:SI 3 3 [orig:26 addr ] [26])
        (reg:SI 15 15)) 15 {movsi} (insn_list 74 (nil))
    (nil))

(jump_insn 76 75 77 10 alias.c:22 (set (pc)
        (label_ref 81)) 126 {jump} (nil)
    (nil))
;; End of basic block 10, registers live:
11 [11] 13 [13] 26

(barrier 77 76 78)

;; Start of basic block 11, registers live: 11 [11] 13 [13] 26
(code_label 78 77 107 11 7 "" [3 uses])

(note 107 78 80 11 [bb 11] NOTE_INSN_BASIC_BLOCK)

(insn 80 107 81 11 alias.c:22 (set (reg/v/f:SI 3 3 [orig:26 addr ] [26])
        (mem/s:SI (plus:SI (reg/v/f:SI 3 3 [orig:26 addr ] [26])
                (const_int 4 [0x4])) [0 <variable>.rtx+0 S4 A32])) 15 
{movsi} (nil)
    (nil))
;; End of basic block 11, registers live:
11 [11] 13 [13] 26

;; Start of basic block 12, registers live: 11 [11] 13 [13] 26
(code_label 81 80 108 12 8 "" [1 uses])

(note 108 81 89 12 [bb 12] NOTE_INSN_BASIC_BLOCK)

(note 89 108 92 12 NOTE_INSN_FUNCTION_END)

(insn 92 89 95 12 alias.c:22 (set (reg/i:SI 15 15 [ <result> ])
        (reg/v/f:SI 3 3 [orig:26 addr ] [26])) 15 {movsi} (nil)
    (nil))

(insn 95 92 116 12 alias.c:22 (use (reg/i:SI 15 15 [ <result> ])) -1 
(insn_list 92 (nil))
    (nil))
;; End of basic block 12, registers live:
11 [11] 13 [13] 15 [15]

(note 116 95 0 NOTE_INSN_DELETED)

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
@ 2011-08-20  7:44 Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2011-08-20  7:44 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
@ 2009-09-22 12:31 Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-09-22 12:31 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

> I have a theory that if both displacements in the S-type (ie register plus
> displacement) address are non-zero, that something fails.  So the
> next thing I will do is see if I can detect just that situation, and stop
> it going into the CLC.

I now have that detection in place, and done a self-compile, and all
is looking great.  No idea if that is producing a technically correct
compiler or not though (ie whether my workaround correctly
bypasses all circumstances).

So that leaves 2 more workarounds which I would like to reverse
out.  I'll spend some time on them next.

BFN.  Paul.




;
; cmpmemsi instruction pattern(s).
;

(define_expand "cmpmemsi"
  [(set (match_operand:SI 0 "general_operand" "")
   (compare (match_operand:BLK 1 "general_operand" "")
     (match_operand:BLK 2 "general_operand" "")))
     (use (match_operand:SI 3 "general_operand" ""))
     (use (match_operand:SI 4 "" ""))]
   ""
   "
{
  rtx op1, op2;
  int iv1 = 0;
  int iv2 = 0;

  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) (iv1 = INTVAL (XEXP (op1, 1))) < 4096))
    {
      op1 = operands[1];
    }
  else
    {
      op1 = gen_rtx_MEM (BLKmode, copy_to_mode_reg (SImode, op1));
    }

  op2 = XEXP (operands[2], 0);
  if (GET_CODE (op2) == REG
      || (GET_CODE (op2) == PLUS && GET_CODE (XEXP (op2, 0)) == REG
   && GET_CODE (XEXP (op2, 1)) == CONST_INT
   && (unsigned) (iv2 = INTVAL (XEXP (op2, 1))) < 4096))
    {
      op2 = operands[2];
    }
  else
    {
      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],
   gen_rtx_COMPARE (SImode, op1, op2)), /* was VOIDmode */
  gen_rtx_USE (VOIDmode, operands[3]))));
    }
  else
    {
        /* implementation suggested by  Richard Henderson <rth@cygnus.com> 
*/
        rtx reg1 = gen_reg_rtx (DImode);
        rtx reg2 = gen_reg_rtx (DImode);
        rtx result = operands[0];
        rtx mem1 = operands[1];
        rtx mem2 = operands[2];
        rtx len = operands[3];
        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);

        /* Compare! */
        emit_insn (gen_cmpmemsi_1 (result, reg1, reg2));
    }
  DONE;
}")

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

(define_insn ""
  [(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)"
  "*
{
  check_label_emit ();
  mvs_check_page (0, 22, 0);
  return \"CLC %O1(%c3,%R1),%2\;BH *+12\;BL *+6\;SLR %0,%0\;LNR %0,%0\";
}"
   [(set_attr "length" "22")]
)

; Compare a block that is larger than 255 bytes in length.
;        (mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "+d") 
0))
;        (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "+d") 
0))))

(define_insn "cmpmemsi_1"
  [(set (match_operand:SI 0 "register_operand" "+d")
        (compare:SI
        (mem:BLK (match_operand:DI 1 "register_operand" "+d") )
        (mem:BLK (match_operand:DI 2 "register_operand" "+d") )))
   (use (match_dup 1))
   (use (match_dup 2))
   (clobber (match_dup 1))
   (clobber (match_dup 2))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 18, 0);
  return \"LA %0,1(0,0)\;CLCL %1,%2\;BH *+12\;BL *+6\;SLR %0,%0\;LNR 
%0,%0\";
}"
   [(set_attr "length" "18")]
)

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-09-08 15:55     ` Paul Edwards
@ 2009-09-14 15:32       ` Ulrich Weigand
  0 siblings, 0 replies; 162+ messages in thread
From: Ulrich Weigand @ 2009-09-14 15:32 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Joseph S. Myers, gcc

Paul Edwards wrote:

Just one comment on this particular point:

> 4. There is one thing that doesn't have proper ASCII to EBCDIC
> translation being done - the __FUNCTION__ builtin.

It looks this was indeed a bug that was fixed for GCC 4.0.0:
http://gcc.gnu.org/ml/gcc-patches/2004-05/msg01773.html
(note that there were some minor revisions to the patch
before it was committed).

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 14:33 ` Joseph S. Myers
  2009-06-05 14:57   ` Paul Edwards
@ 2009-09-12 12:41   ` Paul Edwards
  1 sibling, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-09-12 12:41 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc

>> It was dropped from GCC 4 when there was supposedly no
>> maintainer available.  Actually, Dave Pitts and myself were
>> both maintaining it at that time, but we were both still working
>> on an old version of it (3.2). So gcc 3.4.6, circa 2004, was the
>> last time it was included in the normal GCC distribution.
>
> (For reference, the port was removed in SVN revision 77216; before then it
> had had various largely mechanical changes as part of changes to multiple
> back ends or target-independent code, with r69086 as the last vaguely
> i370-only change but no changes appearing to come from someone
> specifically working and testing on i370 for some years before then.  "svn
> log svn://gcc.gnu.org/svn/gcc/trunk/gcc/config/i370@77215" shows the
> history.)

I just took a look to see if there was anything changed on the head
that didn't make it into 3.4.6.  Short answer: no.

Long answer:

C:\devel\gccoff>diff gccnew gcchead
Only in gcchead: .svn
diff gccnew/i370.h gcchead/i370.h
530,531c530
< #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) 
\
<   ((CUM) = 0)
---
> #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT)  ((CUM) = 0)

I just need to delete that N_NAMED_ARGS when upgrading.

I'm sure that will be the least of my worries though.  I'm more
worried about things like the below.  :-)

Incidentally, 15 years of effort to get a hosted GCC compiler on
real MVS (not USS) came to realization on Jan 11, 2004:

http://osdir.com/ml/emulators.hercules390.mvs/2004-01/msg00031.html

(although it wasn't released until March 2004 when it was good
enough to self-compile.)

The revision that deleted i370 was made on Feb 4th, 2004.  How's
that for timing?

Incidentally, while it may look from this angle like the i370 port
wasn't being worked on, it's actually had a huge amount of
effort put into it.  The activity has just been in different forums
(like the one above).  It wasn't just GCC though.  A lot of
infrastructure was required.  E.g. even the assembler didn't
support such a huge number of externals that was being
generated by GCC, so first I hacked around that in GCC
itself, mapping a whole lot of "unused" flags to be the same,
and then reversed that out when someone came up with a
modification to the assembler.

Then we needed to switch from 24-bit mode to 31-bit mode to
get the required memory for GCC to self-compile.  Another
huge enterprise.

> I would encourage going through all the changes made to the i370 port on
> GCC mainline, after 3.1/3.2 branched and before the port was removed, to
> see what should be merged into your version for mainline; ultimately it
> would be up to you how you get it updated for all the mechanical changes
> on mainline since 3.2, but those changes (see command above to get logs)
> may be a useful guide to how to do some of the updates.

All the merging has already been done in the 3.4.6 effort.  The only
thing that I know of that is still "at large" is someone else who was
working "offline" and made some changes.  Specifically this:

http://osdir.com/ml/emulators.hercules390.mvs/2004-01/msg00008.html

as I just discovered the same problem with both of these strict moves
now that I too am using 3.4.6.

The i370.md looks correct to me (this is the movstricthi one):

> ;(define_insn ""
> ;  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
> ;     (match_operand:HI 1 "general_operand" "dSi"))]
> ;  ""
> ;  "*
> ;{
> ;  check_label_emit ();
> ;  if (REG_P (operands[1]))
> ;    {
> ;      mvs_check_page (0, 8, 0);
> ;      return \"STH   %1,\" CONVLO \"(,13)\;ICM       %0,3,\" CONVLO 
> \"(13)\";

> ;    }
> ;  else if (GET_CODE (operands[1]) == CONST_INT)
> ;    {
> ;      mvs_check_page (0, 4, 2);
> ;      return \"ICM   %0,3,%H1\";
> ;    }
> ;  mvs_check_page (0, 4, 0);
> ;  return \"ICM       %0,3,%1\";
> ;}"
> ;   [(set_attr "length" "8")]
> ;)

but I have had to comment it out, because otherwise I get code like
this generated:

L691     EQU   *
         SLR   2,2
         IC    2,0(8)
         LA    5,92(0,0)
         CLR   2,5
         BE    L699
         BH    L702
         ICM   5,3,=H'64'
         BE    L696
         ICM   5,3,=H'78'
         BE    L694
         B     L701

ie the LA and CLR combination are what I would expect, but gcc 3.4.6
has decided to use an ICM to move a constant in, which seems an
awful waste to me instead of using LA, but the real problem is that
it hasn't generated a CLR afterwards (it needs to compare against
register 2), so isn't taking a branch it should be.

I didn't have this problem in 3.2.3, which has a virtually identical
machine definition.  But I'd be really surprised to find a serious
compiler bug outside of the i370 code?!  I assume I'm just looking
in the wrong spot.

But at least I'm making progress.  :-)

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 15:44   ` Joseph S. Myers
  2009-06-05 15:52     ` Paul Edwards
@ 2009-09-08 15:55     ` Paul Edwards
  2009-09-14 15:32       ` Ulrich Weigand
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-09-08 15:55 UTC (permalink / raw)
  To: Joseph S. Myers, Ulrich Weigand; +Cc: gcc

>> 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
>
> I think the EBCDIC support is largely theoretical and not tested on any
> actual EBCDIC host (or target).  cpplib knows the character set name
> UTF-EBCDIC, but whenever it does anything internally that involves the
> encoding of its internal character set it uses UTF-8 rules (which is not
> something valid to do with UTF-EBCDIC).

Results are finally in.

EBCDIC (or arbitrary character set) support was introduced in 3.4.6,
and continues to be the same today, correct?

I've just succeeded today in getting gcc 3.4.6 to self-compile on an
EBCDIC host.  :-)  That's after a gcc 3.4.6 ascii to ebcdic cross-compile.

It's fascinating to look back at what it took.  Note that there are still
some relatively minor cleanups I have yet to do, but it won't change
much.

Caveats:

1. The generated (from machine definition) files are still generated on
the PC.

2. I am unable to do an optimized compile even as a cross-compile,
I get an internal error in this function:

gcse.c:

static void
compute_hash_table_work (struct hash_table *table)
{
...
  if (!current_bb) /* +++ why are we getting NULL here? */
  {
      printf("internal error in gcse\n");
      exit(EXIT_FAILURE);
  }
  FOR_EACH_BB (current_bb)

and indeed, I can't see anything that would initialize that current_bb,
so it's not that surprising that it's NULL!

3. As with gcc 3.2.3, the compiler is still producing slightly different
results on the PC vs mainframe, probably still because of floating
point comparisons being done to select the next register to use
or something like that.

4. There is one thing that doesn't have proper ASCII to EBCDIC
translation being done - the __FUNCTION__ builtin.

So here is the code generated on the PC:

         COPY  PDPTOP
         CSECT
* Program text area
@@V1     EQU   *
         DC    X'78'
         DC    X'31'
         DC    X'32'
         DC    X'33'
         DC    X'0'
LC0      EQU   *
         DC    C'%s %d %s'
         DC    X'15'
         DC    X'0'
LC1      EQU   *
         DC    C'zatest.c'
         DC    X'0'
         DS    0F
* X-func x123 prologue
X123     PDPPRLG CINDEX=0,FRAME=104,BASER=12,ENTRY=YES
         B     FEN0
         LTORG
FEN0     EQU   *
         DROP  12
         BALR  12,0
         USING *,12
PG0      EQU   *
         LR    11,1
         L     10,=A(PGT0)
* Function x123 code
         MVC   88(4,13),=A(LC0)
         MVC   92(4,13),=A(LC1)
         MVC   96(4,13),=F'5'
         MVC   100(4,13),=A(@@V1)
         LA    1,88(,13)
         L     15,=V(PRINTF)
         BALR  14,15
* Function x123 epilogue
         PDPEPIL
* Function x123 literal pool
         DS    0F
         LTORG
* Function x123 page table
         DS    0F
PGT0     EQU   *
         DC    A(PG0)
         END

for this source:

#include <stdlib.h>

void x123(void)
{
    printf("%s %d %s\n", __FILE__, __LINE__, __FUNCTION__);
}

However, that anomaly is not integral to getting the compiler on the
mainframe, and once on the mainframe, the problem goes away
with the next pass.  :-)

I think the problem is this function:

c-decl.c:
c_make_fname_decl (tree id, int type_dep)

needs to call cpp_interpret_string or something like that to get
converted into EBCDIC.


There's not that much mainline code that needs to be changed.
You can see for youself here:

http://rapidshare.com/files/277287822/gccnew-beta51.zip

The file is 250k compressed containing diffs, but most of them are
simply the generated files (which appear as new).  Here are the
real file changes:

diff -c gccnew/gcc/builtins.c:1.1.1.1 gccnew/gcc/builtins.c:1.3
diff -c gccnew/gcc/c-common.c:1.1.1.1 gccnew/gcc/c-common.c:1.2
diff -c gccnew/gcc/c-incpath.c:1.1.1.1 gccnew/gcc/c-incpath.c:1.3
diff -c gccnew/gcc/c-opts.c:1.1.1.1 gccnew/gcc/c-opts.c:1.2
diff -c gccnew/gcc/c-parse.c:1.1.1.1 gccnew/gcc/c-parse.c:1.5
diff -c gccnew/gcc/c-pch.c:1.1.1.1 gccnew/gcc/c-pch.c:1.3
diff -c gccnew/gcc/cppcharset.c:1.1.1.1 gccnew/gcc/cppcharset.c:1.6
diff -c gccnew/gcc/cpperror.c:1.1.1.1 gccnew/gcc/cpperror.c:1.2
diff -c gccnew/gcc/cppfiles.c:1.1.1.1 gccnew/gcc/cppfiles.c:1.7
diff -c gccnew/gcc/cpplib.h:1.1.1.1 gccnew/gcc/cpplib.h:1.2
diff -c gccnew/gcc/cppmacro.c:1.1.1.1 gccnew/gcc/cppmacro.c:1.2
diff -c gccnew/gcc/cppspec.c:1.1.1.1 gccnew/gcc/cppspec.c:1.3
diff -c gccnew/gcc/gcc.c:1.1.1.1 gccnew/gcc/gcc.c:1.6
diff -c gccnew/gcc/gcc.h:1.1.1.1 gccnew/gcc/gcc.h:1.2
diff -c gccnew/gcc/gcov-io.c:1.1.1.1 gccnew/gcc/gcov-io.c:1.2
diff -c gccnew/gcc/gcov-io.h:1.1.1.1 gccnew/gcc/gcov-io.h:1.2
diff -c gccnew/gcc/gcse.c:1.1.1.1 gccnew/gcc/gcse.c:1.3
diff -c gccnew/gcc/hwint.h:1.1.1.1 gccnew/gcc/hwint.h:1.2
diff -c gccnew/gcc/longlong.h:1.1.1.1 gccnew/gcc/longlong.h:1.2
diff -c gccnew/gcc/opts.c:1.1.1.1 gccnew/gcc/opts.c:1.2
diff -c gccnew/gcc/opts.h:1.1.1.1 gccnew/gcc/opts.h:1.3
diff -c gccnew/gcc/opts.sh:1.1.1.1 gccnew/gcc/opts.sh:1.1.1.2
diff -c gccnew/gcc/pretty-print.c:1.1.1.1 gccnew/gcc/pretty-print.c:1.2
diff -c gccnew/gcc/read-rtl.c:1.1.1.1 gccnew/gcc/read-rtl.c:1.2
diff -c gccnew/gcc/real.c:1.1.1.1 gccnew/gcc/real.c:1.3
diff -c gccnew/gcc/system.h:1.1.1.1 gccnew/gcc/system.h:1.2
diff -c gccnew/gcc/toplev.c:1.1.1.1 gccnew/gcc/toplev.c:1.3
diff -c gccnew/gcc/varasm.c:1.1.1.1 gccnew/gcc/varasm.c:1.2
diff -c gccnew/gcc/version.c:1.1.1.1 gccnew/gcc/version.c:1.2
diff -c gccnew/gcc/config/i370/i370-c.c:1.1.1.1 
gccnew/gcc/config/i370/i370-c.c:1.2
diff -c gccnew/gcc/config/i370/i370-protos.h:1.1.1.1 
gccnew/gcc/config/i370/i370-protos.h:1.2
diff -c gccnew/gcc/config/i370/i370.c:1.1.1.1 
gccnew/gcc/config/i370/i370.c:1.23
diff -c gccnew/gcc/config/i370/i370.h:1.1.1.1 
gccnew/gcc/config/i370/i370.h:1.15
diff -c gccnew/gcc/config/i370/i370.md:1.1.1.1 
gccnew/gcc/config/i370/i370.md:1.3
diff -c gccnew/gcc/config/i370/linux.h:1.1.1.1 
gccnew/gcc/config/i370/linux.h:1.1.1.2
diff -c gccnew/gcc/config/i370/oe.h:1.1.1.1 
gccnew/gcc/config/i370/oe.h:1.1.1.2
diff -c gccnew/include/fnmatch.h:1.1.1.1 gccnew/include/fnmatch.h:1.2
diff -c gccnew/include/safe-ctype.h:1.1.1.1 
gccnew/include/safe-ctype.h:1.1.1.2
diff -c gccnew/include/sort.h:1.1.1.1 gccnew/include/sort.h:1.2
diff -c gccnew/include/xregex2.h:1.1.1.1 gccnew/include/xregex2.h:1.2
diff -c gccnew/libiberty/argv.c:1.1.1.1 gccnew/libiberty/argv.c:1.4
diff -c gccnew/libiberty/concat.c:1.1.1.1 gccnew/libiberty/concat.c:1.2
diff -c gccnew/libiberty/cplus-dem.c:1.1.1.1 
gccnew/libiberty/cplus-dem.c:1.2
diff -c gccnew/libiberty/fdmatch.c:1.1.1.1 gccnew/libiberty/fdmatch.c:1.2
diff -c gccnew/libiberty/getpagesize.c:1.1.1.1 
gccnew/libiberty/getpagesize.c:1.2
diff -c gccnew/libiberty/getpwd.c:1.1.1.1 gccnew/libiberty/getpwd.c:1.2
diff -c gccnew/libiberty/getruntime.c:1.1.1.1 
gccnew/libiberty/getruntime.c:1.2
diff -c gccnew/libiberty/hashtab.c:1.1.1.1 gccnew/libiberty/hashtab.c:1.2
diff -c gccnew/libiberty/hex.c:1.1.1.1 gccnew/libiberty/hex.c:1.1.1.2
diff -c gccnew/libiberty/lrealpath.c:1.1.1.1 
gccnew/libiberty/lrealpath.c:1.2
diff -c gccnew/libiberty/make-temp-file.c:1.1.1.1 
gccnew/libiberty/make-temp-file.c:1.2
diff -c gccnew/libiberty/md5.c:1.1.1.1 gccnew/libiberty/md5.c:1.2
diff -c gccnew/libiberty/mkstemps.c:1.1.1.1 gccnew/libiberty/mkstemps.c:1.2
diff -c gccnew/libiberty/obstack.c:1.1.1.1 gccnew/libiberty/obstack.c:1.2
diff -c gccnew/libiberty/physmem.c:1.1.1.1 gccnew/libiberty/physmem.c:1.2
diff -c gccnew/libiberty/regex.c:1.1.1.1 gccnew/libiberty/regex.c:1.2
diff -c gccnew/libiberty/safe-ctype.c:1.1.1.1 
gccnew/libiberty/safe-ctype.c:1.4
diff -c gccnew/libiberty/vasprintf.c:1.1.1.1 
gccnew/libiberty/vasprintf.c:1.1.1.2
diff -c gccnew/libiberty/xmalloc.c:1.1.1.1 gccnew/libiberty/xmalloc.c:1.3
diff -c gccnew/libiberty/xmemdup.c:1.1.1.1 gccnew/libiberty/xmemdup.c:1.2
diff -c gccnew/libiberty/xstrdup.c:1.1.1.1 gccnew/libiberty/xstrdup.c:1.2

(most files are just a few lines of change though).

The most intrusive change was the #include processing which is
done differently on MVS.

Anyway, I'm planning on spending a bit more time consolidating this
build.  Not sure if the optimization problem can be solved, but even if
it can't, at least all the i370 code is now consolidated ready for the
push forward.  Hopefully these issues are more readily solved in the
latest codebase.

Hopefully also some of those other minor issues (like including
non-standard header files like sys/types) can also be remedied.  :-)

This has certainly taken a while.  The number of people who have
asked me why I don't use 3.4.6 as if it is trivial to do these things,
just change a couple of numbers surely.  :-)

Interesting how well the EBCDIC conversion held up too.  GCC 3.2.3
was a lot more intrusive to get working in that regard.

Let me know if you find anything that should have been done
differently too.  :-)

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-23  8:50 Paul Edwards
@ 2009-08-26 22:13 ` Henrik Sorensen
  0 siblings, 0 replies; 162+ messages in thread
From: Henrik Sorensen @ 2009-08-26 22:13 UTC (permalink / raw)
  To: gcc

On Sunday 23 August 2009 04.27:11 Paul Edwards wrote:
>
> Jujitsu are pleased to announce the release of the
> following software:
>
> GCC 3.2.3 MVS 7.5 - GCC C compiler for z/OS, MVS/380, MVS/370.
> GCC 3.2.3 CMS 7.5 - GCC C compiler for z/VM, VM/380, VM/370.
> PDPCLIB 2.00 - C (C90-compliant) runtime library for MVS
> Hercules/380 3.06 v6.0 - Used to run MVS/380. It now does

Hi Paul

Congrats !!

good to see you are making progress, and also getting feedback on the 
gcc-list.
> BFN.  Paul.
Henrik

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
@ 2009-08-23  8:50 Paul Edwards
  2009-08-26 22:13 ` Henrik Sorensen
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-08-23  8:50 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

>> > How does this work?  ASM_FORMAT_PRIVATE_NAME is not supposed
>> > to completely ignore the NAME argument, the function may well
>> > be called with the same LABELNO but different NAME strings,
>> > and this must not result in conflicting symbols ...
>> 
>> I have compiled the entire GCC and not come up with any duplicate
>> static function names, so I think the number is always unique.
> 
> Hmm, I see that in the 3.2.x code base this is indeed true.
> However, in later compilers ASM_FORMAT_PRIVATE_NAME is used
> for other purposes by the middle-end, not just static function
> or variable names.  You definitely can get number collisions
> in later compilers ...

Well I've compiled and linked all of 3.4.6 without getting name
clashes either.

>> > At this point, you may refer to "current_function_decl" to
>> > retrieve information about the function currently being output.
>> > In particular, you can retrieve the original source-level name
>> > associated with the routine via DECL_NAME (current_function_decl).
>> 
>> Thanks a lot!  I couldn't use that directly, but this:
> 
> Why not?  

It was missing the IDENTIFIER_POINTER so getting a compile
error.

>  printf ("%s", IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
> 
> should work fine ...

Yes, I've adopted that, thanks.

Anyway, I've finally packaged all those changes discussed on the
list, and also creditted you in the documentation for your assistance
in polishing the product off.  Details in announcement below.

BFN.  Paul.






Jujitsu are pleased to announce the release of the
following software:

GCC 3.2.3 MVS 7.5 - GCC C compiler for z/OS, MVS/380, MVS/370.
Delivered in xmit format.

GCC 3.2.3 CMS 7.5 - GCC C compiler for z/VM, VM/380, VM/370.
Delivered in vmarc format.

PDPCLIB 2.00 - C (C90-compliant) runtime library for MVS 
(all flavours), CMS (all flavours), Windows 32, MSDOS, 
OS/2, Linux (new with this release), PDOS. Provided in
source form only, but also delivered as part of GCCMVS
and GCCCMS.

Hercules/380 3.06 v6.0 - Used to run MVS/380. It now does
S/380 even if you specify S/370, so that Hercgui will
work. Now has native support for ftp-rdw files (ie files
that have been transferred from z/OS using ftp with
the RDW option), so that you can quickly get your files
restored to a V dataset. Windows executables provided.
Unix users need to compile from source.

You can find the products at:

http://gccmvs.sourceforge.net
http://pdos.sourceforge.net
http://mvs380.sourceforge.net

(respectively).

Initial documentation can be found in gccmvs.txt,
pdpclib.txt and README.S380 respectively.

Any comments/questions please post over at:

http://tech.groups.yahoo.com/group/hercules-os380

where our complaint department is in operation 24
hours a day, even during Ramadan - may Allah have
mercy on our souls.

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-21  2:37                                   ` Paul Edwards
@ 2009-08-21 16:46                                     ` Ulrich Weigand
  0 siblings, 0 replies; 162+ messages in thread
From: Ulrich Weigand @ 2009-08-21 16:46 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Paul Edwards wrote:

> >> /* Store in OUTPUT a string (made with alloca) containing an
> >>    assembler-name for a local static variable named NAME.
> >>    LABELNO is an integer which is different for each call.  */
> >>
> >> #ifdef TARGET_PDPMAC
> >> #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)  \
> >> { \
> >>   (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10); \
> >>   sprintf ((OUTPUT), "__%d", (LABELNO)); \
> >> }
> >
> > How does this work?  ASM_FORMAT_PRIVATE_NAME is not supposed
> > to completely ignore the NAME argument, the function may well
> > be called with the same LABELNO but different NAME strings,
> > and this must not result in conflicting symbols ...
> 
> I have compiled the entire GCC and not come up with any duplicate
> static function names, so I think the number is always unique.

Hmm, I see that in the 3.2.x code base this is indeed true.
However, in later compilers ASM_FORMAT_PRIVATE_NAME is used
for other purposes by the middle-end, not just static function
or variable names.  You definitely can get number collisions
in later compilers ...

> > At this point, you may refer to "current_function_decl" to
> > retrieve information about the function currently being output.
> > In particular, you can retrieve the original source-level name
> > associated with the routine via DECL_NAME (current_function_decl).
> 
> Thanks a lot!  I couldn't use that directly, but this:

Why not?  I'd have thought something like

  printf ("%s", IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));

should work fine ...


> c:\devel\gcc\gcc\config\i370>cvs diff -r 1.37 i370.c

B.t.w. if you use the -u or -c option to cvs diff, the diffs are
a lot more readable ...

> <            mvs_function_name);
> ---
> >            fname_as_string(0));

This is a bit problematic as fname_as_string is a function defined in
the C front-end.  If you were e.g. to build the Fortran compiler, your
back-end gets linked against the Fortran front-end instead of the C
front-end, and that function simply will not be there.  Generally,
the rule is that the back-end must not directly call front-end routines.

In any case, for C source code fname_as_string does pretty much
nothing else than what I suggested above ...

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-20 22:48                                 ` Ulrich Weigand
@ 2009-08-21  2:37                                   ` Paul Edwards
  2009-08-21 16:46                                     ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-08-21  2:37 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

>> > Hmm, it seems 3.2.x would *always* operate on a function-by-function
>> > basis.  The unit-at-a-time mode was only introduced with 3.4 (I don't
>> > recall if it was already present in 3.3).  I don't think there is any
>> > way in 3.2.3 to check whether there is a "main" function in the file
>> > before it is processed ...
>>
>> Does that mean I could take advantage of this behaviour?
>
> I don't think this would be a good idea.

You're right.  With your new change, I was able to see the difference,
and I can see that the static functions sometimes get numbers
assigned in a different order (I think first one called), and in that case,
with my method the name ends up wrong, but yours works.

* S-func dump_new_line prologue
@@3      PDPPRLG CINDEX=4,FRAME=104,BASER=12,ENTRY=NO
* Function dump_new_line code
* Function dump_new_line epilogue
         PDPEPIL
* Function dump_new_line literal pool
         DS    0F
         LTORG
* Function dump_new_line page table
         DS    0F
* S-func dump_maybe_newline prologue (!!!! your new technique)
@@2      PDPPRLG CINDEX=5,FRAME=104,BASER=12,ENTRY=NO
         B     FEN5
         L     10,=A(PGT5)
* Function dump_new_line code (!!!!!! wrong name)

>> /* Store in OUTPUT a string (made with alloca) containing an
>>    assembler-name for a local static variable named NAME.
>>    LABELNO is an integer which is different for each call.  */
>>
>> #ifdef TARGET_PDPMAC
>> #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)  \
>> { \
>>   (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10); \
>>   sprintf ((OUTPUT), "__%d", (LABELNO)); \
>> }
>
> How does this work?  ASM_FORMAT_PRIVATE_NAME is not supposed
> to completely ignore the NAME argument, the function may well
> be called with the same LABELNO but different NAME strings,
> and this must not result in conflicting symbols ...

I have compiled the entire GCC and not come up with any duplicate
static function names, so I think the number is always unique.

>> static void
>> i370_output_function_prologue (f, l)
>>      FILE *f;
>>      HOST_WIDE_INT l;
>> {
>> /* Don't print stack and args in PDPMAC as it makes the
>>    comment too long */
>> #ifdef TARGET_PDPMAC
>>   fprintf (f, "* %c-func %s prologue\n",
>>            mvs_need_entry ? 'X' : 'S',
>>            mvs_function_name);
>> #else
>
> At this point, you may refer to "current_function_decl" to
> retrieve information about the function currently being output.
> In particular, you can retrieve the original source-level name
> associated with the routine via DECL_NAME (current_function_decl).

Thanks a lot!  I couldn't use that directly, but this:

c:\devel\gcc\gcc\config\i370>cvs diff -r 1.37 i370.c
Index: i370.c
===================================================================
RCS file: c:\cvsroot/gcc/gcc/config/i370/i370.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -r1.37 -r1.38
1457c1457
<            mvs_function_name);
---
>            fname_as_string(0));
1599c1599
<   fprintf (f, "* Function %s code\n", mvs_function_name);
---
>   fprintf (f, "* Function %s code\n", fname_as_string(0));
1786c1786
<   fprintf (file, "* Function %s epilogue\n", mvs_function_name);
---
>   fprintf (file, "* Function %s epilogue\n", fname_as_string(0));
1817c1817
<   fprintf (file, "* Function %s literal pool\n", mvs_function_name);
---
>   fprintf (file, "* Function %s literal pool\n", fname_as_string(0));
1820c1820
<   fprintf (file, "* Function %s page table\n", mvs_function_name);
---
>   fprintf (file, "* Function %s page table\n", fname_as_string(0));

seems to do the trick!

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-20 12:49                               ` Paul Edwards
@ 2009-08-20 22:48                                 ` Ulrich Weigand
  2009-08-21  2:37                                   ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-08-20 22:48 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Paul Edwards wrote:

> > Hmm, it seems 3.2.x would *always* operate on a function-by-function
> > basis.  The unit-at-a-time mode was only introduced with 3.4 (I don't
> > recall if it was already present in 3.3).  I don't think there is any
> > way in 3.2.3 to check whether there is a "main" function in the file
> > before it is processed ...
> 
> Does that mean I could take advantage of this behaviour?

I don't think this would be a good idea.

> /* Store in OUTPUT a string (made with alloca) containing an
>    assembler-name for a local static variable named NAME.
>    LABELNO is an integer which is different for each call.  */
> 
> #ifdef TARGET_PDPMAC
> #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)  \
> { \
>   (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10); \
>   sprintf ((OUTPUT), "__%d", (LABELNO)); \
> }

How does this work?  ASM_FORMAT_PRIVATE_NAME is not supposed
to completely ignore the NAME argument, the function may well
be called with the same LABELNO but different NAME strings,
and this must not result in conflicting symbols ...

> static void
> i370_output_function_prologue (f, l)
>      FILE *f;
>      HOST_WIDE_INT l;
> {
> /* Don't print stack and args in PDPMAC as it makes the
>    comment too long */
> #ifdef TARGET_PDPMAC
>   fprintf (f, "* %c-func %s prologue\n",
>            mvs_need_entry ? 'X' : 'S',
>            mvs_function_name);
> #else

At this point, you may refer to "current_function_decl" to
retrieve information about the function currently being output.
In particular, you can retrieve the original source-level name
associated with the routine via DECL_NAME (current_function_decl).

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-12 16:35                             ` Ulrich Weigand
  2009-08-12 17:27                               ` Paul Edwards
  2009-08-19 12:07                               ` Paul Edwards
@ 2009-08-20 12:49                               ` Paul Edwards
  2009-08-20 22:48                                 ` Ulrich Weigand
  2 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-08-20 12:49 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

>> > That depends a bit on the compiler version and optimization level,
>> > but (in particular in the 3.x time frame) GCC may output assembler
>> > code on a function-by-function basis, without necessarily reading
>> > in the whole source file first.
>>
>> Ok, actually it doesn't matter if it doesn't work all the time.  I'll
>> always be compiling with -Os anyway, so it sounds like I'm in
>> with a chance of the whole file being read first?
>>
>> If so, where is my first opportunity, in 3.2.3, to see if there's a
>> "main" function in this file?
>
> Hmm, it seems 3.2.x would *always* operate on a function-by-function
> basis.  The unit-at-a-time mode was only introduced with 3.4 (I don't
> recall if it was already present in 3.3).  I don't think there is any
> way in 3.2.3 to check whether there is a "main" function in the file
> before it is processed ...

Does that mean I could take advantage of this behaviour?  Currently
I have this change:

/* Store in OUTPUT a string (made with alloca) containing an
   assembler-name for a local static variable named NAME.
   LABELNO is an integer which is different for each call.  */

#ifdef TARGET_PDPMAC
#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)  ^I^I\
{^I^I^I^I^I^I^I^I^I\
  (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10);^I^I^I\
  sprintf ((OUTPUT), "__%d", (LABELNO));^I^I^I^I\
}

to give the static functions unique names within the file.

However, it has the unfortunate side-effect that this code:

#if defined(TARGET_DIGNUS) || defined(TARGET_PDPMAC)
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)^I^I^I\
{^I^I^I^I^I^I^I^I^I\
  if (strlen (NAME) + 1 > mvs_function_name_length)^I^I^I\
    {^I^I^I^I^I^I^I^I^I\
      if (mvs_function_name)^I^I^I^I^I^I\
^Ifree (mvs_function_name);^I^I^I^I^I\
      mvs_function_name = 0;^I^I^I^I^I^I\
    }^I^I^I^I^I^I^I^I^I\
  if (!mvs_function_name)^I^I^I^I^I^I\
    {^I^I^I^I^I^I^I^I^I\
      mvs_function_name_length = strlen (NAME) * 2 + 1;^I^I^I\
      mvs_function_name = (char *) xmalloc (mvs_function_name_length);^I\
    }^I^I^I^I^I^I^I^I^I\
  strcpy (mvs_function_name, NAME);^I^I^I^I^I\
  mvs_need_to_globalize = 1;^I^I^I^I^I^I\
}
#endif

static void
i370_output_function_prologue (f, l)
     FILE *f;
     HOST_WIDE_INT l;
{
/* Don't print stack and args in PDPMAC as it makes the
   comment too long */
#ifdef TARGET_PDPMAC
  fprintf (f, "* %c-func %s prologue\n",
           mvs_need_entry ? 'X' : 'S',
           mvs_function_name);
#else

is producing this output:

* S-func __0 prologue
@@0      PDPPRLG CINDEX=1,FRAME=88,BASER=12,ENTRY=NO
         B     FEN1
         LTORG
FEN1     EQU   *
         DROP  12
         BALR  12,0
         USING *,12
PG1      EQU   *
         LR    11,1
         L     10,=A(PGT1)
* Function __0 code
* 46 world.c
         SLR   15,15
* Function __0 epilogue
         PDPEPIL
* Function __0 literal pool
         DS    0F
         LTORG
* Function __0 page table
         DS    0F
PGT1     EQU   *
         DC    A(PG1)

for this function:

static int aaa(void)
{
    return (0);
}

ie the "aaa" is being completely lost, being replaced by __0 everywhere.
Ideally the __0 would be aaa everywhere, with just the @@0 remaining
generated.

Indeed, I have just made this change:

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

C:\devel\gcc\gcc\config\i370>cvs diff
cvs diff: Diffing .
Index: i370.c
===================================================================
RCS file: c:\cvsroot/gcc/gcc/config/i370/i370.c,v
retrieving revision 1.34
diff -r1.34 i370.c
84a85,87
> /* original name of a static variable */
> char origmvsstatic[150];
>
1457c1460
<            mvs_function_name);
---
>            mvs_need_entry ? mvs_function_name : origmvsstatic);
1599c1602,1603
<   fprintf (f, "* Function %s code\n", mvs_function_name);
---
>   fprintf (f, "* Function %s code\n",
>            mvs_need_entry ? mvs_function_name : origmvsstatic);
1787c1791,1792
<   fprintf (file, "* Function %s epilogue\n", mvs_function_name);
---
>   fprintf (file, "* Function %s epilogue\n",
>            mvs_need_entry ? mvs_function_name : origmvsstatic);
1818c1823,1824
<   fprintf (file, "* Function %s literal pool\n", mvs_function_name);
---
>   fprintf (file, "* Function %s literal pool\n",
>            mvs_need_entry ? mvs_function_name : origmvsstatic);
1821c1827,1828
<   fprintf (file, "* Function %s page table\n", mvs_function_name);
---
>   fprintf (file, "* Function %s page table\n",
>            mvs_need_entry ? mvs_function_name : origmvsstatic);

C:\devel\gcc\gcc\config\i370>cvs diff -c i370.h
Index: i370.h
===================================================================
RCS file: c:\cvsroot/gcc/gcc/config/i370/i370.h,v
retrieving revision 1.35
diff -c -r1.35 i370.h
*** i370.h      18 Jul 2009 08:56:33 -0000      1.35
--- i370.h      20 Aug 2009 10:40:35 -0000
***************
*** 57,62 ****
--- 57,63 ----
  /* The source file module.  */

  extern char *mvs_module;
+ extern char origmvsstatic[];

  /* Compile using char instructions (mvc, nc, oc, xc).  On 4341 use this 
since
     these are more than twice as fast as load-op-store.
***************
*** 1832,1837 ****
--- 1833,1839 ----
  #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)                \
  {                                                                     \
    (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10);                  \
+   strcpy(origmvsstatic, NAME); \
    sprintf ((OUTPUT), "__%d", (LABELNO));                              \
  }
  #else

and it is working:

* S-func aaa prologue
@@0      PDPPRLG CINDEX=1,FRAME=88,BASER=12,ENTRY=NO
         B     FEN1
         LTORG
FEN1     EQU   *
         DROP  12
         BALR  12,0
         USING *,12
PG1      EQU   *
         LR    11,1
         L     10,=A(PGT1)
* Function aaa code
* 46 world.c
         SLR   15,15
* Function aaa epilogue
         PDPEPIL
* Function aaa literal pool
         DS    0F
         LTORG
* Function aaa page table
         DS    0F
PGT1     EQU   *
         DC    A(PG1)


But is that guaranteed?

Thanks.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-19 12:07                               ` Paul Edwards
@ 2009-08-19 12:27                                 ` Paolo Bonzini
  0 siblings, 0 replies; 162+ messages in thread
From: Paolo Bonzini @ 2009-08-19 12:27 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ulrich Weigand, gcc

> My experience is that fold-const.c requires 20 MB of memory (not
> including the size of the executable) to compile with -Os. That's
> the biggest.
>
> Is that typical/expected?

It doesn't seem too big.

> Because it just occurred to me that maybe the lack of a "normal"
> implementation of alloca() is causing memory to not be released,
> and it's taking more space than it needs to.

It may use a little more memory, but not much.

Paolo

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-12 16:35                             ` Ulrich Weigand
  2009-08-12 17:27                               ` Paul Edwards
@ 2009-08-19 12:07                               ` Paul Edwards
  2009-08-19 12:27                                 ` Paolo Bonzini
  2009-08-20 12:49                               ` Paul Edwards
  2 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-08-19 12:07 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

> Hmm, it seems 3.2.x would *always* operate on a function-by-function
> basis.  The unit-at-a-time mode was only introduced with 3.4 (I don't
> recall if it was already present in 3.3).  I don't think there is any
> way in 3.2.3 to check whether there is a "main" function in the file
> before it is processed ...

Ulrich, this comment got me thinking.  If global optimization is not
being done, then less of the source file would need to be in memory
at the same time.

How much memory do you think is required to process the largest
GCC 3.2.3 source file (ie when self-compiling)?

My experience is that fold-const.c requires 20 MB of memory (not
including the size of the executable) to compile with -Os.  That's
the biggest.

Is that typical/expected?

Because it just occurred to me that maybe the lack of a "normal"
implementation of alloca() is causing memory to not be released,
and it's taking more space than it needs to.

Thanks.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-12 19:46                                 ` Ulrich Weigand
@ 2009-08-12 20:31                                   ` Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-08-12 20:31 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Paolo Bonzini, gcc

> GCC relies on the libiberty "pex" family of routines, which are
> much more narrow in scope, and have in fact been ported to several
> non-UNIX systems, including even MS-DOS.  Providing a port of "pex"
> to MVS should be much easier that porting a full Unix "system" or
> "fork" feature.

Ok.  But I don't even have much of system() yet.

> B.t.w. if you cannot execute sub-tasks at all, how does the
> MVS GCC invoke the preprocessor (I think this was still a
> separate process in 3.2) and the core compiler (cc1) from
> the compiler driver?   Do you even have a separate compiler
> driver?

Sleight of hand.  :-)

> #ifdef SINGLE_EXECUTABLE
>   int ret_code = 0;
> #endif
2836a2853,2872
> #ifdef SINGLE_EXECUTABLE
>      {
>          int cnt = 0;
>
>          while (commands[i].argv[cnt] != NULL)
>          {
>              cnt++;
>          }
>          if (strcmp(string, "cpp0") == 0)
>          {
>              ret_code = cpp(cnt, commands[i].argv);
>              if (ret_code != 0) break;
>          }
>          else if (strcmp(string, "cc1") == 0)
>          {
>              ret_code = toplev_main(cnt, commands[i].argv);
>              if (ret_code != 0) break;
>          }
>       }
> #else
2850c2886
<
---
> #endif
2853a2890,2892
> #ifdef SINGLE_EXECUTABLE
>     return (ret_code);


BTW, here's what I am going with:

C:\devel\gcc\gcc>cvs diff -r release-3_2_3 debug.c
Index: debug.c
===================================================================
RCS file: c:\cvsroot/gcc/gcc/debug.c,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 debug.c
20a21,35
> #include "output.h"
> #include "flags.h"
>
> static void
> debug_source_line (line, text)
>      unsigned int line ATTRIBUTE_UNUSED;
>      const char *text ATTRIBUTE_UNUSED;
> {
>    if (flag_debug_asm)
>    {
>        app_enable();
>        fprintf(asm_out_file, "%s %d %s\n", ASM_COMMENT_START, line, text);
>        app_disable();
>    }
> }
34c49
<   debug_nothing_int_charstar, /* source_line */
---
>   debug_source_line,  /* source_line */


Thanks again for everyone's assistance.

Just need to find out who's emitting this warning:

C:\devel\gcc\gcc>gccmvs -DUSE_MEMMGR -Os -S -ansi -pedantic-errors -DHAVE_CONFIG
_H -DIN_GCC -DPUREISO -I ../../pdos/pdpclib -I . -I config/i370 -I 
../include -d
A world.c       -g
world.c:0: warning: `-g': unknown or unsupported -g option

and it'll be a wrap.  :-)

There will be some very happy people who are currently manually
putting in __asm__ lines to get insight.  :-)

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-12 17:27                               ` Paul Edwards
  2009-08-12 17:56                                 ` Paolo Bonzini
@ 2009-08-12 19:46                                 ` Ulrich Weigand
  2009-08-12 20:31                                   ` Paul Edwards
  1 sibling, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-08-12 19:46 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Paolo Bonzini, gcc

Paul Edwards wrote:

> > What is the problem with having GCC itself invoke the linker, just like
> > it does on other platforms?
> 
> 1. That requires extensions to the C90 standard.  The behaviour of
> system() is undefined, much less even the existence of fork() etc.
> 
> 2. The attempt to add functionality to system() in MVS has made
> leaps and bounds, but has not reached the stage of being able
> to detect if the SYSPRINT DCB is already open so it knows not
> to reopen it, and close it, stuffing up the caller.
> 
> 3. MVS compilers don't normally invoke the linker.  That's always
> a separate step.  GCCMVS is an MVS compiler also.  It would
> be normal to generate object code though.  But the compiler
> normally generates the object code, rather than invoking the
> assembler.  In any case, the facility to allocate temporary
> datasets for HLASM and deciding what space parameters
> should be used etc etc has not yet been determined, and is
> unwieldy regardless, and the functionality doesn't exist yet
> anyway, and may be years away still, if it even makes sense.

I cannot really comment on what would be desirable behaviour for
MVS ...   Just as an implementation note, while it is true that
the GCC compiler driver needs to be able to execute other processes
(preprocessor, compiler, assembler, linker) as sub-tasks, it does
not require the full POSIX system/fork/exec functionality to do so.
GCC relies on the libiberty "pex" family of routines, which are
much more narrow in scope, and have in fact been ported to several
non-UNIX systems, including even MS-DOS.  Providing a port of "pex"
to MVS should be much easier that porting a full Unix "system" or
"fork" feature.

B.t.w. if you cannot execute sub-tasks at all, how does the
MVS GCC invoke the preprocessor (I think this was still a
separate process in 3.2) and the core compiler (cc1) from
the compiler driver?   Do you even have a separate compiler
driver?

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-12 17:27                               ` Paul Edwards
@ 2009-08-12 17:56                                 ` Paolo Bonzini
  2009-08-12 19:46                                 ` Ulrich Weigand
  1 sibling, 0 replies; 162+ messages in thread
From: Paolo Bonzini @ 2009-08-12 17:56 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ulrich Weigand, gcc

> Ok, after a few false leads, I found something that produced a
> pleasing result. Fantastic I should say!
>
> With this mod:
>
> C:\devel\gcc\gcc>cvs diff debug.c
> Index: debug.c
> ===================================================================
> RCS file: c:\cvsroot/gcc/gcc/debug.c,v
> retrieving revision 1.1.1.1
> diff -r1.1.1.1 debug.c
> 20a21,31
>> #include "output.h"
>> #include "flags.h"
>>
>> void
>> fff (line, text)
>> unsigned int line ATTRIBUTE_UNUSED;
>> const char *text ATTRIBUTE_UNUSED;
>> {
>> if (flag_debug_asm)
>> fprintf(asm_out_file, "fff %d %s\n", line, text);
>> }

with s/fff/ASM_COMMENT_START/ and with a proper function name, this is 
actually an almost acceptable patch.  Only, you also have to do 
app_enable/app_disable (search for the other occurrences of 
flag_debug_asm in dwarf2out.c, they also explain why this is needed). 
These probably can be moved to common code in general.

> But let me guess - I'm not allowed to modify debug.c and have
> to decide whether MVS is an sdb, xcoff, dbx, dwarf 1/2, or vms?

No, that's fine.  -dA can actually be handled by common code.

Paolo

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-12 16:35                             ` Ulrich Weigand
@ 2009-08-12 17:27                               ` Paul Edwards
  2009-08-12 17:56                                 ` Paolo Bonzini
  2009-08-12 19:46                                 ` Ulrich Weigand
  2009-08-19 12:07                               ` Paul Edwards
  2009-08-20 12:49                               ` Paul Edwards
  2 siblings, 2 replies; 162+ messages in thread
From: Paul Edwards @ 2009-08-12 17:27 UTC (permalink / raw)
  To: Ulrich Weigand, Paolo Bonzini; +Cc: gcc

Thanks guys for your reply.

> As Paolo mentioned, the -dA flag is an option to the *compiler* that
> causes it to place additional information into its output stream
> (the assembler source code).

[from Paolo]

> Only DWARF-2 output supports it currently, but if you want to use it say 
> together with STABS, it is just a matter of modifying dbxout_source_line 
> and add a single statement like this:
> 
>       if (flag_debug_asm)
>         fprintf (asm_out_file, "\t%s %s:%d\n", ASM_COMMENT_START,
>                  filename, line);

Ok, after a few false leads, I found something that produced a
pleasing result.  Fantastic I should say!

With this mod:

C:\devel\gcc\gcc>cvs diff debug.c
Index: debug.c
===================================================================
RCS file: c:\cvsroot/gcc/gcc/debug.c,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 debug.c
20a21,31
> #include "output.h"
> #include "flags.h"
>
> void
> fff (line, text)
>      unsigned int line ATTRIBUTE_UNUSED;
>      const char *text ATTRIBUTE_UNUSED;
> {
>    if (flag_debug_asm)
>    fprintf(asm_out_file, "fff %d %s\n", line, text);
> }
34c45
<   debug_nothing_int_charstar, /* source_line */
---
>   fff /*debug_nothing_int_charstar*/, /* source_line */

and the -g -dA options

I was able to get exactly what I needed:

* Function main code
fff 32 world.c
         * basic block 0
         L     2,=V(X)
         L     2,0(2)
         LTR   2,2
         BE    L2
fff 34 world.c
         * basic block 1
         MVC   88(4,13),=A(LC0)
         B     L4
L2       EQU   *
         * basic block 2
fff 38 world.c
         MVC   88(4,13),=A(LC1)
L4       EQU   *
         * basic block 3
         LA    1,88(,13)
         L     15,=V(PRINTF)
         BALR  14,15
fff 41 world.c
         SLR   15,15
* Function main epilogue

But let me guess - I'm not allowed to modify debug.c and have
to decide whether MVS is an sdb, xcoff, dbx, dwarf 1/2, or vms?

>> > That depends a bit on the compiler version and optimization level,
>> > but (in particular in the 3.x time frame) GCC may output assembler
>> > code on a function-by-function basis, without necessarily reading
>> > in the whole source file first.
>> 
>> Ok, actually it doesn't matter if it doesn't work all the time.  I'll
>> always be compiling with -Os anyway, so it sounds like I'm in
>> with a chance of the whole file being read first?
>> 
>> If so, where is my first opportunity, in 3.2.3, to see if there's a
>> "main" function in this file?
> 
> Hmm, it seems 3.2.x would *always* operate on a function-by-function
> basis.  The unit-at-a-time mode was only introduced with 3.4 (I don't
> recall if it was already present in 3.3).  I don't think there is any
> way in 3.2.3 to check whether there is a "main" function in the file
> before it is processed ...

Ok, I'll wait until 3.4.6 is working before attempting to get
the entry point to 0 then.  :-)

>> > I don't know exactly how your port handles this on MVS, but usually
>> > GCC itself will invoke the linker, and will itself prepare an
>> > appropriate command linker for the linker.
>> 
>> GCC on MVS *only* outputs assembler.  ie you always have to
>> use the "-S" option.
>> 
>> By doing so, it turns GCC into a pure text-processing application,
>> which will thus work in any C90 environment.
> 
> Huh.  So the user will always have to invoke the linker manually, and
> pass all the correct options (libraries etc.)?

Correct.  Very normal MVS.  Where would we be without IEWL?

> What is the problem with having GCC itself invoke the linker, just like
> it does on other platforms?

1. That requires extensions to the C90 standard.  The behaviour of
system() is undefined, much less even the existence of fork() etc.

2. The attempt to add functionality to system() in MVS has made
leaps and bounds, but has not reached the stage of being able
to detect if the SYSPRINT DCB is already open so it knows not
to reopen it, and close it, stuffing up the caller.

3. MVS compilers don't normally invoke the linker.  That's always
a separate step.  GCCMVS is an MVS compiler also.  It would
be normal to generate object code though.  But the compiler
normally generates the object code, rather than invoking the
assembler.  In any case, the facility to allocate temporary
datasets for HLASM and deciding what space parameters
should be used etc etc has not yet been determined, and is
unwieldy regardless, and the functionality doesn't exist yet
anyway, and may be years away still, if it even makes sense.

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-12 11:52                           ` Paul Edwards
  2009-08-12 15:27                             ` Paolo Bonzini
@ 2009-08-12 16:35                             ` Ulrich Weigand
  2009-08-12 17:27                               ` Paul Edwards
                                                 ` (2 more replies)
  1 sibling, 3 replies; 162+ messages in thread
From: Ulrich Weigand @ 2009-08-12 16:35 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Paul Edwards wrote:
> > That depends a bit on the compiler version and optimization level,
> > but (in particular in the 3.x time frame) GCC may output assembler
> > code on a function-by-function basis, without necessarily reading
> > in the whole source file first.
> 
> Ok, actually it doesn't matter if it doesn't work all the time.  I'll
> always be compiling with -Os anyway, so it sounds like I'm in
> with a chance of the whole file being read first?
> 
> If so, where is my first opportunity, in 3.2.3, to see if there's a
> "main" function in this file?

Hmm, it seems 3.2.x would *always* operate on a function-by-function
basis.  The unit-at-a-time mode was only introduced with 3.4 (I don't
recall if it was already present in 3.3).  I don't think there is any
way in 3.2.3 to check whether there is a "main" function in the file
before it is processed ...

> > I don't know exactly how your port handles this on MVS, but usually
> > GCC itself will invoke the linker, and will itself prepare an
> > appropriate command linker for the linker.
> 
> GCC on MVS *only* outputs assembler.  ie you always have to
> use the "-S" option.
> 
> By doing so, it turns GCC into a pure text-processing application,
> which will thus work in any C90 environment.

Huh.  So the user will always have to invoke the linker manually, and
pass all the correct options (libraries etc.)?

What is the problem with having GCC itself invoke the linker, just like
it does on other platforms?

> > In current GCC, every insn contains "location" information pointing
> > back to source code line (and column) numbers.  However, in GCC 3.x
> > I think this wasn't yet present, but you had to rely on line number
> > notes interspersed with the insn stream.
> >
> > In any case, if you build with -g and use in addition the "debug
> > assembler output" flag -dA the assembler output should contain
> > human-readable comments containing line number information.
> 
> The GCC assembler is never invoked.  After getting the assembler
> output from the -S option, this is fed into IFOX00/IEV90/ASMA90.

As Paolo mentioned, the -dA flag is an option to the *compiler* that
causes it to place additional information into its output stream
(the assembler source code).


Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-12 11:52                           ` Paul Edwards
@ 2009-08-12 15:27                             ` Paolo Bonzini
  2009-08-12 16:35                             ` Ulrich Weigand
  1 sibling, 0 replies; 162+ messages in thread
From: Paolo Bonzini @ 2009-08-12 15:27 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ulrich Weigand, gcc


>> In any case, if you build with -g and use in addition the "debug
>> assembler output" flag -dA the assembler output should contain
>> human-readable comments containing line number information.
>
> Regardless, if line number notes are interspersed in the stream,
> maybe whenever I write out an assembler instruction I will have
> access to those notes and can print out a comment.

No, that might break when you upgrade later.  GCC already has support 
for annotating the assembly output with human-readable line number info. 
  That is option -dA as Ulrich pointed out.

Only DWARF-2 output supports it currently, but if you want to use it say 
together with STABS, it is just a matter of modifying dbxout_source_line 
and add a single statement like this:

       if (flag_debug_asm)
         fprintf (asm_out_file, "\t%s %s:%d\n", ASM_COMMENT_START,
                  filename, line);

Paolo

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-11 15:21                         ` Ulrich Weigand
@ 2009-08-12 11:52                           ` Paul Edwards
  2009-08-12 15:27                             ` Paolo Bonzini
  2009-08-12 16:35                             ` Ulrich Weigand
  0 siblings, 2 replies; 162+ messages in thread
From: Paul Edwards @ 2009-08-12 11:52 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

> That depends a bit on the compiler version and optimization level,
> but (in particular in the 3.x time frame) GCC may output assembler
> code on a function-by-function basis, without necessarily reading
> in the whole source file first.

Ok, actually it doesn't matter if it doesn't work all the time.  I'll
always be compiling with -Os anyway, so it sounds like I'm in
with a chance of the whole file being read first?

If so, where is my first opportunity, in 3.2.3, to see if there's a
"main" function in this file?

>> > As crt0.o can be (and usually is) completely
>> > written in assembler, you can arrange for everything to be in the 
>> > sequence
>> > that is required.  (On the linker command line, crt0.o would be placed
>> > first, so if the entry point is the first thing in crt0.o it will then
>> > also be the first thing in the executable.)
>>
>> Yes, I can do that, but that means I need to have a linker command
>> line!  The way the MVS linker works, I can link my main program,
>> (which obviously doesn't have crt0 in it), and, thanks to the "END"
>> statement, I can specify an entry point.  This means no complaint
>> from the linker about a default (and wrong) entry point, and no
>> need for any linker statements.  It all automatically resolves.
>
> I don't know exactly how your port handles this on MVS, but usually
> GCC itself will invoke the linker, and will itself prepare an
> appropriate command linker for the linker.

GCC on MVS *only* outputs assembler.  ie you always have to
use the "-S" option.

By doing so, it turns GCC into a pure text-processing application,
which will thus work in any C90 environment.

> In current GCC, every insn contains "location" information pointing
> back to source code line (and column) numbers.  However, in GCC 3.x
> I think this wasn't yet present, but you had to rely on line number
> notes interspersed with the insn stream.
>
> In any case, if you build with -g and use in addition the "debug
> assembler output" flag -dA the assembler output should contain
> human-readable comments containing line number information.

The GCC assembler is never invoked.  After getting the assembler
output from the -S option, this is fed into IFOX00/IEV90/ASMA90.

Regardless, if line number notes are interspersed in the stream,
maybe whenever I write out an assembler instruction I will have
access to those notes and can print out a comment.

Thanks.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-11  0:34                       ` Paul Edwards
@ 2009-08-11 15:21                         ` Ulrich Weigand
  2009-08-12 11:52                           ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-08-11 15:21 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

Paul Edwards wrote:

> I expected that the assembler generation wouldn't happen until
> after the optimization was completed, and thus, by then, I
> would know whether this was a main.

That depends a bit on the compiler version and optimization level,
but (in particular in the 3.x time frame) GCC may output assembler
code on a function-by-function basis, without necessarily reading
in the whole source file first.

As I said, it seems the best way would be to not have care at all
whether or not any particular source file contains a main routine,
but instead do all entry-point processing in the crt0 startup file.

> > As crt0.o can be (and usually is) completely
> > written in assembler, you can arrange for everything to be in the sequence
> > that is required.  (On the linker command line, crt0.o would be placed
> > first, so if the entry point is the first thing in crt0.o it will then
> > also be the first thing in the executable.)
> 
> Yes, I can do that, but that means I need to have a linker command
> line!  The way the MVS linker works, I can link my main program,
> (which obviously doesn't have crt0 in it), and, thanks to the "END"
> statement, I can specify an entry point.  This means no complaint
> from the linker about a default (and wrong) entry point, and no
> need for any linker statements.  It all automatically resolves.

I don't know exactly how your port handles this on MVS, but usually
GCC itself will invoke the linker, and will itself prepare an
appropriate command linker for the linker.  As part of this command
line, things like crt files will be specified.  You should set the
STARTFILE_SPEC macro in your back-end to do that ...

> > There doesn't seem to be an easy way to do this from the
> > compiler.  At the time compiler output is generated, the
> > original source code text isn't even kept any more; you'd
> > have to go back and re-read the original source files using
> > the line-number debug data, just as the assembler would ...
> 
> Ok, well - I would be content with just the source line number
> appearing in the output assembler.  Is this information
> available as each assembler line is output?

In current GCC, every insn contains "location" information pointing
back to source code line (and column) numbers.  However, in GCC 3.x
I think this wasn't yet present, but you had to rely on line number
notes interspersed with the insn stream.

In any case, if you build with -g and use in addition the "debug
assembler output" flag -dA the assembler output should contain
human-readable comments containing line number information.


Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-10 21:25                     ` Ulrich Weigand
@ 2009-08-11  0:34                       ` Paul Edwards
  2009-08-11 15:21                         ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-08-11  0:34 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Daniel Jacobowitz, gcc

> This probably is not gimp (the graphics editor) but gmp (the
> multi-precision integer operation library) and mpfr (same for
> floating-point).  To build any recent GCC you'll indeed need
> these two libraries.  Fortunately, they're already available
> on s390(x) on Linux, and shouldn't really contain anything
> that is OS-specific, so porting those to MVS should hopefully
> be straightforward ...

Ok, thanks Ulrich.

>> Until then, back at GCC 3.2.3, I have a "need" to make the entry
>> point 0 in my MVS modules.
>
>> Currently I generate this:
> [snip]
>> for a main program.  In order to get the entry point to 0, I need to move
>> that
>> @@MAIN function to the top of the file.
>
> I don't think there is a reliable way to change the sequence of
> functions / objects in the output file.

Sorry, my question may not have been clear.

When I see main(), I generate the normal MAIN code, and I don't
care where this goes.

However, given that I now know that a main() exists somewhere
in this source file, I need to change the ASM_FILE_START
output.

I expected that the assembler generation wouldn't happen until
after the optimization was completed, and thus, by then, I
would know whether this was a main.

> However, it seems to me it shouldn't really be necessary to treat "main"
> special.  Usually, the "entry point" isn't really "main", but rather some
> function in crt0.o, which then in turn *calls* main after all startup
> processing has been done.

That is roughly the case, yes.

> As crt0.o can be (and usually is) completely
> written in assembler, you can arrange for everything to be in the sequence
> that is required.  (On the linker command line, crt0.o would be placed
> first, so if the entry point is the first thing in crt0.o it will then
> also be the first thing in the executable.)

Yes, I can do that, but that means I need to have a linker command
line!  The way the MVS linker works, I can link my main program,
(which obviously doesn't have crt0 in it), and, thanks to the "END"
statement, I can specify an entry point.  This means no complaint
from the linker about a default (and wrong) entry point, and no
need for any linker statements.  It all automatically resolves.

It all works really great!

Except - I would ideally like to have an entry point of 0, instead
of the typical "58" or whatever my static variables happen to be.
(my main is normally at the top).

>> And I have another question - where is the code for __asm__?
>>
>> Currently that is generating garbage for me:
>>
>> unsigned int bytes = 258;
>>
>> __asm__("? :");
>>
>> int main(void)
>>
>> BYTES    EQU   *
>>          DC    F'258'
>>          o@z
>> * Program text area
>>
>> when done in cross-compiler mode, and need to find out where
>> the literal is being translated (or more likely - failing to be
>> translated in the first instance).  Any idea where that is?
>
> Hmm, this seems to be the bug fixed by Eric Christopher in 2004:
> http://gcc.gnu.org/ml/gcc-cvs/2004-02/msg01425.html

Thanks again!  That didn't seem to make it into 3.4.6.  I was able
to apply most of his stuff to 3.4.6, and I will see how far that gets
me, before trying to find it in 3.2.3.

Or maybe I'll skip it, since the problem doesn't occur on a pure
EBCDIC system.  :-)

>> And final thing - the interest in the __asm__ comes from the hope
>> that in the generated 370 assembler, it would be possible to have
>> the C code interspersed to whatever extent possible.  The plan was
>> to basically somehow get every line of C code, e.g. "int main(void)"
>> above, and automatically generate an:
>> __asm__("int main void)");
>
> As you note, this doesn't seem workable as the result wouldn't
> be syntactically valid ...
>
>> which gives a syntax error.  Any idea how to get the mixed
>> C/assembler when I'm running with the "-S" option and don't
>> have the luxury of calling the normal "as" which would
>> normally handle that?
>
> There doesn't seem to be an easy way to do this from the
> compiler.  At the time compiler output is generated, the
> original source code text isn't even kept any more; you'd
> have to go back and re-read the original source files using
> the line-number debug data, just as the assembler would ...

Ok, well - I would be content with just the source line number
appearing in the output assembler.  Is this information
available as each assembler line is output?

Thanks.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-08-08 12:04                   ` Paul Edwards
@ 2009-08-10 21:25                     ` Ulrich Weigand
  2009-08-11  0:34                       ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-08-10 21:25 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Daniel Jacobowitz, gcc

Paul Edwards wrote:

> GCC 4 complained (on my Linux system) that I didn't have
> various things (gimp etc) installed, which means I would need
> that other software to be ported too, which is not a project
> I want to work on at the moment.  However, at least it means
> that i have successfully merged all the GCCMVS changes
> to 3.2.3 in with the (last available) 3.4.6 development, which
> was a precursor to any GCC 4 port anyway.  I'll see over time
> how GCC 3.4.6 pans out.

This probably is not gimp (the graphics editor) but gmp (the
multi-precision integer operation library) and mpfr (same for
floating-point).  To build any recent GCC you'll indeed need
these two libraries.  Fortunately, they're already available
on s390(x) on Linux, and shouldn't really contain anything
that is OS-specific, so porting those to MVS should hopefully
be straightforward ...

> Until then, back at GCC 3.2.3, I have a "need" to make the entry
> point 0 in my MVS modules.

> Currently I generate this:
[snip]
> for a main program.  In order to get the entry point to 0, I need to move 
> that
> @@MAIN function to the top of the file.

I don't think there is a reliable way to change the sequence of
functions / objects in the output file.

However, it seems to me it shouldn't really be necessary to treat "main"
special.  Usually, the "entry point" isn't really "main", but rather some
function in crt0.o, which then in turn *calls* main after all startup
processing has been done.  As crt0.o can be (and usually is) completely
written in assembler, you can arrange for everything to be in the sequence
that is required.  (On the linker command line, crt0.o would be placed
first, so if the entry point is the first thing in crt0.o it will then
also be the first thing in the executable.)

> And I have another question - where is the code for __asm__?
> 
> Currently that is generating garbage for me:
> 
> unsigned int bytes = 258;
> 
> __asm__("? :");
> 
> int main(void)
> 
> BYTES    EQU   *
>          DC    F'258'
>          o@z
> * Program text area
> 
> when done in cross-compiler mode, and need to find out where
> the literal is being translated (or more likely - failing to be
> translated in the first instance).  Any idea where that is?

Hmm, this seems to be the bug fixed by Eric Christopher in 2004:
http://gcc.gnu.org/ml/gcc-cvs/2004-02/msg01425.html


> And final thing - the interest in the __asm__ comes from the hope
> that in the generated 370 assembler, it would be possible to have
> the C code interspersed to whatever extent possible.  The plan was
> to basically somehow get every line of C code, e.g. "int main(void)"
> above, and automatically generate an:
> __asm__("int main void)");

As you note, this doesn't seem workable as the result wouldn't
be syntactically valid ...

> which gives a syntax error.  Any idea how to get the mixed
> C/assembler when I'm running with the "-S" option and don't
> have the luxury of calling the normal "as" which would
> normally handle that?

There doesn't seem to be an easy way to do this from the
compiler.  At the time compiler output is generated, the
original source code text isn't even kept any more; you'd
have to go back and re-read the original source files using
the line-number debug data, just as the assembler would ...

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-07-20 14:27                 ` Ulrich Weigand
@ 2009-08-08 12:04                   ` Paul Edwards
  2009-08-10 21:25                     ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-08-08 12:04 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Daniel Jacobowitz, gcc

>> I then found out that even with old versions of the machine definition,
>> I can have the warning removed by simply not defining CONST_INT
>> in the PREDICATE_CODES, even though it is allowed when the
>> function is called.  ie it seems to have no effect on the code
>> generation, but succeeds in eliminating the warning, and without
>> needing to define an extra constraint for non-constant situations.
>
> Actually PREDICATE_CODES does have to match the predicate definitions.
> If it does not, you can run into subtle bugs, as the code in genrecog.c
> that generates the finite state automaton matching an RTX pattern
> against the .md insn definitions *does* make use of PREDICATE_CODES;
> for example, it will assume that two predicates with disjoint sets
> of PREDICATE_CODES can never both match the same RTX.
>
> This may or may not lead to visible differences when compiling simple
> test cases, but I'd expect effects to be visible in more complex
> scenarios.

Thanks Ulrich.  When I went back to this I found that I had
misdiagnosed - actually the r_or_s didn't allow constants after
all.  It was only const_rtx that it allowed.  So the machine definition
no longer has any warnings and all looks good.

That's with 3.2.3.

With 3.4.6 I have now managed to get an MVS load module,
unoptimized (I already know that optimized doesn't work), to
compile a hello world program successfully, although it abends
at the end of that and I haven't investigated that yet.

So the theoretical EBCDIC support is less theoretical now.
I "needed" to change the parameter search algorithm to stop
being binary search though.

GCC 4 complained (on my Linux system) that I didn't have
various things (gimp etc) installed, which means I would need
that other software to be ported too, which is not a project
I want to work on at the moment.  However, at least it means
that i have successfully merged all the GCCMVS changes
to 3.2.3 in with the (last available) 3.4.6 development, which
was a precursor to any GCC 4 port anyway.  I'll see over time
how GCC 3.4.6 pans out.

Until then, back at GCC 3.2.3, I have a "need" to make the entry
point 0 in my MVS modules.

Currently I generate this:

         COPY  PDPTOP
         CSECT
* X-var bytes
         ENTRY BYTES
* Program data area
         DS    0F
BYTES    EQU   *
         DC    F'258'
* Program text area
LC0      EQU   *
         DC    C'bytes is %d'
         DC    X'15'
         DC    X'0'
         DS    0F
         DC    C'GCCMVS!!'
         EXTRN @@CRT0
         ENTRY @@MAIN
@@MAIN   DS    0H
         USING *,15
         L     15,=V(@@CRT0)
         BR    15
         DROP  15
         LTORG
* X-func main prologue
MAIN     PDPPRLG CINDEX=0,FRAME=96,BASER=12,ENTRY=YES
...
* Function main page table
         DS    0F
PGT0     EQU   *
         DC    A(PG0)
         END   @@MAIN

for a main program.  In order to get the entry point to 0, I need to move 
that
@@MAIN function to the top of the file.

But I only really want that function if this is a main program.  I have 
found
somewhere where I can add some code to see if the function "main" is
being compiled, and set a global variable.

Unfortunately, the place that happens (c-decl) isn't called until after all
the data has been written out!

I looked at the documentation:

http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gccint/Assembler-Format.html#Assembler%20Format

but maybe I'm looking in the wrong place.  Any ideas?

And I have another question - where is the code for __asm__?

Currently that is generating garbage for me:

unsigned int bytes = 258;

__asm__("? :");

int main(void)

BYTES    EQU   *
         DC    F'258'
         o@z
* Program text area

when done in cross-compiler mode, and need to find out where
the literal is being translated (or more likely - failing to be
translated in the first instance).  Any idea where that is?

And final thing - the interest in the __asm__ comes from the hope
that in the generated 370 assembler, it would be possible to have
the C code interspersed to whatever extent possible.  The plan was
to basically somehow get every line of C code, e.g. "int main(void)"
above, and automatically generate an:
__asm__("int main void)");

although I'm not sure what to do about this:

int main(void)
__asm__("? :");
{

which gives a syntax error.  Any idea how to get the mixed
C/assembler when I'm running with the "-S" option and don't
have the luxury of calling the normal "as" which would
normally handle that?

Thanks.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-07-18 11:28               ` Paul Edwards
@ 2009-07-20 14:27                 ` Ulrich Weigand
  2009-08-08 12:04                   ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-07-20 14:27 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Daniel Jacobowitz, gcc

Paul Edwards wrote:

> I then found out that even with old versions of the machine definition,
> I can have the warning removed by simply not defining CONST_INT
> in the PREDICATE_CODES, even though it is allowed when the
> function is called.  ie it seems to have no effect on the code
> generation, but succeeds in eliminating the warning, and without
> needing to define an extra constraint for non-constant situations.

Actually PREDICATE_CODES does have to match the predicate definitions.
If it does not, you can run into subtle bugs, as the code in genrecog.c
that generates the finite state automaton matching an RTX pattern
against the .md insn definitions *does* make use of PREDICATE_CODES;
for example, it will assume that two predicates with disjoint sets
of PREDICATE_CODES can never both match the same RTX.

This may or may not lead to visible differences when compiling simple
test cases, but I'd expect effects to be visible in more complex
scenarios.

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-19 12:28             ` Ulrich Weigand
@ 2009-07-18 11:28               ` Paul Edwards
  2009-07-20 14:27                 ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-07-18 11:28 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Daniel Jacobowitz, gcc

>> But sometimes r_or_s_operand is being used as a source, in
>> which case, the constant is fine.  But when it is used as a
>> destination, it is not fine.
>> 
>> What is the *simplest* way of changing the setup so that the
>> code generation remains the same, but the warning is eliminated?
> 
> Well, I guess you need to do two things:
> 
> - Define the PREDICATE_CODES macro -- if this is undefined,
>  genrecog will consider *any* target-defined predicate as
>  potentially allowing non-lvalues, because it cannot know
>  better.
> 
> - Actually define two distinct predicates, one that allows
>  non-lvalue and one that doesn't, and use them as appropriate.
> 
>> But wondering if there's something simpler and neater.
> 
> Well, you could also simply ignore the warning -- nothing
> is going to go wrong because of it.

Thanks for pointing me in the right direction Ulrich.  Unfortunately
just short of what would have been best for this situation.

I defined the PREDICATE_CODES macro and put in the things
I thought were appropriate:

C:\devel\gcc\gcc\config\i370>cvs diff -r 1.33 -r 1.34 i370.h
Index: i370.h
===================================================================
RCS file: c:\cvsroot/gcc/gcc/config/i370/i370.h,v
retrieving revision 1.33
retrieving revision 1.34
diff -r1.33 -r1.34
200a201,204
> #define PREDICATE_CODES \
>   {"r_or_s_operand", { REG, SUBREG, MEM, CONST_INT }}, \
>   {"s_operand", { MEM, CONST_INT }},
>

It had no effect on anything that I could see, but that was to be expected.

I then had a closer look at the machine definitions and realised that some
of them that were defined as r_or_s_operand could instead be
nonimmediate_operand, which started eliminating warnings.

So I proceeded down this track, eliminating things here and there, or
in some cases, opening things up to be more general, with the hope
that I would eventually have things so that the only r_or_s_operand
I needed were ones that didn't require literals, so that I could (at the
end), make this change:

C:\devel\gcc\gcc\config\i370>cvs diff -r 1.34 -r 1.35 i370.h
Index: i370.h
===================================================================
RCS file: c:\cvsroot/gcc/gcc/config/i370/i370.h,v
retrieving revision 1.34
retrieving revision 1.35
diff -r1.34 -r1.35
202,203c202,203
<   {"r_or_s_operand", { REG, SUBREG, MEM, CONST_INT }}, \
<   {"s_operand", { MEM, CONST_INT }},
---
>   {"r_or_s_operand", { REG, SUBREG, MEM }}, \
>   {"s_operand", { MEM }},

and something similar in i370.c, to make constants invalid, so that I
could eliminate the warnings.

It took a month to do that, because I kept on being hit by presumed
bugs, which started generating bad or unexpected code when I made
a seemingly innocuous change.  To make matters worse, sometimes
I could only find out whether the code was good or not by running it on
MVS, via the emulator, which means a 2 hour wait for a result.

However, I did get it down to just a handful of warnings, which would
be eliminated now that I could drop the CONST_INT.  And I would
check the generated code to see what I had missed when I took
off the CONST_INT.

Anyway, I took off the CONST_INT, and the warnings all disappeared,
and the code didn't change!

I then found out that even with old versions of the machine definition,
I can have the warning removed by simply not defining CONST_INT
in the PREDICATE_CODES, even though it is allowed when the
function is called.  ie it seems to have no effect on the code
generation, but succeeds in eliminating the warning, and without
needing to define an extra constraint for non-constant situations.

So I've revamped the machine definition unnecessarily.  Well, I
did make things defined more consistently, and did make code
generation improvements, but they're not major, and I wouldn't
have done any of it if I knew I could have just defined a predicate
that wasn't really going to be used.

Oh well.  At the end of the day, the warning has gone, the code
is better and the machine definition is more correct.  :-)

I've also got 3.4.6 working to some extent.  I have managed to
build an single GCC executable, and if I call it with no parameters,
it prints its usage (as designed).

However, if I try to pass parameters it doesn't recognize them.
It could be something to do with not having run the appropriate
stuff through bison (or flex) on an EBCDIC platform.

Normally I use this to get around that problem:

C:\devel\gccnew\gcc>cvs diff -r release-3_4_6 c-parse.c
Index: c-parse.c
===================================================================
RCS file: c:\cvsroot/gccnew/gcc/c-parse.c,v
retrieving revision 1.1.1.1
retrieving revision 1.4
diff -r1.1.1.1 -r1.4
497a498,503
> #if defined(__MVS__) || defined(__CMS__)
> #define YYTRANSLATE(YYX)                      \
>   ((unsigned int) (YYX) <= YYMAXUTOK ? \
>   ((unsigned int) (YYX) < 256 ? yytranslate[_sch_ebcasc[YYX]] \
>   : yytranslate[YYX]) : YYUNDEFTOK)
> #else
499a506
> #endif

But perhaps the new gengtyp lex and yacc, although not used in the
actual GCC executable, are causing a problem by being run on the
ASCII machine.

Next step is to see if I can run the generated files all on MVS so
that that is eliminated from the equation.  Since I actually do have
an EBCDIC flex and bison available now (thanks to 3.2.3).

I also had problems with 3.4.6 when I switched on optimization.
A couple of internal errors popped up, which will presumably
trace back to the i370 code, but be outside my knowledge to
fix.

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-19  0:06           ` Paul Edwards
@ 2009-06-19 12:28             ` Ulrich Weigand
  2009-07-18 11:28               ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-06-19 12:28 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Daniel Jacobowitz, gcc

Paul Edwards wrote:

> But sometimes r_or_s_operand is being used as a source, in
> which case, the constant is fine.  But when it is used as a
> destination, it is not fine.
> 
> What is the *simplest* way of changing the setup so that the
> code generation remains the same, but the warning is eliminated?

Well, I guess you need to do two things:

- Define the PREDICATE_CODES macro -- if this is undefined,
  genrecog will consider *any* target-defined predicate as
  potentially allowing non-lvalues, because it cannot know
  better.

- Actually define two distinct predicates, one that allows
  non-lvalue and one that doesn't, and use them as appropriate.

> But wondering if there's something simpler and neater.

Well, you could also simply ignore the warning -- nothing
is going to go wrong because of it.

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-15 17:46         ` Ulrich Weigand
@ 2009-06-19  0:06           ` Paul Edwards
  2009-06-19 12:28             ` Ulrich Weigand
  0 siblings, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-06-19  0:06 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Daniel Jacobowitz, gcc

Hi guys.

The last class of warning I have from the machine definition is this:

./config/i370/i370.md:784: warning: destination operand 0 allows non-lvalue

which is because I have used r_or_s_operand like this:

;
; movdi instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:DI 0 "r_or_s_operand" "=dm,dS")
        (match_operand:DI 1 "r_or_s_operand" "dm*fF,i"))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))

and I believe what is happening is that r_or_s_operand allows
a constant.

But sometimes r_or_s_operand is being used as a source, in
which case, the constant is fine.  But when it is used as a
destination, it is not fine.

What is the *simplest* way of changing the setup so that the
code generation remains the same, but the warning is eliminated?

Note that this is 3.2.3 and I'm not wanting to restructure the
whole thing to be the same as s390.md.  I am thinking I can
define something like r_or_s_lval_operand which would be
the same as r_or_s_operand except not allow constants.

But wondering if there's something simpler and neater.

Thanks.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-06 15:00       ` Paul Edwards
@ 2009-06-15 17:46         ` Ulrich Weigand
  2009-06-19  0:06           ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Ulrich Weigand @ 2009-06-15 17:46 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Daniel Jacobowitz, gcc

Paul Edwards wrote:

> One of the things that I experienced when porting 3.2.3 to MVS
> was that GCC was sensitive to the exact floating point representation.
> 
> Register selection was different depending on those slight differences.
> 
> Below is what documentation I have for it.  Dave Edwards, who
> wrote another S/370 emulator, was the one who discovered that.
> 
> Does anyone know if that was changed somewhere along the line?
> 
> BFN.  Paul.
> 
> 
> 
> 17. The assembler code generated by gccmvs when run on the
> PC is slightly different (even when the same parameters
> are used for code generation) from that when run on the
> mainframe, if -O2 is used instead of -Os. But functionally
> equivalent. This non-deterministic nature of the compiler
> is disconcerting. It seems to not always allocate registers
> consistently. This has been traced to floating point code
> in predict.c and local-alloc.c which is sensitive to the
> very small changes in floating point representation. This
> should be changed to include deltas when comparing floating
> point values. Here's an example of what's happening:

I agree that GCC output should not depend on details of the host
floating point representation.  (Ideally, the output of GCC built
as a cross-compiler should not depend on the host architecture
at all.)

However, it is hard to say whether such observations made on a
GCC 3.2 code base have any relevance to the current code -- for
example, local-alloc.c does not even exist any more, we now have
a completely new register allocator.

I'd recommend you go ahead with a port to current mainline and
verify whether you still see problems along those lines; if so,
it would be appropriate to open a bug report against GCC.

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 15:49     ` Daniel Jacobowitz
  2009-06-05 15:57       ` Paul Edwards
@ 2009-06-06 15:00       ` Paul Edwards
  2009-06-15 17:46         ` Ulrich Weigand
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-06-06 15:00 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Ulrich Weigand, gcc

> Why are you migrating to 3.4.6 now, instead of to a current version?
> If you want to include this in mainline some day, then eventually it
> has to be caught up - and 3.4.6 is older than it may appear from the
> release date, since it branched off of mainline five years ago.  A lot
> has changed since then.

A question about those changes.

One of the things that I experienced when porting 3.2.3 to MVS
was that GCC was sensitive to the exact floating point representation.

Register selection was different depending on those slight differences.

Below is what documentation I have for it.  Dave Edwards, who
wrote another S/370 emulator, was the one who discovered that.

Does anyone know if that was changed somewhere along the line?

BFN.  Paul.



17. The assembler code generated by gccmvs when run on the
PC is slightly different (even when the same parameters
are used for code generation) from that when run on the
mainframe, if -O2 is used instead of -Os. But functionally
equivalent. This non-deterministic nature of the compiler
is disconcerting. It seems to not always allocate registers
consistently. This has been traced to floating point code
in predict.c and local-alloc.c which is sensitive to the
very small changes in floating point representation. This
should be changed to include deltas when comparing floating
point values. Here's an example of what's happening:

*** c-lex.s Mon Jan 14 20:48:35 2008
--- temp.dat Mon Jan 14 21:14:04 2008
***************
*** 1328,1335 ****
           SLR   15,15
           STC   15,0(3,4)
           SLR   6,6
-          LR    9,6
           LR    8,6
           L     2,192(13)
           CLR   2,5
           BNL   L303
--- 1328,1335 ----
           SLR   15,15
           STC   15,0(3,4)
           SLR   6,6
           LR    8,6
+          LR    9,6
           L     2,192(13)
           CLR   2,5
           BNL   L303

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 20:20         ` Joseph S. Myers
@ 2009-06-05 20:45           ` Paul Edwards
  0 siblings, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-06-05 20:45 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Daniel Jacobowitz, Ulrich Weigand, gcc

>> 3.4.6 made some revamps to the i370 port (compared to 3.2.3), and I
>> need to make sure those changes have been digested, and no code
>> has been lost, so that I can pick up the final i370 port and move it.
>
> But there were probably also (mechanical) changes to the port between when
> 3.4 branched (long before 3.4.6 was released) and when the port was
> removed from trunk - that's why the last revision before it was removed
> from trunk may be a better starting point.

Ok, I understand now.  So there were some changes, that would
nominally have made it to GCC 4, but were in fact never officially
released, because it was dropped before release.

So, prior to starting a GCC 4 port (ie the changes may not be
desirable for the GCC 3.4.6 port I am currently working on), I
need to get GCC 3.4 as a base, GCC 3.4.6 as one derivative,
and SVN 77215, then do a 3-way diff/merge to obtain the
"nominal GCC 4" changes.

Or perhaps not.

I don't want the 3.4.6 changes at that point, since anything of
value will be covered by SVN 77215.  So I need to use GCC 3.4.6
as the base, my personal version as one derivative, SVN 77215
as the second derivative, and feed that into the 3-way diff.

Ok, I'll do that when I'm in a position to do the GCC 4 port
attempt.  I'm still months away from completing the GCC 3.4.6
port, and there are other MVS-related projects that are more
important than what is basically a transparent 3.2.3 to 4
upgrade that will only start being useful when it enables something
else to happen (such as the PL/1 front-end).

So I'll be working on that stable 3.4.6 before taking my chances
with what is basically an axed beta (SVN 77215), with still no
indication of whether even a perfectly working self-compiling
i370 target will be accepted unless the testsuite is working first
(and even if it was working, that still may not be enough - as
the next hoop may be an s390 merge - and a requirement to
switch from 370 to 390).

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 15:57       ` Paul Edwards
@ 2009-06-05 20:20         ` Joseph S. Myers
  2009-06-05 20:45           ` Paul Edwards
  0 siblings, 1 reply; 162+ messages in thread
From: Joseph S. Myers @ 2009-06-05 20:20 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Daniel Jacobowitz, Ulrich Weigand, gcc

On Sat, 6 Jun 2009, Paul Edwards wrote:

> 3.4.6 made some revamps to the i370 port (compared to 3.2.3), and I
> need to make sure those changes have been digested, and no code
> has been lost, so that I can pick up the final i370 port and move it.

But there were probably also (mechanical) changes to the port between when 
3.4 branched (long before 3.4.6 was released) and when the port was 
removed from trunk - that's why the last revision before it was removed 
from trunk may be a better starting point.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 15:49     ` Daniel Jacobowitz
@ 2009-06-05 15:57       ` Paul Edwards
  2009-06-05 20:20         ` Joseph S. Myers
  2009-06-06 15:00       ` Paul Edwards
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-06-05 15:57 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Ulrich Weigand, gcc

>>> 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.
>>
>> It looks that way from what I've seen of 3.4.6 so far.  However, I
>> won't know for sure until it's on the host and self-generating.
> 
> Why are you migrating to 3.4.6 now, instead of to a current version?
> If you want to include this in mainline some day, then eventually it
> has to be caught up - and 3.4.6 is older than it may appear from the
> release date, since it branched off of mainline five years ago.  A lot
> has changed since then.

3.4.6 made some revamps to the i370 port (compared to 3.2.3), and I
need to make sure those changes have been digested, and no code
has been lost, so that I can pick up the final i370 port and move it.

It's less daunting to get 3.4.6 working first.  At least there the target
actually exists and does obstensibly appear to work!

Migrating from 3.4.6 to 4.x is not going to be made any bigger a deal.
It's not like someone else is making incompatible changes to the
i370 port at the same time as me!

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 15:44   ` Joseph S. Myers
@ 2009-06-05 15:52     ` Paul Edwards
  2009-09-08 15:55     ` Paul Edwards
  1 sibling, 0 replies; 162+ messages in thread
From: Paul Edwards @ 2009-06-05 15:52 UTC (permalink / raw)
  To: Joseph S. Myers, Ulrich Weigand; +Cc: gcc

>> 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
>
> I think the EBCDIC support is largely theoretical and not tested on any
> actual EBCDIC host (or target).  cpplib knows the character set name
> UTF-EBCDIC, but whenever it does anything internally that involves the
> encoding of its internal character set it uses UTF-8 rules (which is not
> something valid to do with UTF-EBCDIC).

From the hercules-os380 files section, here's the relevant change
to 3.4.6 to stop it being theoretical:

Index: gccnew/gcc/cppcharset.c
diff -c gccnew/gcc/cppcharset.c:1.1.1.1 gccnew/gcc/cppcharset.c:1.6
*** gccnew/gcc/cppcharset.c:1.1.1.1 Wed Apr 15 16:26:16 2009
--- gccnew/gcc/cppcharset.c Wed May 13 11:07:08 2009
***************
*** 23,28 ****
--- 23,30 ----
  #include "cpplib.h"
  #include "cpphash.h"
  #include "cppucnid.h"
+ #include "coretypes.h"
+ #include "tm.h"

  /* Character set handling for C-family languages.

***************
*** 529,534 ****
--- 531,561 ----
    return conversion_loop (one_utf32_to_utf8, cd, from, flen, to);
  }

+ #ifdef MAP_OUTCHAR
+ /* convert ASCII to EBCDIC */
+ static bool
+ convert_asc_ebc (iconv_t cd ATTRIBUTE_UNUSED,
+          const uchar *from, size_t flen, struct _cpp_strbuf *to)
+ {
+   size_t x;
+   int c;
+
+   if (to->len + flen > to->asize)
+     {
+       to->asize = to->len + flen;
+       to->text = xrealloc (to->text, to->asize);
+     }
+   for (x = 0; x < flen; x++)
+     {
+       c = from[x];
+       c = MAP_OUTCHAR(c);
+       to->text[to->len + x] = c;
+     }
+   to->len += flen;
+   return true;
+ }
+ #endif
+
  /* Identity conversion, used when we have no alternative.  */
  static bool
  convert_no_conversion (iconv_t cd ATTRIBUTE_UNUSED,
***************
*** 606,611 ****
--- 633,641 ----
    { "UTF-32BE/UTF-8", convert_utf32_utf8, (iconv_t)1 },
    { "UTF-16LE/UTF-8", convert_utf16_utf8, (iconv_t)0 },
    { "UTF-16BE/UTF-8", convert_utf16_utf8, (iconv_t)1 },
+ #if defined(TARGET_EBCDIC)
+   { "UTF-8/UTF-EBCDIC", convert_asc_ebc, (iconv_t)0 },
+ #endif
  };

  /* Subroutine of cpp_init_iconv: initialize and return a
***************
*** 683,688 ****
--- 713,722 ----

    bool be = CPP_OPTION (pfile, bytes_big_endian);

+ #if defined(TARGET_EBCDIC)
+   ncset = "UTF-EBCDIC";
+   wcset = "UTF-EBCDIC";
+ #else
    if (CPP_OPTION (pfile, wchar_precision) >= 32)
      default_wcset = be ? "UTF-32BE" : "UTF-32LE";
    else if (CPP_OPTION (pfile, wchar_precision) >= 16)
***************
*** 696,701 ****
--- 730,736 ----
      ncset = SOURCE_CHARSET;
    if (!wcset)
      wcset = default_wcset;
+ #endif

    pfile->narrow_cset_desc = init_iconv_desc (pfile, ncset, 
SOURCE_CHARSET);
    pfile->wide_cset_desc = init_iconv_desc (pfile, wcset, SOURCE_CHARSET);


The generated code appears to be fine from visual inspection.

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 15:39   ` Paul Edwards
@ 2009-06-05 15:49     ` Daniel Jacobowitz
  2009-06-05 15:57       ` Paul Edwards
  2009-06-06 15:00       ` Paul Edwards
  0 siblings, 2 replies; 162+ messages in thread
From: Daniel Jacobowitz @ 2009-06-05 15:49 UTC (permalink / raw)
  To: Paul Edwards; +Cc: Ulrich Weigand, gcc

On Sat, Jun 06, 2009 at 01:39:07AM +1000, Paul Edwards wrote:
>> 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.
>
> It looks that way from what I've seen of 3.4.6 so far.  However, I
> won't know for sure until it's on the host and self-generating.

Why are you migrating to 3.4.6 now, instead of to a current version?
If you want to include this in mainline some day, then eventually it
has to be caught up - and 3.4.6 is older than it may appear from the
release date, since it branched off of mainline five years ago.  A lot
has changed since then.

-- 
Daniel Jacobowitz
CodeSourcery

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 15:24       ` Paul Edwards
@ 2009-06-05 15:47         ` Joseph S. Myers
  0 siblings, 0 replies; 162+ messages in thread
From: Joseph S. Myers @ 2009-06-05 15:47 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

On Sat, 6 Jun 2009, Paul Edwards wrote:

> > 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).
> 
> I have a large backlog of work to do with the i370 port already, starting
> with getting gcc 3.4.6 running natively.  Isn't that a more productive
> thing to do?  Even after 3.4.6 is done, so that every scrap of code is
> available, then there's version 4 to do!

It's up to you what priorities you assign to different things involved in 
getting this on mainline, but we use test results postings as evidence of 
what sort of state each port is in, where a particular test failure is 
appearing and whether each port is being used, so there may be reluctance 
to accept a port that will not have test results posted regularly for 
mainline.  (This is much less of a problem for OS ports than for CPU 
ports; if one OS for a given CPU has results routinely posted, it doesn't 
matter so much if other OSes don't, though having results for different 
OSes is still useful.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 15:21 ` Ulrich Weigand
  2009-06-05 15:39   ` Paul Edwards
@ 2009-06-05 15:44   ` Joseph S. Myers
  2009-06-05 15:52     ` Paul Edwards
  2009-09-08 15:55     ` Paul Edwards
  1 sibling, 2 replies; 162+ messages in thread
From: Joseph S. Myers @ 2009-06-05 15:44 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Paul Edwards, gcc

On Fri, 5 Jun 2009, Ulrich Weigand wrote:

> 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

I think the EBCDIC support is largely theoretical and not tested on any 
actual EBCDIC host (or target).  cpplib knows the character set name 
UTF-EBCDIC, but whenever it does anything internally that involves the 
encoding of its internal character set it uses UTF-8 rules (which is not 
something valid to do with UTF-EBCDIC).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 15:21 ` Ulrich Weigand
@ 2009-06-05 15:39   ` Paul Edwards
  2009-06-05 15:49     ` Daniel Jacobowitz
  2009-06-05 15:44   ` Joseph S. Myers
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-06-05 15:39 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

Wow, what a lot of responses.  Last time I tried making
contact, I didn't get a single response!

>> 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?

Yep.

> I assume those changes are not (primarily) in the back-end, but
> throughout GCC common code?

Yes.  Or rather, they would be, if it weren't for sleight-of-hand to
minimize that.  I dummied up all the Posix calls to point back to
C90 functions.

Please take a look at the actual changes to GCC.  There's not
a lot:

Here's the exact file:

https://sourceforge.net/project/downloading.php?group_id=195127&filename=gccmvs-3_2_3-7_0.zip&a=50206324

Most of the size is generated code from the md, or other new files,
and not changes to GCC proper.

However, in fact, GCC is turned on its head.  It's a single executable.
C90 doesn't guarantee, and the host doesn't support, the ability to do
a fork() and exec().

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

Great.

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

It looks that way from what I've seen of 3.4.6 so far.  However, I
won't know for sure until it's on the host and self-generating.

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

Well, I would like to see that - I don't know why there are all
those calls to open() instead of fopen() etc in the first place,
but I don't see that happening.

> 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 minimum a S/390 G2 with the branch relative
> instructions ... but those have been around for nearly 15 years).

The last free MVS was MVS 3.8j which runs on the S/370 architecture.
If you want to write MVS software, for free, your only option is to
pick that up.  It doesn't run on S/390 hardware.

However.  :-)

That's where MVS/380 comes in.

http://mvs380.sourceforge.net

So yes, we can sort of cope with S/390 instructions.  It's just not as
widely supported as the proper S/370 (emulated) machine.  Or rather,
I think we can.  It's into unchartered territory what restrictions
S/380 actually has in its current form.  It's known that it's enough to
run 31-bit GCC using 20 MB of memory though.  Which again, is a
damn good start.

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 15:03     ` Joseph S. Myers
@ 2009-06-05 15:24       ` Paul Edwards
  2009-06-05 15:47         ` Joseph S. Myers
  2017-03-31 10:34       ` Paul Edwards
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-06-05 15:24 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc

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

It doesn't build executables either.

Only the "-S" option is used.

With that restriction, GCC merely reads a bunch of text files and
writes a text file, and thus is amenable to being a pure C90
application.  That's how it manages to work at all.

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

It so happens that MVS/380 has the ability to be run in batch, and
extracting the exit code won't be a problem either.

Note however that I normally do all my GCC work in Windows,
and the batch running etc is done with batch files.

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

I have a large backlog of work to do with the i370 port already, starting
with getting gcc 3.4.6 running natively.  Isn't that a more productive
thing to do?  Even after 3.4.6 is done, so that every scrap of code is
available, then there's version 4 to do!

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 12:45 Paul Edwards
  2009-06-05 14:33 ` Joseph S. Myers
@ 2009-06-05 15:21 ` Ulrich Weigand
  2009-06-05 15:39   ` Paul Edwards
  2009-06-05 15:44   ` Joseph S. Myers
  1 sibling, 2 replies; 162+ messages in thread
From: Ulrich Weigand @ 2009-06-05 15:21 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

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 minimum a S/390 G2 with the branch relative
instructions ... but those have been around for nearly 15 years).

Bye,
Ulrich

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

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 14:57   ` Paul Edwards
@ 2009-06-05 15:03     ` Joseph S. Myers
  2009-06-05 15:24       ` Paul Edwards
  2017-03-31 10:34       ` Paul Edwards
  0 siblings, 2 replies; 162+ messages in thread
From: Joseph S. Myers @ 2009-06-05 15:03 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

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
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 14:33 ` Joseph S. Myers
@ 2009-06-05 14:57   ` Paul Edwards
  2009-06-05 15:03     ` Joseph S. Myers
  2009-09-12 12:41   ` Paul Edwards
  1 sibling, 1 reply; 162+ messages in thread
From: Paul Edwards @ 2009-06-05 14:57 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc

>> We were both maintaining it, and continue to maintain it,
>> because MVS doesn't have any alternate free C compiler
>> available.
>
> To merge back into FSF GCC, the people who have made changes that would be
> merged back will need to have copyright assignments on file at the FSF
> (and disclaimers from any relevant employers).  I don't have a current
> copy of the assignments list (my very old copy does show assignments from
> David G. Pitts with an employer disclaimer dating from 1993).

There's only 3 people who have made changes.  Dave Pitts, Linas
Vepstas and myself.  Dave you already have apparently.  Linas's
code is largely already merged - just his last set of changes didn't
get put in.  That leaves me.  I work as a contractor and I'd probably
be sacked if I tried to either bring in or attempt to maintain gcc.
All my work was done at home.

>> So, my question is - what is required to get the i370 port reinstated
>> into the GCC mainline?
>
> The basic requirements for a resurrected port are the same as for a new
> port; it needs to be assigned to the FSF, to pass the normal technical
> review, and the SC needs to approve someone as a maintainer of the port
> (there may be a bottleneck with the last stage, since there are currently
> at least three new ports pending approval).  It is a very good idea if you
> can run the testsuite for the port and will be posting results to
> gcc-testresults regularly.

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.

It's difficult enough just to get GCC to know to open dd:include(xxx)
for an include of "xxx.h" and dd:sysincl(xxx) for an include of <xxx.h>.
That logic was revamped in gcc 3.4.6 so I haven't put it in yet.  It'll
probably be months before I do that, because I can't test it until it
gets up onto the mainframe.  And once again, in preparation for that,
I need to make it a pure C90 application.  So that is where I spend
my effort.

Note that the i370 port used to be in GCC even though it was riddled
with bugs.  It took literally years to get rid of them.  I would have
thought that GCC recompiling itself was a damn good start for
inclusion, irrespective of any test suites (assuming those test
suites are even C90 code - as they would need to be to work).

> I would encourage going through all the changes made to the i370 port on
> GCC mainline, after 3.1/3.2 branched and before the port was removed, to
> see what should be merged into your version for mainline; ultimately it
> would be up to you how you get it updated for all the mechanical changes
> on mainline since 3.2, but those changes (see command above to get logs)
> may be a useful guide to how to do some of the updates.

I have already merged the changes made from 3.2.3 to 3.4.6 into my
code, and have a diff against 3.4.6 available already.  ie, that covers
all known code changes.  But it only works as a cross-compiler at the
moment.  It's probably a few months away from being native.

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

* Re: i370 port
  2009-06-05 12:45 Paul Edwards
@ 2009-06-05 14:33 ` Joseph S. Myers
  2009-06-05 14:57   ` Paul Edwards
  2009-09-12 12:41   ` Paul Edwards
  2009-06-05 15:21 ` Ulrich Weigand
  1 sibling, 2 replies; 162+ messages in thread
From: Joseph S. Myers @ 2009-06-05 14:33 UTC (permalink / raw)
  To: Paul Edwards; +Cc: gcc

On Fri, 5 Jun 2009, Paul Edwards wrote:

> It was dropped from GCC 4 when there was supposedly no
> maintainer available.  Actually, Dave Pitts and myself were
> both maintaining it at that time, but we were both still working
> on an old version of it (3.2). So gcc 3.4.6, circa 2004, was the
> last time it was included in the normal GCC distribution.

(For reference, the port was removed in SVN revision 77216; before then it 
had had various largely mechanical changes as part of changes to multiple 
back ends or target-independent code, with r69086 as the last vaguely 
i370-only change but no changes appearing to come from someone 
specifically working and testing on i370 for some years before then.  "svn 
log svn://gcc.gnu.org/svn/gcc/trunk/gcc/config/i370@77215" shows the 
history.)

> We were both maintaining it, and continue to maintain it,
> because MVS doesn't have any alternate free C compiler
> available.

To merge back into FSF GCC, the people who have made changes that would be 
merged back will need to have copyright assignments on file at the FSF 
(and disclaimers from any relevant employers).  I don't have a current 
copy of the assignments list (my very old copy does show assignments from 
David G. Pitts with an employer disclaimer dating from 1993).

> So, my question is - what is required to get the i370 port reinstated
> into the GCC mainline?

The basic requirements for a resurrected port are the same as for a new 
port; it needs to be assigned to the FSF, to pass the normal technical 
review, and the SC needs to approve someone as a maintainer of the port 
(there may be a bottleneck with the last stage, since there are currently 
at least three new ports pending approval).  It is a very good idea if you 
can run the testsuite for the port and will be posting results to 
gcc-testresults regularly.

I would encourage going through all the changes made to the i370 port on 
GCC mainline, after 3.1/3.2 branched and before the port was removed, to 
see what should be merged into your version for mainline; ultimately it 
would be up to you how you get it updated for all the mechanical changes 
on mainline since 3.2, but those changes (see command above to get logs) 
may be a useful guide to how to do some of the updates.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 162+ messages in thread

* i370 port
@ 2009-06-05 12:45 Paul Edwards
  2009-06-05 14:33 ` Joseph S. Myers
  2009-06-05 15:21 ` Ulrich Weigand
  0 siblings, 2 replies; 162+ messages in thread
From: Paul Edwards @ 2009-06-05 12:45 UTC (permalink / raw)
  To: gcc

Hello GCC maintainers.

There used to be an i370 target for GCC.  It was written in 1989,
and put into GCC 2.5 in 1993.

It has always been semi-working, but never good enough to
actually use.

It was dropped from GCC 4 when there was supposedly no
maintainer available.  Actually, Dave Pitts and myself were
both maintaining it at that time, but we were both still working
on an old version of it (3.2). So gcc 3.4.6, circa 2004, was the
last time it was included in the normal GCC distribution.

We were both maintaining it, and continue to maintain it,
because MVS doesn't have any alternate free C compiler
available.

As of yesterday, after years of work, an i370 version was 
released that is now fully working.  The code generator has 
no known bugs that would stop it from being C90-compliant,
and GCC can fully regenerate itself, with full optimization.  

You can see it here:

http://gccmvs.sourceforge.net

It's based on GCC 3.2.3.

There is also a free i370 emulator (Hercules) and a free i370-based 
operating system (MVS/380) that enables the compiler to be fully 
tested and fully regenerate itself on its native environment.  Not
only that, but there is an effort underway to allow this free
environment to be made available on the internet so that Unix
users can do an MVS build (takes around 4 hours if done properly
- ie 3 stage, full optimization, on an emulated machine), from the 
safety of their Unix box.

Both of those products are also under active development by a
community of mainframe enthusiasts.

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.

There is a lot of other activity (e.g. availability of REXX, PL/1, Cobol)
that rests on the C compiler being available.

So, my question is - what is required to get the i370 port reinstated
into the GCC mainline?

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.

So, here's hoping that the i370 port can end up where it was originally
intended to end up, and that all the effort that was spent in the GCC
mainline to get rid of the ASCII assumptions can now be put to good
use.

BFN.  Paul.

^ permalink raw reply	[flat|nested] 162+ messages in thread

end of thread, other threads:[~2021-03-15 13:55 UTC | newest]

Thread overview: 162+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-09 22:33 i370 port Paul Edwards
2009-09-14 15:42 ` Ulrich Weigand
2009-09-15 12:59   ` Paul Edwards
2009-09-15 13:51     ` Ulrich Weigand
2009-09-17 13:00       ` Paul Edwards
2009-09-17 17:55         ` Ulrich Weigand
2009-09-18  0:35           ` Paul Edwards
2009-09-18 12:06             ` Ulrich Weigand
2009-09-18 12:23               ` Paul Edwards
2009-09-18 13:27                 ` Ulrich Weigand
2009-09-18 13:42                   ` Paul Edwards
2009-09-18 16:08                     ` Ulrich Weigand
2009-09-19 12:57                       ` Paul Edwards
2009-09-25 10:19                       ` Paul Edwards
2009-09-25 15:20                         ` Ulrich Weigand
2009-09-30 17:24                           ` i370 port - constructing compile script Paul Edwards
2009-09-30 17:36                             ` Richard Henderson
2009-09-30 21:40                               ` Paul Edwards
     [not found]                                 ` <mcrpr98x9w8.fsf@dhcp-172-17-9-151.mtv.corp.google.com>
2009-10-01  0:16                                   ` Joseph S. Myers
2009-10-01 14:00                                     ` Paul Edwards
2009-10-02 12:41                                     ` Paul Edwards
2009-10-02 16:00                                       ` Ian Lance Taylor
2009-10-02 22:53                                         ` Paul Edwards
2009-10-04  4:11                                           ` Ian Lance Taylor
2009-10-04  5:14                                             ` Paul Edwards
2009-10-04  6:04                                               ` Ian Lance Taylor
2009-10-04  6:50                                                 ` Paul Edwards
2009-10-04 15:38                                                   ` Ulrich Weigand
2009-10-04 22:51                                                     ` Paul Edwards
2009-10-05 13:15                                                       ` Ulrich Weigand
2009-10-06  9:32                                                         ` Paul Edwards
2009-10-06 13:15                                                           ` Ulrich Weigand
2009-10-06 13:38                                                             ` Paul Edwards
2009-10-06 14:01                                                               ` Ulrich Weigand
2009-10-14 14:33                                                                 ` Paul Edwards
2009-10-19 14:19                                                         ` Paul Edwards
2009-10-19 17:37                                                           ` Ulrich Weigand
2009-10-20 14:18                                                             ` Paul Edwards
2009-10-20 15:30                                                               ` Ulrich Weigand
2009-11-12 14:03                                                             ` Paul Edwards
2009-11-12 20:06                                                               ` Ralf Wildenhues
2009-11-12 20:56                                                                 ` Paul Edwards
2009-11-13 11:43                                                                 ` Paul Edwards
2009-11-13 12:01                                                                   ` Ulrich Weigand
2009-11-13 12:18                                                                     ` Paul Edwards
2009-11-13 12:57                                                                       ` Ulrich Weigand
2009-11-14  8:52                                                                         ` Paul Edwards
2009-11-14 10:49                                                                           ` Ralf Wildenhues
2009-11-14 11:28                                                                             ` Paul Edwards
2009-11-22  0:51                                                                               ` Paolo Bonzini
2009-11-18 10:51                                                                             ` Paul Edwards
2009-11-19 14:27                                                                               ` Ulrich Weigand
2009-11-21 13:40                                                                                 ` Paul Edwards
2009-11-23 10:33                                                                                 ` i370 port - 3.4.6 to 4.4 upgrade attempt Paul Edwards
2009-11-23 10:43                                                                                   ` Andreas Schwab
2009-11-23 15:43                                                                                   ` Paolo Bonzini
2009-11-24 14:05                                                                                   ` Ulrich Weigand
2009-11-24 14:36                                                                                     ` Paul Edwards
2009-11-28 15:14                                                                                     ` i370 port - music/sp - possible generic gcc problem Paul Edwards
2009-11-28 16:03                                                                                       ` Richard Guenther
2009-11-28 16:35                                                                                         ` Paul Edwards
2009-11-28 17:03                                                                                           ` Richard Guenther
2009-11-28 23:44                                                                                             ` Paul Edwards
2010-05-26 14:40                                                                                         ` i370 port - status Paul Edwards
2021-03-14  5:55                                                                                         ` negative indexes Paul Edwards
2021-03-14  8:05                                                                                           ` Richard Biener
2021-03-14  8:12                                                                                             ` Paul Edwards
2021-03-14 13:37                                                                                               ` Richard Biener
     [not found]                                                                                                 ` <755065BE2A0B4B508DD3A262B2A83801@DESKTOP0OKG1VA>
2021-03-15  9:22                                                                                                   ` Richard Biener
2021-03-15 13:55                                                                                                     ` extended segments on 80386 Paul Edwards
2009-12-07 12:05                                                                                     ` i370 port - 3.4.6 to 4.4 upgrade attempt Paul Edwards
2009-12-08 13:55                                                                                       ` Ulrich Weigand
2009-11-15 14:22                                                                         ` i370 port - finally building Paul Edwards
2009-11-22  0:46                                                                   ` i370 port - constructing compile script Paolo Bonzini
2009-11-13 12:08                                                               ` Ulrich Weigand
2009-10-05 13:17                                                   ` Michael Matz
2009-10-05 13:38                                                     ` Paul Edwards
2009-10-05 13:46                                                       ` Michael Matz
2009-10-01 14:28                             ` Paul Brook
2009-10-01 16:00                               ` Paul Edwards
2009-10-01 18:36                                 ` Ian Lance Taylor
2009-10-01 23:43                                   ` Paul Edwards
2009-10-01 21:10                                 ` David Edelsohn
2009-10-01 22:22                                   ` Toon Moene
2009-10-02  0:19                                     ` Paul Edwards
2009-11-04  5:21                       ` i370 port Paul Edwards
2009-11-04 16:47                         ` Ulrich Weigand
2009-11-09 14:55                           ` Paul Edwards
2009-11-09 15:57                             ` Ian Lance Taylor
2009-11-09 23:10                               ` Paul Edwards
2009-11-10 14:58                               ` Paul Edwards
2009-11-10 15:36                                 ` Ian Lance Taylor
2009-11-10 15:51                               ` Paul Edwards
2009-11-10 15:56                                 ` Ian Lance Taylor
2009-12-02 22:03                                   ` Paul Edwards
2011-08-13  8:34                           ` Paul Edwards
2011-08-15 14:32                             ` Ulrich Weigand
2011-08-15 15:26                               ` Paul Edwards
2011-08-15 17:23                                 ` Ulrich Weigand
2011-08-16 11:20                                   ` Paul Edwards
2011-08-16 13:26                                     ` Ulrich Weigand
2011-08-18 12:15                                       ` Paul Edwards
2011-08-18 13:14                                         ` Ulrich Weigand
2011-08-18 14:18                                           ` Paul Edwards
  -- strict thread matches above, loose matches on Subject: below --
2014-02-13  4:23 Paul Edwards
2012-04-07  5:45 Paul Edwards
2012-04-08 17:43 ` Ulrich Weigand
2014-02-11 17:01   ` Paul Edwards
2012-04-06 12:49 Paul Edwards
2012-04-06 18:16 ` Ulrich Weigand
2012-04-07  4:12   ` Paul Edwards
2012-04-06  5:51 Paul Edwards
2011-08-20 12:15 Paul Edwards
2011-08-22 12:23 ` Ulrich Weigand
2012-04-05 13:32   ` Paul Edwards
2012-04-06 18:13     ` Ulrich Weigand
2011-08-20 10:09 Paul Edwards
2011-08-20  7:44 Paul Edwards
2009-09-22 12:31 Paul Edwards
2009-08-23  8:50 Paul Edwards
2009-08-26 22:13 ` Henrik Sorensen
2009-06-05 12:45 Paul Edwards
2009-06-05 14:33 ` Joseph S. Myers
2009-06-05 14:57   ` Paul Edwards
2009-06-05 15:03     ` Joseph S. Myers
2009-06-05 15:24       ` Paul Edwards
2009-06-05 15:47         ` Joseph S. Myers
2017-03-31 10:34       ` Paul Edwards
2009-09-12 12:41   ` Paul Edwards
2009-06-05 15:21 ` Ulrich Weigand
2009-06-05 15:39   ` Paul Edwards
2009-06-05 15:49     ` Daniel Jacobowitz
2009-06-05 15:57       ` Paul Edwards
2009-06-05 20:20         ` Joseph S. Myers
2009-06-05 20:45           ` Paul Edwards
2009-06-06 15:00       ` Paul Edwards
2009-06-15 17:46         ` Ulrich Weigand
2009-06-19  0:06           ` Paul Edwards
2009-06-19 12:28             ` Ulrich Weigand
2009-07-18 11:28               ` Paul Edwards
2009-07-20 14:27                 ` Ulrich Weigand
2009-08-08 12:04                   ` Paul Edwards
2009-08-10 21:25                     ` Ulrich Weigand
2009-08-11  0:34                       ` Paul Edwards
2009-08-11 15:21                         ` Ulrich Weigand
2009-08-12 11:52                           ` Paul Edwards
2009-08-12 15:27                             ` Paolo Bonzini
2009-08-12 16:35                             ` Ulrich Weigand
2009-08-12 17:27                               ` Paul Edwards
2009-08-12 17:56                                 ` Paolo Bonzini
2009-08-12 19:46                                 ` Ulrich Weigand
2009-08-12 20:31                                   ` Paul Edwards
2009-08-19 12:07                               ` Paul Edwards
2009-08-19 12:27                                 ` Paolo Bonzini
2009-08-20 12:49                               ` Paul Edwards
2009-08-20 22:48                                 ` Ulrich Weigand
2009-08-21  2:37                                   ` Paul Edwards
2009-08-21 16:46                                     ` Ulrich Weigand
2009-06-05 15:44   ` Joseph S. Myers
2009-06-05 15:52     ` Paul Edwards
2009-09-08 15:55     ` Paul Edwards
2009-09-14 15:32       ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).