Re: i370 port

2012-04-06 Thread Paul Edwards

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

Any suggestions on how to debug this?

Thanks.  Paul.




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

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

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

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

   return;
}

C:\devel\gcc\gcc>





-Original Message- 
From: Paul Edwards

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

I have made this change:

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

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


And it has had a good effect:

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

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

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

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





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

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

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



It triggers off a problem with plus:SI

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

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

C:\devel\gcc\gcc>


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

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

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

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

;(define_insn "addsi3"
;  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
;^I(plus:SI (match_operand:SI 1 "general_operand" "%0")
;^I^I (match_operand:SI 2 "general_operand" "g")))]
;  ""
;  "*
;{
;  check_label_emit ();
;  if (REG_P (operands[2]))
;{
;  mvs_check_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"

Re: i370 port

2012-04-06 Thread Ulrich Weigand
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'");
> } else {
>fprintf (FILE, "=XL8'");
> }
> fprintf (FILE, "%08X'", INTVAL (XV));
>   }
> 
> and it looks to me like it is already correct. If movdi is given a
> const_int as a parameter, then sign-extending to 64-bit is
> exactly what needs to happen, isn't it?
> 
> I'm only expecting to compile programs as 32-bit, so I'm not
> expecting more than 32-bit integers. The IFOX assembler
> won't do more than that. In case that's the issue.

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.weig...@de.ibm.com



Re: i370 port

2012-04-06 Thread Ulrich Weigand
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.weig...@de.ibm.com



Re: [gnat] reuse of ASTs already constructed

2012-04-06 Thread oliver.kell...@t-online.de
I am finally finding some some time to continue this work,
having left off with
  http://gcc.gnu.org/ml/gcc/2009-08/msg00475.html :

> [...]
> There are two problems right now:
> 
> 1) Mixing of Ada.Text_IO and Text_IO as described at
>http://gcc.gnu.org/ml/gcc-help/2009-08/msg00113.html

The solution to this one turned out to be quite simple, see attached patch.
Sem_Ch12.Analyze_Package_Instantiation calls Rtsfind.Text_IO_Kludge,
and the latter contains:

  if Chrs in Text_IO_Package_Name then
 for U in Main_Unit .. Last_Unit loop
Get_Name_String (Unit_File_Name (U));
...
On compiling the second file, Main_Unit is not 0 but some larger value.
The existing node for Text_IO was not being found because it is at an
index smaller than the current Main_Unit. The solution was to start the
loop at index 0.

I will now start looking into the second problem,

> 2) The 'X' lines in the ALI files are not what they should be.
> This is due to the fact that Lib.Xref.Generate_(Definition|Reference) is
> called during semantic analysis. However, when I discover that a
> tree was already built for a main unit by a previous compilation,
> Sem is not redone for that tree. Depending on whether
> Lib.Xref.Initialize is called per-job or per-file, this leads to either
> too much or too little cross ref info.

By the way, I am currently using trunk r152433 (4.5.0 pre-release) and
moving forward to the 4.5.0 release.
When that is done: Should I continue on trunk or switch to the
gcc-4_5-branch ?

Thanks,

Oliver
Index: rtsfind.adb
===
--- rtsfind.adb	(revision 152433)
+++ rtsfind.adb	(working copy)
@@ -1406,7 +1406,7 @@
   --  or [Wide_]Wide_Text_IO already loaded, then load the proper child.
 
   if Chrs in Text_IO_Package_Name then
- for U in Main_Unit .. Last_Unit loop
+ for U in 0 .. Last_Unit loop
 Get_Name_String (Unit_File_Name (U));
 
 if Name_Len = 12 then


please keep the "deprecated" -I- option: it has important functionality not available elsewhere

2012-04-06 Thread Mark Galeck (CW)
Hello,

I am the author of Foundry build system which is now transitioning to the use 
of gcc from another compiler.  This is great because gcc is an excellent 
compiler.  However. there is a potential problem for me.

I hope that the designers of gcc are aware, that some of the gcc (as any 
advanced software tool) options, are for "convenience", while some are for 
"uniformity".

With a small system, like, a few files to compile, convenience is the key - you 
want to write the necessary commands to do your compilation, as quickly as 
possible. 

With a huge system of hundreds of thousands of files, convenience goes out the 
window, and the important thing is instead, uniformity. The useful features are 
the ones who behave in a simple way and always in the same way.  That is the 
only way, with such a large system, for a human to get a handle on the 
behaviour of the system.

Case in point, is the use of "current directory" for -I/-iquote include file 
searches.  That the "current directory" (the directory that the currently 
preprocessed file was found) is searched first, is a "convenience" feature.  
For a system with few files, it is very useful.  For a huge system, with 
gazillions of files with duplicate names all over, in order to be sure that the 
intended include files are included and not some other duplicates, it is 
crucial to have a simple, uniform algorithm for the search, which lends itself 
easily to script automation.  

The addition of "current directory" to the search algorithm, makes it in 
practice impossible to ensure always the correct files are included (in a huge 
system).  

That is why I always disabled the "current directory" (and also disabled the 
use of "system" directories, and disabled any difference between "" and <>). 
That way, the one and only thing to worry about is the ordering of -I 
directories. 

As I can see, the only way to get this effect in gcc, is with -I- put before 
all the -I options.  In fact, -I- option is really for something else, and this 
disabling of current directory is a side effect.  The whole option is obsolete, 
and the side effect is in fact thought of as a nuisance in the manual.  

Nothing could be more misguided!  This "strange side effect" is in fact very 
important.  


So please don't remove -I- (or make it possible to disable the current 
directory search, with some other option).  


Thank you,

Mark Galeck



gcc-4.6-20120406 is now available

2012-04-06 Thread gccadmin
Snapshot gcc-4.6-20120406 is now available on
  ftp://gcc.gnu.org/pub/gcc/snapshots/4.6-20120406/
and on various mirrors, see http://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 4.6 SVN branch
with the following options: svn://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch 
revision 186200

You'll find:

 gcc-4.6-20120406.tar.bz2 Complete GCC

  MD5=3d7ebf813652d464f0e5b361f6a76a6d
  SHA1=6a2fcf9200f835cc9dac7076d4db1364b4177fcf

Diffs from 4.6-20120330 are available in the diffs/ subdirectory.

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


RFH - Testing targets for the switch to C++

2012-04-06 Thread Diego Novillo
I have started testing the switch to C++ and there is a pile of
testing to be done.  The testing itself is trivial, but the number of
targets that need to be tested is large and I don't have access to all
these combinations.

My proposal is to make sure that C++ builds work with:

- Primary targets
- Secondary targets
- Any other targets that people regularly test.

The first two items are easy to define.  I took them from
http://gcc.gnu.org/gcc-4.8/criteria.html.

The third item I populated from gcc-testresults postings in 2011.
This gave me a list of 136 targets.  Further, I sorted them by the
number of test reports sent, to determine an idea of "popularity".  I
removed from the list all the targets that had a popularity index
lower than 0.01%.

This is still a large list (about 109 entries), but there are several
overlapping entries (like different flavours of the same basic
target), so it should not be too bad.

The testing plan is, then, to go through this table to make sure that
we can build all of them with C++ enabled for all stages.

I have created a wiki page to track testing progress:
http://gcc.gnu.org/wiki/CppBuildStatus

My plea for help is to everyone who has access to the targets
mentioned in the list: please follow the instructions in that page and
fill-in the table entries of the targets that you tested.

If you see a missing target that should be tested, by all means, add
it to the list.


Thanks.  Diego.


build break in libstdc++-v3 on OS/2

2012-04-06 Thread Paul Smedley

Hi All,

I'm trying to update my OS/2 port of GCC to v4.6.3

I have the compiler part building, but am currently getting a break in 
libstdc++-v3.


The error is as follows:
In file included from 
U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/rege

x:39:0,
 from ../../.././libstdc++-v3/src/regex.cc:30:
U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/bitset: In member 
function
 'void std::bitset<_Nb>::_M_copy_from_ptr(const _CharT*, std::size_t, 
std::size_

t, std::size_t, _CharT, _CharT)':
U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/bitset:1371:67: 
error: no

matching function for call to 'min(unsigned int&, const unsigned int&)'
U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/bitset:1371:67: 
note: cand

idates are:
U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/bits/stl_algobase.h:187:5:
 note: template const _Tp& std::min(const _Tp&, const _Tp&)
U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/bits/stl_algobase.h:233:5:
 note: template const _Tp& std::min(const 
_Tp&, const

 _Tp&, _Compare)
U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/bits/stl_algo.h:4184:5: 
no

te: template _Tp std::min(std::initializer_list<_Tp>)
U:/DEV/gcc-4.6.3/i386-pc-os2-emx/libstdc++-v3/include/bits/stl_algo.h:4189:5: 
no
te: template _Tp 
std::min(std::initializer_list<_Tp>,

 _Compare)

Any ideas?

Cheers,

Paul



Re: i370 port

2012-04-06 Thread Paul Edwards

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


Hi Ulrich. Thanks for your reply.

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

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

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

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

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

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


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


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

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

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


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


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


Thanks.  Paul.



Re: i370 port

2012-04-06 Thread Paul Edwards

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.