* Re: [PATCH] adds powerpc-*-freebsd? to mainline
2001-11-13 15:03 ` Geoff Keating
@ 2001-11-13 15:03 ` David Edelsohn
2001-11-13 15:03 ` David O'Brien
2001-11-13 15:03 ` Richard Henderson
0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2001-11-13 15:03 UTC (permalink / raw)
To: Geoff Keating; +Cc: shebs, obrien, gcc-patches
>>>>> Geoff Keating writes:
>> Not to mention that this is ugly and cumbersome.
Geoff> I couldn't think of a better solution, neither could David, and I
Geoff> find the solution grows on me. Isn't this exactly what header files
Geoff> are for?
If this now is a required file for config/rs6000/sysv4.h, why not
#include it right before the macros are used instead of adding it
throughout config.gcc? If the two no longer can be separated, it makes no
sense for everyone to repeat that boilerplate.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] adds powerpc-*-freebsd? to mainline
2001-11-13 15:03 ` David Edelsohn
@ 2001-11-13 15:03 ` David O'Brien
2001-11-13 15:03 ` Geoff Keating
1 sibling, 0 replies; 875+ messages in thread
From: David O'Brien @ 2001-11-13 15:03 UTC (permalink / raw)
To: David Edelsohn; +Cc: Geoff Keating, shebs, gcc-patches
On Wed, Nov 21, 2001 at 12:19:25AM -0500, David Edelsohn wrote:
> Geoff> Why do you object?
>
> Because a FreeBSD maintainer for any architecture now can break
> all PowerPC ELF targets. Not to mention that this is ugly and
> cumbersome.
Only with a syntax error. The values used from freebsd-spec.h cannot
break any other target.
--
-- David (obrien@FreeBSD.org)
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] adds powerpc-*-freebsd? to mainline
@ 2001-11-13 15:03 David Edelsohn
2001-11-13 15:03 ` Geoff Keating
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2001-11-13 15:03 UTC (permalink / raw)
To: Geoff Keating, Stan Shebs, David O'Brien; +Cc: gcc-patches
>>>>> Geoff writes:
Geoff> I don't think that would be a problem.
I have a problem with that. Adding freebsd-spec.h to the generic
PowerPC ELF targets is fine, but adding it to every ELF target is not
acceptable to me. I do not agree with the config.gcc changes in this
patch and it needs to be revised or reverted.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] adds powerpc-*-freebsd? to mainline
2001-11-13 15:03 ` David Edelsohn
2001-11-13 15:03 ` David O'Brien
@ 2001-11-13 15:03 ` Geoff Keating
2001-11-13 15:03 ` David Edelsohn
1 sibling, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2001-11-13 15:03 UTC (permalink / raw)
To: dje; +Cc: shebs, obrien, gcc-patches
> cc: shebs@apple.com, obrien@FreeBSD.org, gcc-patches@gcc.gnu.org
> Date: Wed, 21 Nov 2001 00:19:25 -0500
> From: David Edelsohn <dje@watson.ibm.com>
>
> >>>>> Geoff Keating writes:
>
> Geoff> Why do you object?
>
> Because a FreeBSD maintainer for any architecture now can break
> all PowerPC ELF targets.
Well,
(a) so let's tell them not to do that.
(b) I really don't think it's likely that they'll be able to somehow
break things in a file that defines five macros, unless
of course they forget to 'cvs add' it (hint hint David)
(c) and anyway, the automated regression tester will catch them.
> Not to mention that this is ugly and cumbersome.
I couldn't think of a better solution, neither could David, and I
find the solution grows on me. Isn't this exactly what header files
are for?
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] adds powerpc-*-freebsd? to mainline
2001-11-13 15:03 [PATCH] adds powerpc-*-freebsd? to mainline David Edelsohn
@ 2001-11-13 15:03 ` Geoff Keating
2001-11-13 15:03 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2001-11-13 15:03 UTC (permalink / raw)
To: dje; +Cc: shebs, obrien, gcc-patches
> cc: gcc-patches@gcc.gnu.org
> Date: Tue, 20 Nov 2001 22:56:40 -0500
> From: David Edelsohn <dje@watson.ibm.com>
>
> >>>>> Geoff writes:
>
> Geoff> I don't think that would be a problem.
>
> I have a problem with that. Adding freebsd-spec.h to the generic
> PowerPC ELF targets is fine, but adding it to every ELF target is not
> acceptable to me. I do not agree with the config.gcc changes in this
> patch and it needs to be revised or reverted.
Why do you object?
The only differences from the similar definitions for Linux (and,
once, Solaris) in srv4.h are that this is in a separate file and is
shared with other freebsd OSs.
It's worth noting that there are only 'generic' PowerPC ELF targets.
All ELF targets just take the generic target and change the defaults,
but all the functionality is always there.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] adds powerpc-*-freebsd? to mainline
2001-11-13 15:03 ` David Edelsohn
2001-11-13 15:03 ` David O'Brien
@ 2001-11-13 15:03 ` Richard Henderson
1 sibling, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2001-11-13 15:03 UTC (permalink / raw)
To: David Edelsohn; +Cc: Geoff Keating, shebs, obrien, gcc-patches
On Wed, Nov 21, 2001 at 01:03:05AM -0500, David Edelsohn wrote:
> If this now is a required file for config/rs6000/sysv4.h, why not
> #include it right before the macros are used instead of adding it
> throughout config.gcc?
Putting it in config.gcc means that Makefile dependencies come out right.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] adds powerpc-*-freebsd? to mainline
2001-11-13 15:03 ` David Edelsohn
@ 2001-11-13 15:03 ` David O'Brien
2001-11-13 15:03 ` Richard Henderson
1 sibling, 0 replies; 875+ messages in thread
From: David O'Brien @ 2001-11-13 15:03 UTC (permalink / raw)
To: David Edelsohn; +Cc: Geoff Keating, shebs, gcc-patches
On Wed, Nov 21, 2001 at 01:03:05AM -0500, David Edelsohn wrote:
> If this now is a required file for config/rs6000/sysv4.h, why not
> #include it right before the macros are used instead of adding it
> throughout config.gcc?
That is the style I was taught by Jeff Law. He spoke as if it was a
rather absolute rule. (maybe I misunderstood him)
--
-- David (obrien@FreeBSD.org)
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] adds powerpc-*-freebsd? to mainline
2001-11-13 15:03 ` Geoff Keating
@ 2001-11-13 15:03 ` David Edelsohn
2001-11-13 15:03 ` David O'Brien
2001-11-13 15:03 ` Geoff Keating
0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2001-11-13 15:03 UTC (permalink / raw)
To: Geoff Keating; +Cc: shebs, obrien, gcc-patches
>>>>> Geoff Keating writes:
Geoff> Why do you object?
Because a FreeBSD maintainer for any architecture now can break
all PowerPC ELF targets. Not to mention that this is ugly and
cumbersome.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* PATCH, rs6000 (alpha?) long const
@ 2001-12-29 7:03 Tom Rix
2001-12-29 11:40 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: Tom Rix @ 2001-12-29 7:03 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 552 bytes --]
This patch fixes an incorrect add of a large immediate in
rs6000_emit_set_long_const. d2 can not be added because it is greater
than 2^16.
To reproduce the problem, run the testsuite with the -maix64 switch. A
large number of internal compiler errors are generated. The one I
looked specifically was execute/920410-1.c
With the patch, -maix64 c failures are reduced from 216 to 115.
Looks like alpha also uses this logic. Can someone familar with alpha
comment on the old logic's correctness?
Tom
--
Tom Rix
GCC Engineer
trix@redhat.com
[-- Attachment #2: long_const-001fa.patch --]
[-- Type: text/plain, Size: 2939 bytes --]
2001-12-28 Tom Rix <trix@redhat.com>
* config/rs6000/rs6000.c (rs6000_emit_set_long_const): Fix invalid add
of large immediate.
diff -rcp gcc-old/gcc/config/rs6000/rs6000.c gcc/gcc/config/rs6000/rs6000.c
*** gcc-old/gcc/config/rs6000/rs6000.c Fri Dec 28 10:00:02 2001
--- gcc/gcc/config/rs6000/rs6000.c Fri Dec 28 22:59:44 2001
*************** rs6000_emit_set_long_const (dest, c1, c2
*** 2002,2008 ****
}
else
{
! HOST_WIDE_INT d1, d2, d3, d4;
/* Decompose the entire word */
#if HOST_BITS_PER_WIDE_INT >= 64
--- 2002,2008 ----
}
else
{
! HOST_WIDE_INT d1, d2, d2_s, d3, d4;
/* Decompose the entire word */
#if HOST_BITS_PER_WIDE_INT >= 64
*************** rs6000_emit_set_long_const (dest, c1, c2
*** 2011,2016 ****
--- 2011,2017 ----
d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
c1 -= d1;
d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
+ d2_s = d2 >> 16;
c1 = (c1 - d2) >> 32;
d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
c1 -= d3;
*************** rs6000_emit_set_long_const (dest, c1, c2
*** 2021,2026 ****
--- 2022,2028 ----
d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
c1 -= d1;
d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
+ d2_s = d2 >> 16;
if (c1 != d2)
abort ();
c2 += (d2 < 0);
*************** rs6000_emit_set_long_const (dest, c1, c2
*** 2039,2056 ****
emit_move_insn (dest,
gen_rtx_PLUS (DImode, dest, GEN_INT (d3)));
}
! else
emit_move_insn (dest, GEN_INT (d3));
/* Shift it into place */
if (d3 != 0 || d4 != 0)
! emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
/* Add in the low bits. */
if (d2 != 0)
! emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d2)));
if (d1 != 0)
! emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d1)));
}
return dest;
--- 2041,2074 ----
emit_move_insn (dest,
gen_rtx_PLUS (DImode, dest, GEN_INT (d3)));
}
! else if (d3 != 0)
emit_move_insn (dest, GEN_INT (d3));
/* Shift it into place */
if (d3 != 0 || d4 != 0)
! if (d2 != 0)
! emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
! else
! emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
/* Add in the low bits. */
if (d2 != 0)
! {
! if (d3 != 0 || d4 != 0)
! {
! emit_move_insn (dest, gen_rtx_PLUS (DImode, dest,
! GEN_INT (d2_s)));
! emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest,
! GEN_INT (16)));
! }
! else
! emit_move_insn (dest, GEN_INT (d2));
! }
if (d1 != 0)
! if (d2 != 0 || d3 != 0 || d4 != 0)
! emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d1)));
! else
! emit_move_insn (dest, GEN_INT (d1));
}
return dest;
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const
2001-12-29 7:03 PATCH, rs6000 (alpha?) long const Tom Rix
@ 2001-12-29 11:40 ` Richard Henderson
2001-12-29 12:40 ` Tom Rix
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2001-12-29 11:40 UTC (permalink / raw)
To: Tom Rix; +Cc: gcc-patches
On Sat, Dec 29, 2001 at 09:22:23AM -0600, Tom Rix wrote:
> Looks like alpha also uses this logic. Can someone familar with alpha
> comment on the old logic's correctness?
The 'L' constraint is for exactly this sort of constant. This
is supported by the "ldah" insn on alpha, and "addis" on ppc64.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const
2001-12-29 11:40 ` Richard Henderson
@ 2001-12-29 12:40 ` Tom Rix
2001-12-29 17:00 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: Tom Rix @ 2001-12-29 12:40 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches
Richard Henderson wrote:
> On Sat, Dec 29, 2001 at 09:22:23AM -0600, Tom Rix wrote:
> > Looks like alpha also uses this logic. Can someone familar with alpha
> > comment on the old logic's correctness?
>
> The 'L' constraint is for exactly this sort of constant. This
> is supported by the "ldah" insn on alpha, and "addis" on ppc64.
>
Yes. The internal errors complained about not meeting the insn's 'L'
contraint. In the case I looked at, rs6000_emit_set_long_const was
called from rs6000_emit_allocate_stack, via try_split. I believe the
usual contraint checking is bypassed and was worried alpha would have the
same problem.
Tom
>
> r~
--
Tom Rix
GCC Engineer
trix@redhat.com
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const
2001-12-29 12:40 ` Tom Rix
@ 2001-12-29 17:00 ` Richard Henderson
2001-12-29 18:37 ` Tom Rix
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2001-12-29 17:00 UTC (permalink / raw)
To: Tom Rix; +Cc: gcc-patches
On Sat, Dec 29, 2001 at 03:33:35PM -0600, Tom Rix wrote:
> Yes. The internal errors complained about not meeting the insn's 'L'
> contraint.
What is the number that didn't match?
> I believe the usual contraint checking is bypassed...
No.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const
2001-12-29 17:00 ` Richard Henderson
@ 2001-12-29 18:37 ` Tom Rix
2001-12-29 20:45 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: Tom Rix @ 2001-12-29 18:37 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches
Richard Henderson wrote:
> On Sat, Dec 29, 2001 at 03:33:35PM -0600, Tom Rix wrote:
> > Yes. The internal errors complained about not meeting the insn's 'L'
> > contraint.
>
> What is the number that didn't match?
-131072
split from -160128
Tom
--
Tom Rix
GCC Engineer
trix@redhat.com
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const
2001-12-29 18:37 ` Tom Rix
@ 2001-12-29 20:45 ` Richard Henderson
2001-12-29 21:24 ` PATCH, rs6000 (alpha?) long const --verbose Tom Rix
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2001-12-29 20:45 UTC (permalink / raw)
To: Tom Rix; +Cc: gcc-patches
On Sat, Dec 29, 2001 at 09:06:39PM -0600, Tom Rix wrote:
> > What is the number that didn't match?
>
> -131072
That's 0xffff_ffff_fffe_0000, which is definitely valid. So
why doesn't that insn get recognized?
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const --verbose
2001-12-29 20:45 ` Richard Henderson
@ 2001-12-29 21:24 ` Tom Rix
2001-12-29 23:01 ` Richard Henderson
2001-12-29 23:02 ` Richard Henderson
0 siblings, 2 replies; 875+ messages in thread
From: Tom Rix @ 2001-12-29 21:24 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches
Richard Henderson wrote:
> On Sat, Dec 29, 2001 at 09:06:39PM -0600, Tom Rix wrote:
> > > What is the number that didn't match?
> >
> > -131072
>
> That's 0xffff_ffff_fffe_0000, which is definitely valid. So
> why doesn't that insn get recognized?
I believe the rs6000_emit_allocate_stack is called after the usual
recogn/splitting. From inspection of the funtion :
if (TARGET_UPDATE)
{
if (size > 32767) << --checking for large stack
{
/* Need a note here so that try_split doesn't get confused.
*/
if (get_last_insn() == NULL_RTX)
emit_note (0, NOTE_INSN_DELETED);
insn = emit_move_insn (tmp_reg, todec);
try_split (PATTERN (insn), insn, 0); << --splitting the r1 =
r1 - bigstack
todec = tmp_reg;
}
}
If this was a normal add (a = a - 131072), yes the constraint in adddi3
would have worked. I am guessing the check for the size means this
add happens after normal contraint checking/splitting and split is
being done here the hard way.
The split that try_split uses is :
;; Split a load of a large constant into the appropriate
five-instruction
;; sequence. Handle anything in a constant number of insns.
;; When non-easy constants can go in the TOC, this should use
;; easy_fp_constant predicate.
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(match_operand:DI 1 "const_int_operand" ""))]
"TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
[(set (match_dup 0) (match_dup 2))
(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
"
{ rtx tem = rs6000_emit_set_const (operands[0], DImode, operands[1], 5);
if (tem == operands[0])
DONE;
else
FAIL;
}")
Here is the rtl dump of the stack allocation from flow2 :
(note 3 2 5 NOTE_INSN_FUNCTION_BEG)
(note 5 3 24 30033180 NOTE_INSN_BLOCK_BEG)
;; Start of basic block 0, registers live: 1 [1] 65 [lr]
(note 24 5 29 [bb 0] NOTE_INSN_BASIC_BLOCK)
(insn 29 24 31 (set (reg:DI 0 r0)
(reg:DI 65 lr)) -1 (nil)
(expr_list:REG_DEAD (reg:DI 65 lr)
(nil)))
(insn/f 31 29 35 (set (mem:DI (plus:DI (reg/f:DI 1 r1)
(const_int 16 [0x10])) [0 S8 A64])
(reg:DI 0 r0)) -1 (insn_list 29 (nil))
(expr_list:REG_DEAD (reg:DI 0 r0)
(expr_list:REG_FRAME_RELATED_EXPR (set (mem:DI (plus:DI
(reg/f:DI 1 r1)
(const_int 16 [0x10])) [0 S8 A64])
(reg:DI 65 lr))
(nil))))
-- start of rs6000_emit_set_long_const
<<< emit_move_insn (dest, GEN_INT (d3));
(insn 35 31 37 (set (reg:DI 0 r0)
(const_int 0 [0x0])) -1 (nil)
(nil))
<<< if (d2 != 0)
emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT
(d2)));
(insn 37 35 39 (set (reg:DI 0 r0) <<< this is the problem >>>
(plus:DI (reg:DI 0 r0)
(const_int -131072 [0xfffffffffffe0000]))) -1 (insn_list 35
(nil))
(nil))
<<< if (d1 != 0)
emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT
(d1)));
(insn 39 37 40 (set (reg:DI 0 r0)
(plus:DI (reg:DI 0 r0)
(const_int -29040 [0xffffffffffff8e90]))) -1 (insn_list 37
(nil))
(nil))
-- end of rs6000_emit_set_long const
(insn/f 40 39 41 (parallel[
(set (mem:DI (plus:DI (reg/f:DI 1 r1)
(reg:DI 0 r0)) [0 S8 A64])
(reg/f:DI 1 r1))
(set (reg/f:DI 1 r1)
(plus:DI (reg/f:DI 1 r1)
(reg:DI 0 r0)))
] ) -1 (insn_list 39 (nil))
(expr_list:REG_DEAD (reg:DI 0 r0)
(expr_list:REG_FRAME_RELATED_EXPR (set (reg/f:DI 1 r1)
(plus:DI (reg/f:DI 1 r1)
(const_int -160112 [0xfffffffffffd8e90])))
(nil))))
(note 41 40 9 NOTE_INSN_PROLOGUE_END)
>
>
New add improved spits out
(insn 35 31 37 (set (reg:DI 0 r0)
(const_int -131072 [0xfffffffffffe0000])) -1 (nil)
(nil))
(insn 37 35 38 (set (reg:DI 0 r0)
(plus:DI (reg:DI 0 r0)
(const_int -29040 [0xffffffffffff8e90]))) -1 (insn_list 35
(nil))
(nil))
Which is fairly close to the way it used to work before
rs6000_emit_set_long_const. If you want to see that, I will have to
set output to --verbose --verbose :)~
If rs6000_emit_set_long_const is called early, the error of the add
will be hidden by splitting it again as if it were a normal addition of
a large immediate. If it is called late, the error shows up as a fatal
compiler error.
Tom
--
Tom Rix
GCC Engineer
trix@redhat.com
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const --verbose
2001-12-29 21:24 ` PATCH, rs6000 (alpha?) long const --verbose Tom Rix
@ 2001-12-29 23:01 ` Richard Henderson
2001-12-29 23:02 ` Richard Henderson
1 sibling, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2001-12-29 23:01 UTC (permalink / raw)
To: Tom Rix; +Cc: gcc-patches
On Sat, Dec 29, 2001 at 11:42:37PM -0600, Tom Rix wrote:
> try_split (PATTERN (insn), insn, 0); << --splitting the r1 =
Hum. I'm of the opinion that this is fairly dodgy. Try this.
r~
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.270
diff -c -p -d -r1.270 rs6000.c
*** rs6000.c 2001/12/29 09:07:56 1.270
--- rs6000.c 2001/12/30 06:49:38
*************** rs6000_emit_set_const (dest, mode, sourc
*** 1951,1963 ****
{
HOST_WIDE_INT c0, c1;
! if (mode == QImode || mode == HImode || mode == SImode)
{
- if (dest == NULL)
- dest = gen_reg_rtx (mode);
emit_insn (gen_rtx_SET (VOIDmode, dest, source));
return dest;
}
if (GET_CODE (source) == CONST_INT)
{
--- 1951,1976 ----
{
HOST_WIDE_INT c0, c1;
! if (dest == NULL)
! dest = gen_reg_rtx (mode);
!
! if (num_insns_constant (source, mode) == 1)
{
emit_insn (gen_rtx_SET (VOIDmode, dest, source));
return dest;
}
+ else if (mode == SImode)
+ {
+ if (GET_CODE (source) != CONST_INT)
+ abort ();
+ c0 = INTVAL (source);
+ emit_insn (gen_rtx_SET (VOIDmode, dest,
+ GEN_INT (c0 & ~ (HOST_WIDE_INT) 0xffff)));
+ emit_insn (gen_rtx_SET (VOIDmode, dest,
+ gen_rtx_IOR (mode, dest,
+ GEN_INT (c0 & 0xffff))));
+ return dest;
+ }
if (GET_CODE (source) == CONST_INT)
{
*************** rs6000_emit_allocate_stack (size, copy_r
*** 7755,7769 ****
if (TARGET_UPDATE)
{
if (size > 32767)
! {
! /* Need a note here so that try_split doesn't get confused. */
! if (get_last_insn() == NULL_RTX)
! emit_note (0, NOTE_INSN_DELETED);
! insn = emit_move_insn (tmp_reg, todec);
! try_split (PATTERN (insn), insn, 0);
! todec = tmp_reg;
! }
!
if (Pmode == SImode)
insn = emit_insn (gen_movsi_update (stack_reg, stack_reg,
todec, stack_reg));
--- 7768,7775 ----
if (TARGET_UPDATE)
{
if (size > 32767)
! todec = rs6000_emit_set_const (tmp_reg, Pmode, todec, 5);
!
if (Pmode == SImode)
insn = emit_insn (gen_movsi_update (stack_reg, stack_reg,
todec, stack_reg));
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const --verbose
2001-12-29 21:24 ` PATCH, rs6000 (alpha?) long const --verbose Tom Rix
2001-12-29 23:01 ` Richard Henderson
@ 2001-12-29 23:02 ` Richard Henderson
2002-01-01 12:21 ` PATCH, rs6000 (alpha?) long const take 2 Tom Rix
1 sibling, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2001-12-29 23:02 UTC (permalink / raw)
To: Tom Rix; +Cc: gcc-patches
On Sat, Dec 29, 2001 at 11:42:37PM -0600, Tom Rix wrote:
> (insn 37 35 39 (set (reg:DI 0 r0) <<< this is the problem >>>
>
> (plus:DI (reg:DI 0 r0)
> (const_int -131072 [0xfffffffffffe0000]))) -1 (insn_list 35
> (nil))
> (nil))
Actually, the real problem is that addis must be used
with some register other than r0. So the temp register
chosen should be other than r0.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const take 2
2001-12-29 23:02 ` Richard Henderson
@ 2002-01-01 12:21 ` Tom Rix
2002-01-01 13:46 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: Tom Rix @ 2002-01-01 12:21 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 581 bytes --]
Richard Henderson wrote:
> On Sat, Dec 29, 2001 at 11:42:37PM -0600, Tom Rix wrote:
> > (insn 37 35 39 (set (reg:DI 0 r0) <<< this is the problem >>>
> >
> > (plus:DI (reg:DI 0 r0)
> > (const_int -131072 [0xfffffffffffe0000]))) -1 (insn_list 35
> > (nil))
> > (nil))
>
> Actually, the real problem is that addis must be used
> with some register other than r0. So the temp register
> chosen should be other than r0.
Yes.
Here is the original patch modified to do the addsi if the reg is not 0.
Tom
--
Tom Rix
GCC Engineer
trix@redhat.com
[-- Attachment #2: long_const-002fa.patch --]
[-- Type: text/plain, Size: 3307 bytes --]
2002-01-01 Tom Rix <trix@redhat.com>
* config/rs6000/rs6000.c (rs6000_emit_set_long_const): Fix for use by
rs6000_emit_allocate_stack.
diff -rcp gcc-old/gcc/config/rs6000/rs6000.c gcc/gcc/config/rs6000/rs6000.c
*** gcc-old/gcc/config/rs6000/rs6000.c Tue Jan 1 07:12:35 2002
--- gcc/gcc/config/rs6000/rs6000.c Tue Jan 1 07:34:25 2002
*************** rs6000_emit_set_long_const (dest, c1, c2
*** 2002,2008 ****
}
else
{
! HOST_WIDE_INT d1, d2, d3, d4;
/* Decompose the entire word */
#if HOST_BITS_PER_WIDE_INT >= 64
--- 2002,2013 ----
}
else
{
! HOST_WIDE_INT d1, d2, d2_s, d3, d4;
!
! /* This function is called by rs6000_emit_allocate_stack after reload
! with a dest of r0. r0 is an invalid register for addsi. Use an addi
! and a shift instead. */
! int regnum = REGNO (dest);
/* Decompose the entire word */
#if HOST_BITS_PER_WIDE_INT >= 64
*************** rs6000_emit_set_long_const (dest, c1, c2
*** 2011,2016 ****
--- 2016,2022 ----
d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
c1 -= d1;
d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
+ d2_s = d2 >> 16;
c1 = (c1 - d2) >> 32;
d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
c1 -= d3;
*************** rs6000_emit_set_long_const (dest, c1, c2
*** 2021,2026 ****
--- 2027,2033 ----
d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
c1 -= d1;
d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
+ d2_s = d2 >> 16;
if (c1 != d2)
abort ();
c2 += (d2 < 0);
*************** rs6000_emit_set_long_const (dest, c1, c2
*** 2039,2056 ****
emit_move_insn (dest,
gen_rtx_PLUS (DImode, dest, GEN_INT (d3)));
}
! else
emit_move_insn (dest, GEN_INT (d3));
/* Shift it into place */
if (d3 != 0 || d4 != 0)
! emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
/* Add in the low bits. */
if (d2 != 0)
! emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d2)));
if (d1 != 0)
! emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d1)));
}
return dest;
--- 2046,2085 ----
emit_move_insn (dest,
gen_rtx_PLUS (DImode, dest, GEN_INT (d3)));
}
! else if (d3 != 0)
emit_move_insn (dest, GEN_INT (d3));
/* Shift it into place */
if (d3 != 0 || d4 != 0)
! if (regnum == 0 && d2 != 0)
! emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
! else
! emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
/* Add in the low bits. */
if (d2 != 0)
! {
! if (d3 != 0 || d4 != 0)
! {
! if (regnum == 0)
! {
! emit_move_insn (dest, gen_rtx_PLUS (DImode, dest,
! GEN_INT (d2_s)));
! emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest,
! GEN_INT (16)));
! }
! else
! emit_move_insn (dest, gen_rtx_PLUS (DImode, dest,
! GEN_INT (d2)));
! }
! else
! emit_move_insn (dest, GEN_INT (d2));
! }
if (d1 != 0)
! if (d2 != 0 || d3 != 0 || d4 != 0)
! emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d1)));
! else
! emit_move_insn (dest, GEN_INT (d1));
}
return dest;
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const take 2
2002-01-01 12:21 ` PATCH, rs6000 (alpha?) long const take 2 Tom Rix
@ 2002-01-01 13:46 ` Richard Henderson
2002-01-02 13:20 ` Geoff Keating
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-01-01 13:46 UTC (permalink / raw)
To: Tom Rix; +Cc: gcc-patches
On Tue, Jan 01, 2002 at 03:16:57PM -0600, Tom Rix wrote:
> * config/rs6000/rs6000.c (rs6000_emit_set_long_const): Fix for use by
> rs6000_emit_allocate_stack.
Ok.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const take 2
2002-01-01 13:46 ` Richard Henderson
@ 2002-01-02 13:20 ` Geoff Keating
2002-01-02 13:22 ` Richard Henderson
2002-01-02 20:44 ` David Edelsohn
0 siblings, 2 replies; 875+ messages in thread
From: Geoff Keating @ 2002-01-02 13:20 UTC (permalink / raw)
To: trix; +Cc: Richard Henderson, gcc-patches
Richard Henderson <rth@redhat.com> writes:
> On Tue, Jan 01, 2002 at 03:16:57PM -0600, Tom Rix wrote:
> > * config/rs6000/rs6000.c (rs6000_emit_set_long_const): Fix for use by
> > rs6000_emit_allocate_stack.
>
> Ok.
No, not ok!
! /* This function is called by rs6000_emit_allocate_stack after reload
! with a dest of r0. r0 is an invalid register for addsi. Use an addi
! and a shift instead. */
The code sequence to load a value into r0 is like this:
lis %r0,0x1234
ori %r0,%r0,0x5678
If you already have a value in r0's high bits (and know the low bits
are 0), you can use
oris %r0,%r0,0x9ABC
ori %r0,%r0,0xDEF0
So the full 5-word load sequence looks like:
lis %r0,0x1234
ori %r0,%r0,0x5678
sli %r0,%r0,32
oris %r0,%r0,0x9ABC
ori %r0,%r0,0xDEF0
There is no need for additional shift instructions.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const take 2
2002-01-02 13:20 ` Geoff Keating
@ 2002-01-02 13:22 ` Richard Henderson
2002-01-02 20:44 ` David Edelsohn
1 sibling, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-01-02 13:22 UTC (permalink / raw)
To: Geoff Keating; +Cc: trix, gcc-patches
On Wed, Jan 02, 2002 at 01:14:19PM -0800, Geoff Keating wrote:
> oris %r0,%r0,0x9ABC
Doh. I forgot that oris didn't sign-extend the constant.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const take 2
2002-01-02 13:20 ` Geoff Keating
2002-01-02 13:22 ` Richard Henderson
@ 2002-01-02 20:44 ` David Edelsohn
2002-01-03 0:52 ` Richard Henderson
1 sibling, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-01-02 20:44 UTC (permalink / raw)
To: Geoff Keating, trix, Richard Henderson; +Cc: gcc-patches
Do we want to change rs6000_emit_set_long_const to use get_rtx_IOR
instead of gen_rtx_PLUS?
Also, if explicitly allocting r0 was a problem, r12 should have
been used instead. Adding extra shifts was wrong on a number of levels.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const take 2
2002-01-02 20:44 ` David Edelsohn
@ 2002-01-03 0:52 ` Richard Henderson
2002-01-03 8:06 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-01-03 0:52 UTC (permalink / raw)
To: David Edelsohn; +Cc: Geoff Keating, trix, gcc-patches
On Wed, Jan 02, 2002 at 11:26:12PM -0500, David Edelsohn wrote:
> Do we want to change rs6000_emit_set_long_const to use get_rtx_IOR
> instead of gen_rtx_PLUS?
>
> Also, if explicitly allocting r0 was a problem, r12 should have
> been used instead. Adding extra shifts was wrong on a number of levels.
I think changing rs6000_emit_set_long_const so that it always
works is the right thing. If you want to choose another register,
that's fine.
That said, IOR clearly works better than PLUS because of the r0 issue.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const take 2
2002-01-03 0:52 ` Richard Henderson
@ 2002-01-03 8:06 ` David Edelsohn
2002-01-04 12:04 ` Geoff Keating
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-01-03 8:06 UTC (permalink / raw)
To: Richard Henderson, Geoff Keating, trix, gcc-patches
>>>>> Richard Henderson writes:
Richard> I think changing rs6000_emit_set_long_const so that it always
Richard> works is the right thing. If you want to choose another register,
Richard> that's fine.
rs6000_emit_set_long_const() does always work when called from the
MD file because the MD file register constraints ensure that the
instructions always will have an appropriate registers.
Only, *ONLY*, rs6000_emit_allocate_stack() forces r0 into a
pattern for which it was not designed:
rtx tmp_reg = gen_rtx_REG (Pmode, 0);
rs6000_emit_allocate_stack() is the problem and what should be fixed, not
rs6000_emit_set_long_const(). rs6000_emit_set_long_const() was the
symptom and was correct. Fix the problem, not the symptom.
Richard> That said, IOR clearly works better than PLUS because of the r0 issue.
If rs6000_emit_allocate_stack() cannot be rewritten in terms of
r12 for this large stack frame case, *IT* should be modified to use
gen_iorsi3() instead of gen_addsi3() for that case, not modifying
rs6000_emit_set_long_const().
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const take 2
2002-01-03 8:06 ` David Edelsohn
@ 2002-01-04 12:04 ` Geoff Keating
2002-01-04 14:31 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-01-04 12:04 UTC (permalink / raw)
To: dje; +Cc: rth, trix, gcc-patches
> Date: Thu, 03 Jan 2002 11:04:19 -0500
> From: David Edelsohn <dje@watson.ibm.com>
>
> If rs6000_emit_allocate_stack() cannot be rewritten in terms of
> r12 for this large stack frame case, *IT* should be modified to use
> gen_iorsi3() instead of gen_addsi3() for that case, not modifying
> rs6000_emit_set_long_const().
Wouldn't it be better to improve rs6000_emit_set_long_const so that it
can handle r0 as a destination? That would make it more useful as a
routine, and would mean that if some other piece of code needs to set
a register, which might be r0, to a constant,
rs6000_emit_set_long_const could be used without needing any changes.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 (alpha?) long const take 2
2002-01-04 12:04 ` Geoff Keating
@ 2002-01-04 14:31 ` David Edelsohn
2002-01-10 14:00 ` PATCH, rs6000 long const take 3 Tom Rix
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-01-04 14:31 UTC (permalink / raw)
To: Geoff Keating; +Cc: rth, trix, gcc-patches
>>>>> Geoff Keating writes:
Geoff> Wouldn't it be better to improve rs6000_emit_set_long_const so that it
Geoff> can handle r0 as a destination? That would make it more useful as a
Geoff> routine, and would mean that if some other piece of code needs to set
Geoff> a register, which might be r0, to a constant,
Geoff> rs6000_emit_set_long_const could be used without needing any changes.
Are you suggesting / recommending the function be implemented only
in terms of IOR (which works with any GPR) instead of PLUS or that the
function should try to choose between IOR and PLUS based on the most
efficient algorithm for the particular constant and register?
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* PATCH, rs6000 long const take 3
2002-01-04 14:31 ` David Edelsohn
@ 2002-01-10 14:00 ` Tom Rix
2002-01-10 14:08 ` Richard Henderson
2002-01-10 14:20 ` David Edelsohn
0 siblings, 2 replies; 875+ messages in thread
From: Tom Rix @ 2002-01-10 14:00 UTC (permalink / raw)
To: David Edelsohn; +Cc: Geoff Keating, rth, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1056 bytes --]
David Edelsohn wrote:
> >>>>> Geoff Keating writes:
>
> Geoff> Wouldn't it be better to improve rs6000_emit_set_long_const so that it
> Geoff> can handle r0 as a destination? That would make it more useful as a
> Geoff> routine, and would mean that if some other piece of code needs to set
> Geoff> a register, which might be r0, to a constant,
> Geoff> rs6000_emit_set_long_const could be used without needing any changes.
>
> Are you suggesting / recommending the function be implemented only
> in terms of IOR (which works with any GPR) instead of PLUS
Yes. Here is a patch to replace the PLUS with IOR
> or that the
> function should try to choose between IOR and PLUS based on the most
> efficient algorithm for the particular constant and register?
PLUS favors 0xffff_ffff_8xxx_xxxx and half words of 0xffff's
IOR favors 0x0000_0000_7xxx_xxxx and half words of 0x0000's.
Other than that they are evenly matched.
I don't think there is enough of a win to check for the PLUS algorithm.
Tom
--
Tom Rix
GCC Engineer
trix@redhat.com
[-- Attachment #2: long_const-004fa.patch --]
[-- Type: text/plain, Size: 4898 bytes --]
2002-01-10 Tom Rix <trix@redhat.com>
* config/rs6000/rs6000.c (rs6000_emit_set_long_const): Use ior for
TARGET_POWERPC64.
diff -rcp gcc-old/gcc/config/rs6000/rs6000.c gcc/gcc/config/rs6000/rs6000.c
*** gcc-old/gcc/config/rs6000/rs6000.c Fri Jan 4 19:51:37 2002
--- gcc/gcc/config/rs6000/rs6000.c Thu Jan 10 10:46:43 2002
*************** rs6000_emit_set_long_const (dest, c1, c2
*** 2002,2087 ****
}
else
{
! HOST_WIDE_INT d1, d2, d2_s, d3, d4;
! /* This function is called by rs6000_emit_allocate_stack after reload
! with a dest of r0. r0 is an invalid register for addsi. Use an addi
! and a shift instead. */
! int regnum = REGNO (dest);
!
! /* Decompose the entire word */
#if HOST_BITS_PER_WIDE_INT >= 64
! if (c2 != -(c1 < 0))
! abort ();
! d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
! c1 -= d1;
! d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
! d2_s = d2 >> 16;
! c1 = (c1 - d2) >> 32;
! d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
! c1 -= d3;
! d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
! if (c1 != d4)
! abort ();
! #else
! d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
! c1 -= d1;
! d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
! d2_s = d2 >> 16;
! if (c1 != d2)
! abort ();
! c2 += (d2 < 0);
! d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
! c2 -= d3;
! d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
! if (c2 != d4)
! abort ();
#endif
! /* Construct the high word */
! if (d4 != 0)
{
! emit_move_insn (dest, GEN_INT (d4));
! if (d3 != 0)
! emit_move_insn (dest,
! gen_rtx_PLUS (DImode, dest, GEN_INT (d3)));
}
- else if (d3 != 0)
- emit_move_insn (dest, GEN_INT (d3));
! /* Shift it into place */
! if (d3 != 0 || d4 != 0)
! if (regnum == 0 && d2 != 0)
! emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
! else
! emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
! /* Add in the low bits. */
! if (d2 != 0)
{
! if (d3 != 0 || d4 != 0)
! {
! if (regnum == 0)
! {
! emit_move_insn (dest, gen_rtx_PLUS (DImode, dest,
! GEN_INT (d2_s)));
! emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest,
! GEN_INT (16)));
! }
! else
! emit_move_insn (dest, gen_rtx_PLUS (DImode, dest,
! GEN_INT (d2)));
! }
else
! emit_move_insn (dest, GEN_INT (d2));
}
- if (d1 != 0)
- if (d2 != 0 || d3 != 0 || d4 != 0)
- emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT (d1)));
- else
- emit_move_insn (dest, GEN_INT (d1));
}
-
return dest;
}
--- 2002,2071 ----
}
else
{
! HOST_WIDE_INT ud1, ud2, ud3, ud4;
! ud1 = c1 & 0xffff;
! ud2 = (c1 & 0xffff0000) >> 16;
#if HOST_BITS_PER_WIDE_INT >= 64
! c2 = c1 >> 32;
#endif
+ ud3 = c2 & 0xffff;
+ ud4 = (c2 & 0xffff0000) >> 16;
! if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
! || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
{
! if (ud1 & 0x8000)
! emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
! else
! emit_move_insn (dest, GEN_INT (ud1));
}
! else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
! || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
! {
! if (ud2 & 0x8000)
! emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
! - 0x80000000));
! else
! emit_move_insn (dest, GEN_INT (ud2 << 16));
! if (ud1)
! emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
! }
! else if ((ud4 == 0xffff && (ud3 & 0x8000))
! || (ud4 == 0 && ! (ud3 & 0x8000)))
! {
! if (ud3 & 0x8000)
! emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
! - 0x80000000));
! else
! emit_move_insn (dest, GEN_INT (ud3 << 16));
! if (ud2)
! emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
! emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
! if (ud1)
! emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
! }
! else
{
! if (ud4 & 0x8000)
! emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
! - 0x80000000));
else
! emit_move_insn (dest, GEN_INT (ud4 << 16));
!
! if (ud3)
! emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
!
! emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
! if (ud2)
! emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
! GEN_INT (ud2 << 16)));
! if (ud1)
! emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
}
}
return dest;
}
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 long const take 3
2002-01-10 14:00 ` PATCH, rs6000 long const take 3 Tom Rix
@ 2002-01-10 14:08 ` Richard Henderson
2002-01-10 14:20 ` David Edelsohn
1 sibling, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-01-10 14:08 UTC (permalink / raw)
To: Tom Rix; +Cc: David Edelsohn, Geoff Keating, gcc-patches
On Thu, Jan 10, 2002 at 04:52:46PM -0600, Tom Rix wrote:
> Other than that they are evenly matched.
> I don't think there is enough of a win to check for the PLUS algorithm.
Depending on where this is used. If it is ever used in early rtl
generation, PLUS favours being merged with address loads.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PATCH, rs6000 long const take 3
2002-01-10 14:00 ` PATCH, rs6000 long const take 3 Tom Rix
2002-01-10 14:08 ` Richard Henderson
@ 2002-01-10 14:20 ` David Edelsohn
1 sibling, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-01-10 14:20 UTC (permalink / raw)
To: Tom Rix; +Cc: Geoff Keating, rth, gcc-patches
Yes, this looks okay, as long as you change
if (ud2)
to
if (ud2 != 0)
etc.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* ppc call_value* fixes (plus minor apple gripe)
@ 2002-01-28 1:05 Aldy Hernandez
2002-01-28 7:26 ` Stan Shebs
` (3 more replies)
0 siblings, 4 replies; 875+ messages in thread
From: Aldy Hernandez @ 2002-01-28 1:05 UTC (permalink / raw)
To: gcc-patches; +Cc: David Edelsohn, Stan Shebs
[-- Attachment #1: Type: text/plain, Size: 5474 bytes --]
<gripe>
both of the problems described here had obviously
been debugged and fixed by apple, and at least one of them was coded
after my altivec changes went in, so it would have been VERY simple
to submit the fix to the gcc list as well.
guys, if you have fixes in your local tree that are very obviously
correct,
and will undoubtedly be encountered by others, post them. it saves
the rest of us cycles that could be used to do other cool things in gcc
(and not spent re-fixing things that have already been fixed).
</gripe>
find_reloads was dying trying to fit the register constraints of
*call_value_nonlocal_sysv. the first operand needed a "v" constraint
added.
likewise for a couple more call_value* patterns. i didn't mess with the
AIX
call_value patterns because currently there is no AIX altivec, but i
could
add it if someone wants it.
i also added a new register class because find_reloads was picking the
wrong register for the pattern:
(define_insn "*call_value_nonlocal_sysv"
[(set (match_operand 0 "" "=fgv,fgv,fgv,fgv")
upon seeing f and g, the biggest subunion containing them was set to
NON_SPECIAL_REGS, then when it tried to get the union of that and
ALTIVEC_REGS it got confused. i noticed apple-gcc has moved
NON_SPECIAL_REGS before ALTIVEC_REGS to fix the problem, but
i believe the proper solution is to add a register class encompassing all
three register classes.
so... this patch:
a) fixes the call_value patterns to handle vector return values
b) adds GEN_OR_FLOAT_OR_ALTIVEC_REGS
ok?
2002-01-28 Aldy Hernandez <aldyh@redhat.com>
* config/rs6000/rs6000.h (reg_class): New class
GEN_OR_FLOAT_OR_ALTIVEC_REGS.
(REG_CLASS_NAMES): Same.
(REG_CLASS_CONTENTS): Same.
* rs6000.md ("*call_value_local32"): Support vector registers.
("*call_value_local64"): Same.
("*call_value_nonlocal_sysv"): Same.
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.176
diff -c -p -r1.176 rs6000.h
*** rs6000.h 2002/01/22 02:36:52 1.176
--- rs6000.h 2002/01/28 07:30:17
*************** enum reg_class
*** 1046,1051 ****
--- 1046,1052 ----
GENERAL_REGS,
FLOAT_REGS,
ALTIVEC_REGS,
+ GEN_OR_FLOAT_OR_ALTIVEC_REGS,
VRSAVE_REGS,
NON_SPECIAL_REGS,
MQ_REGS,
*************** enum reg_class
*** 1073,1078 ****
--- 1074,1080 ----
"GENERAL_REGS", \
"FLOAT_REGS", \
"ALTIVEC_REGS", \
+
"GEN_OR_FLOAT_OR_ALTIVEC_REGS", \
"VRSAVE_REGS", \
"NON_SPECIAL_REGS", \
"MQ_REGS", \
*************** enum reg_class
*** 1099,1104 ****
--- 1101,1107 ----
{ 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /*
GENERAL_REGS */ \
{ 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /*
FLOAT_REGS */ \
{ 0x00000000, 0x00000000, 0xffffe000, 0x00001fff }, /*
ALTIVEC_REGS */ \
+ { 0xffffffff, 0xffffffff, 0xffffe008, 0x00001fff }, /*
GEN_OR_FLOAT_OR_ALTIVEC_REGS */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00002000 }, /* VRSAVE_REGS */
\
{ 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /*
NON_SPECIAL_REGS */ \
{ 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */
\
Index: config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.161
diff -c -p -r1.161 rs6000.md
*** rs6000.md 2002/01/25 17:52:43 1.161
--- rs6000.md 2002/01/28 07:30:28
***************
*** 9878,9884 ****
(set_attr "length" "4,8")])
(define_insn "*call_value_local32"
! [(set (match_operand 0 "" "=fg,fg")
(call (mem:SI (match_operand:SI 1 "current_file_function_operand"
"s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
--- 9878,9884 ----
(set_attr "length" "4,8")])
(define_insn "*call_value_local32"
! [(set (match_operand 0 "" "=fgv,fgv")
(call (mem:SI (match_operand:SI 1 "current_file_function_operand"
"s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
***************
*** 9899,9905 ****
(define_insn "*call_value_local64"
! [(set (match_operand 0 "" "=fg,fg")
(call (mem:SI (match_operand:DI 1 "current_file_function_operand"
"s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
--- 9899,9905 ----
(define_insn "*call_value_local64"
! [(set (match_operand 0 "" "=fgv,fgv")
(call (mem:SI (match_operand:DI 1 "current_file_function_operand"
"s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
***************
*** 10067,10073 ****
(set_attr "length" "4,8,4,8")])
(define_insn "*call_value_nonlocal_sysv"
! [(set (match_operand 0 "" "=fg,fg,fg,fg")
(call (mem:SI (match_operand:SI 1 "call_operand" "cl,cl,s,s"))
(match_operand 2 "" "g,g,g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
--- 10067,10073 ----
(set_attr "length" "4,8,4,8")])
(define_insn "*call_value_nonlocal_sysv"
! [(set (match_operand 0 "" "=fgv,fgv,fgv,fgv")
(call (mem:SI (match_operand:SI 1 "call_operand" "cl,cl,s,s"))
(match_operand 2 "" "g,g,g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
[-- Attachment #2: Type: text/enriched, Size: 5615 bytes --]
<fontfamily><param>Helvetica</param><<gripe>
both of the problems described here had obviously
been debugged and fixed by apple, and at least one of them was coded
after my altivec changes went in, so it would have been VERY simple
to submit the fix to the gcc list as well.
guys, if you have fixes in your local tree that are very obviously
correct,
and will undoubtedly be encountered by others, post them. it saves
the rest of us cycles that could be used to do other cool things in
gcc
(and not spent re-fixing things that have already been fixed).
<</gripe>
find_reloads was dying trying to fit the register constraints of
*call_value_nonlocal_sysv. the first operand needed a "v" constraint
added.
likewise for a couple more call_value* patterns. i didn't mess with
the AIX
call_value patterns because currently there is no AIX altivec, but i
could
add it if someone wants it.
i also added a new register class because find_reloads was picking the
wrong register for the pattern:
(define_insn "*call_value_nonlocal_sysv"
[(set (match_operand 0 "" "=fgv,fgv,fgv,fgv")
upon seeing f and g, the biggest subunion containing them was set to
NON_SPECIAL_REGS, then when it tried to get the union of that and
ALTIVEC_REGS it got confused. i noticed apple-gcc has moved
NON_SPECIAL_REGS before ALTIVEC_REGS to fix the problem, but
i believe the proper solution is to add a register class encompassing
all
three register classes.
so... this patch:
a) fixes the call_value patterns to handle vector return values
b) adds GEN_OR_FLOAT_OR_ALTIVEC_REGS
ok?
2002-01-28 Aldy Hernandez <<aldyh@redhat.com>
* config/rs6000/rs6000.h (reg_class): New class
GEN_OR_FLOAT_OR_ALTIVEC_REGS.
(REG_CLASS_NAMES): Same.
(REG_CLASS_CONTENTS): Same.
* rs6000.md ("*call_value_local32"): Support vector registers.
("*call_value_local64"): Same.
("*call_value_nonlocal_sysv"): Same.
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.176
diff -c -p -r1.176 rs6000.h
*** rs6000.h 2002/01/22 02:36:52 1.176
--- rs6000.h 2002/01/28 07:30:17
*************** enum reg_class
*** 1046,1051 ****
--- 1046,1052 ----
GENERAL_REGS,
FLOAT_REGS,
ALTIVEC_REGS,
+ GEN_OR_FLOAT_OR_ALTIVEC_REGS,
VRSAVE_REGS,
NON_SPECIAL_REGS,
MQ_REGS,
*************** enum reg_class
*** 1073,1078 ****
--- 1074,1080 ----
"GENERAL_REGS", \
"FLOAT_REGS", \
"ALTIVEC_REGS", \
+ "GEN_OR_FLOAT_OR_ALTIVEC_REGS", \
"VRSAVE_REGS", \
"NON_SPECIAL_REGS", \
"MQ_REGS", \
*************** enum reg_class
*** 1099,1104 ****
--- 1101,1107 ----
{ 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /*
GENERAL_REGS */ \
{ 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS
*/ \
{ 0x00000000, 0x00000000, 0xffffe000, 0x00001fff }, /*
ALTIVEC_REGS */ \
+ { 0xffffffff, 0xffffffff, 0xffffe008, 0x00001fff }, /*
GEN_OR_FLOAT_OR_ALTIVEC_REGS */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00002000 }, /* VRSAVE_REGS
*/ \
{ 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /*
NON_SPECIAL_REGS */ \
{ 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */ \
Index: config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.161
diff -c -p -r1.161 rs6000.md
*** rs6000.md 2002/01/25 17:52:43 1.161
--- rs6000.md 2002/01/28 07:30:28
***************
*** 9878,9884 ****
(set_attr "length" "4,8")])
(define_insn "*call_value_local32"
! [(set (match_operand 0 "" "=fg,fg")
(call (mem:SI (match_operand:SI 1 "current_file_function_operand"
"s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
--- 9878,9884 ----
(set_attr "length" "4,8")])
(define_insn "*call_value_local32"
! [(set (match_operand 0 "" "=fgv,fgv")
(call (mem:SI (match_operand:SI 1 "current_file_function_operand"
"s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
***************
*** 9899,9905 ****
(define_insn "*call_value_local64"
! [(set (match_operand 0 "" "=fg,fg")
(call (mem:SI (match_operand:DI 1 "current_file_function_operand"
"s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
--- 9899,9905 ----
(define_insn "*call_value_local64"
! [(set (match_operand 0 "" "=fgv,fgv")
(call (mem:SI (match_operand:DI 1 "current_file_function_operand"
"s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
***************
*** 10067,10073 ****
(set_attr "length" "4,8,4,8")])
(define_insn "*call_value_nonlocal_sysv"
! [(set (match_operand 0 "" "=fg,fg,fg,fg")
(call (mem:SI (match_operand:SI 1 "call_operand" "cl,cl,s,s"))
(match_operand 2 "" "g,g,g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
--- 10067,10073 ----
(set_attr "length" "4,8,4,8")])
(define_insn "*call_value_nonlocal_sysv"
! [(set (match_operand 0 "" "=fgv,fgv,fgv,fgv")
(call (mem:SI (match_operand:SI 1 "call_operand" "cl,cl,s,s"))
(match_operand 2 "" "g,g,g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
</fontfamily>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: ppc call_value* fixes (plus minor apple gripe)
2002-01-28 1:05 ppc call_value* fixes (plus minor apple gripe) Aldy Hernandez
@ 2002-01-28 7:26 ` Stan Shebs
2002-01-29 14:30 ` Aldy Hernandez
2002-01-28 7:43 ` Geoff Keating
` (2 subsequent siblings)
3 siblings, 1 reply; 875+ messages in thread
From: Stan Shebs @ 2002-01-28 7:26 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: gcc-patches, David Edelsohn
Aldy Hernandez wrote:
>
> <gripe>
> both of the problems described here had obviously
> been debugged and fixed by apple, and at least one of them was coded
> after my altivec changes went in, so it would have been VERY simple
> to submit the fix to the gcc list as well.
Unfortunately, our actual experience over the past year has been
otherwise - a certain amount of time has to be set aside for
nitpicking and debate over even the apparently straightforward
changes. I'm not griping (OK, a little :-) ), but it's clearly
not a zero-cost activity.
> guys, if you have fixes in your local tree that are very obviously correct,
> and will undoubtedly be encountered by others, post them. it saves
> the rest of us cycles that could be used to do other cool things in gcc
> (and not spent re-fixing things that have already been fixed).
> </gripe>
Sorry - as you know, the Apple version has many local differences,
particularly for AltiVec code, and any submission candidate patch
needs a whole separate round of testing with FSF sources, to be sure
that the patch does not depend on any of our local changes that have
been deemed permanently unacceptable for FSF GCC.
> [...] i noticed apple-gcc has moved
> NON_SPECIAL_REGS before ALTIVEC_REGS to fix the problem, but
> i believe the proper solution is to add a register class encompassing all
> three register classes.
This is a perfect example - I did something expedient, basically
to get our version working again after an import of FSF code,
but was pretty sure it was wrong, and I didn't want to submit
a hack that I couldn't justify. Worse, since the patch only
mattered if one had more complete AltiVec support than was in
FSF GCC at the time, there was no way to validate it or any
better patch using only FSF code.
I can assure you that the parallel maintenance of versions consumes
way more of my personal time and effort than anybody else's, so I
totally sympathize when there is evidence that it is inefficient.
But Apple is not going to give up its requirements for GCC just
because they're not desired in FSF GCC, nor vice versa, so we live
with the permanent fork instead.
Stan
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: ppc call_value* fixes (plus minor apple gripe)
2002-01-28 1:05 ppc call_value* fixes (plus minor apple gripe) Aldy Hernandez
2002-01-28 7:26 ` Stan Shebs
@ 2002-01-28 7:43 ` Geoff Keating
2002-01-28 7:49 ` David Edelsohn
2002-01-28 11:12 ` Richard Henderson
3 siblings, 0 replies; 875+ messages in thread
From: Geoff Keating @ 2002-01-28 7:43 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: gcc-patches
Aldy Hernandez <aldyh@redhat.com> writes:
...
> i also added a new register class because find_reloads was picking the
> wrong register for the pattern:
>
> (define_insn "*call_value_nonlocal_sysv"
> [(set (match_operand 0 "" "=fgv,fgv,fgv,fgv")
>
> upon seeing f and g, the biggest subunion containing them was set to
> NON_SPECIAL_REGS, then when it tried to get the union of that and
> ALTIVEC_REGS it got confused. i noticed apple-gcc has moved
> NON_SPECIAL_REGS before ALTIVEC_REGS to fix the problem, but
> i believe the proper solution is to add a register class encompassing
> all
> three register classes.
>
> so... this patch:
> a) fixes the call_value patterns to handle vector return
That part is OK, although of course it won't work without the next bit.
> values
> b) adds GEN_OR_FLOAT_OR_ALTIVEC_REGS
>
> ok?
Could you change the name of NON_SPECIAL_REGS too? I don't think the
altivec registers are "special" in that sense...
Actually, I think it'd probably be better to create a
GEN_OR_FLOAT_REGS class, and then make NON_SPECIAL_REGS contain
altivec registers too. There are two places where NON_SPECIAL_REGS is
used, in PREFERRED_RELOAD_CLASS and secondary_reload_class; the
secondary_reload_class case should be
(regno == -1 || FP_REGNO_P (regno)) && reg_class_subset_p (FLOAT_REGS, class)
and for PREFERRED_RELOAD_CLASS, you probably want to add a
GEN_OR_ALTIVEC_REGS and use that.
> 2002-01-28 Aldy Hernandez <aldyh@redhat.com>
>
> * config/rs6000/rs6000.h (reg_class): New class
> GEN_OR_FLOAT_OR_ALTIVEC_REGS.
> (REG_CLASS_NAMES): Same.
> (REG_CLASS_CONTENTS): Same.
>
> * rs6000.md ("*call_value_local32"): Support vector registers.
> ("*call_value_local64"): Same.
> ("*call_value_nonlocal_sysv"): Same.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: ppc call_value* fixes (plus minor apple gripe)
2002-01-28 1:05 ppc call_value* fixes (plus minor apple gripe) Aldy Hernandez
2002-01-28 7:26 ` Stan Shebs
2002-01-28 7:43 ` Geoff Keating
@ 2002-01-28 7:49 ` David Edelsohn
2002-01-28 11:12 ` Richard Henderson
3 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-01-28 7:49 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: gcc-patches, Stan Shebs
2002-01-28 Aldy Hernandez <aldyh@redhat.com>
* config/rs6000/rs6000.h (reg_class): New class
GEN_OR_FLOAT_OR_ALTIVEC_REGS.
(REG_CLASS_NAMES): Same.
(REG_CLASS_CONTENTS): Same.
* rs6000.md ("*call_value_local32"): Support vector registers.
("*call_value_local64"): Same.
("*call_value_nonlocal_sysv"): Same.
This patch is fine.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: ppc call_value* fixes (plus minor apple gripe)
2002-01-28 1:05 ppc call_value* fixes (plus minor apple gripe) Aldy Hernandez
` (2 preceding siblings ...)
2002-01-28 7:49 ` David Edelsohn
@ 2002-01-28 11:12 ` Richard Henderson
2002-01-28 12:52 ` David Edelsohn
2002-01-28 22:44 ` Aldy Hernandez
3 siblings, 2 replies; 875+ messages in thread
From: Richard Henderson @ 2002-01-28 11:12 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: gcc-patches, David Edelsohn, Stan Shebs
On Mon, Jan 28, 2002 at 06:33:00PM +1100, Aldy Hernandez wrote:
> (define_insn "*call_value_local32"
> - [(set (match_operand 0 "" "=fg,fg")
> + [(set (match_operand 0 "" "=fgv,fgv")
This is silly. This operand will _always_ be a hard reg right
from the beginning of code generation. This should be written
(match_operand 0 "" "")
so that reload does nothing with it at all.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: ppc call_value* fixes (plus minor apple gripe)
2002-01-28 11:12 ` Richard Henderson
@ 2002-01-28 12:52 ` David Edelsohn
2002-01-28 22:44 ` Aldy Hernandez
1 sibling, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-01-28 12:52 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: gcc-patches, Stan Shebs
The output constraints on call_value have been around for a very
long time. If we remove them, we need to remove them from all call_value
patterns.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: ppc call_value* fixes (plus minor apple gripe)
2002-01-28 11:12 ` Richard Henderson
2002-01-28 12:52 ` David Edelsohn
@ 2002-01-28 22:44 ` Aldy Hernandez
2002-01-29 10:51 ` David Edelsohn
1 sibling, 1 reply; 875+ messages in thread
From: Aldy Hernandez @ 2002-01-28 22:44 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches, David Edelsohn, Stan Shebs
> This is silly. This operand will _always_ be a hard reg right
> from the beginning of code generation. This should be written
>
> (match_operand 0 "" "")
>
> so that reload does nothing with it at all.
weee!!!
ok, here's the new patch. regression tested on darwin.
david, i fixed all the call_value patterns.
ok?
--
Aldy Hernandez E-mail: aldyh@redhat.com
Professional Gypsy Lost in Australia
Red Hat, Inc.
2002-01-29 Aldy Hernandez <aldyh@redhat.com>
* rs6000.md ("*call_value_local32"): Remove constraints.
("*call_value_local64"): Same.
("*call_value_indirect_nonlocal_aix32"): Same.
("*call_value_nonlocal_aix32"): Same.
("*call_value_indirect_nonlocal_aix64"): Same.
("*call_value_nonlocal_aix64"): Same.
("*call_value_nonlocal_sysv"): Same.
Index: config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.161
diff -c -p -r1.161 rs6000.md
*** rs6000.md 2002/01/25 17:52:43 1.161
--- rs6000.md 2002/01/29 05:50:23
***************
*** 9878,9884 ****
(set_attr "length" "4,8")])
(define_insn "*call_value_local32"
! [(set (match_operand 0 "" "=fg,fg")
(call (mem:SI (match_operand:SI 1 "current_file_function_operand"
"s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
--- 9878,9884 ----
(set_attr "length" "4,8")])
(define_insn "*call_value_local32"
! [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "current_file_function_operand"
"s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
***************
*** 9899,9905 ****
(define_insn "*call_value_local64"
! [(set (match_operand 0 "" "=fg,fg")
(call (mem:SI (match_operand:DI 1 "current_file_function_operand"
"s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
--- 9899,9905 ----
(define_insn "*call_value_local64"
! [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:DI 1 "current_file_function_operand"
"s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
***************
*** 9976,9982 ****
(set_attr "length" "8")])
(define_insn "*call_value_indirect_nonlocal_aix32"
! [(set (match_operand 0 "" "=fg")
(call (mem:SI (match_operand:SI 1 "register_operand" "cl"))
(match_operand 2 "" "g")))
(use (reg:SI 2))
--- 9976,9982 ----
(set_attr "length" "8")])
(define_insn "*call_value_indirect_nonlocal_aix32"
! [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "register_operand" "cl"))
(match_operand 2 "" "g")))
(use (reg:SI 2))
***************
*** 9990,9996 ****
(set_attr "length" "8")])
(define_insn "*call_value_nonlocal_aix32"
! [(set (match_operand 0 "" "=fg")
(call (mem:SI (match_operand:SI 1 "call_operand" "s"))
(match_operand 2 "" "g")))
(use (match_operand:SI 3 "immediate_operand" "O"))
--- 9990,9996 ----
(set_attr "length" "8")])
(define_insn "*call_value_nonlocal_aix32"
! [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "call_operand" "s"))
(match_operand 2 "" "g")))
(use (match_operand:SI 3 "immediate_operand" "O"))
***************
*** 10003,10009 ****
(set_attr "length" "8")])
(define_insn "*call_value_indirect_nonlocal_aix64"
! [(set (match_operand 0 "" "=fg")
(call (mem:SI (match_operand:DI 1 "register_operand" "cl"))
(match_operand 2 "" "g")))
(use (reg:DI 2))
--- 10003,10009 ----
(set_attr "length" "8")])
(define_insn "*call_value_indirect_nonlocal_aix64"
! [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:DI 1 "register_operand" "cl"))
(match_operand 2 "" "g")))
(use (reg:DI 2))
***************
*** 10017,10023 ****
(set_attr "length" "8")])
(define_insn "*call_value_nonlocal_aix64"
! [(set (match_operand 0 "" "=fg")
(call (mem:SI (match_operand:DI 1 "call_operand" "s"))
(match_operand 2 "" "g")))
(use (match_operand:SI 3 "immediate_operand" "O"))
--- 10017,10023 ----
(set_attr "length" "8")])
(define_insn "*call_value_nonlocal_aix64"
! [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:DI 1 "call_operand" "s"))
(match_operand 2 "" "g")))
(use (match_operand:SI 3 "immediate_operand" "O"))
***************
*** 10067,10073 ****
(set_attr "length" "4,8,4,8")])
(define_insn "*call_value_nonlocal_sysv"
! [(set (match_operand 0 "" "=fg,fg,fg,fg")
(call (mem:SI (match_operand:SI 1 "call_operand" "cl,cl,s,s"))
(match_operand 2 "" "g,g,g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
--- 10067,10073 ----
(set_attr "length" "4,8,4,8")])
(define_insn "*call_value_nonlocal_sysv"
! [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "call_operand" "cl,cl,s,s"))
(match_operand 2 "" "g,g,g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: ppc call_value* fixes (plus minor apple gripe)
2002-01-28 22:44 ` Aldy Hernandez
@ 2002-01-29 10:51 ` David Edelsohn
0 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-01-29 10:51 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: Richard Henderson, gcc-patches, Stan Shebs
2002-01-29 Aldy Hernandez <aldyh@redhat.com>
* rs6000.md ("*call_value_local32"): Remove constraints.
("*call_value_local64"): Same.
("*call_value_indirect_nonlocal_aix32"): Same.
("*call_value_nonlocal_aix32"): Same.
("*call_value_indirect_nonlocal_aix64"): Same.
("*call_value_nonlocal_aix64"): Same.
("*call_value_nonlocal_sysv"): Same.
This patch looks okay and works so far in my preliminary test.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: ppc call_value* fixes (plus minor apple gripe)
2002-01-28 7:26 ` Stan Shebs
@ 2002-01-29 14:30 ` Aldy Hernandez
0 siblings, 0 replies; 875+ messages in thread
From: Aldy Hernandez @ 2002-01-29 14:30 UTC (permalink / raw)
To: Stan Shebs; +Cc: gcc-patches, David Edelsohn
> Unfortunately, our actual experience over the past year has been
> otherwise - a certain amount of time has to be set aside for
> nitpicking and debate over even the apparently straightforward
> changes. I'm not griping (OK, a little :-) ), but it's clearly
> not a zero-cost activity.
yes, i am aware it takes a lot extra-hours work time.
perhaps, if you know it's something that will definitely have
to be fixed later, distill a small testcase and mail it to me.
> because they're not desired in FSF GCC, nor vice versa, so we live
> with the permanent fork instead.
forked trees? we have the mother of all forked trees here at
redhat. :)
--
Aldy Hernandez E-mail: aldyh@redhat.com
Professional Gypsy Lost in Australia
Red Hat, Inc.
^ permalink raw reply [flat|nested] 875+ messages in thread
* [PATCH] PowerPC fsel PR5217
@ 2002-02-03 19:14 David Edelsohn
2002-02-03 21:14 ` Geoff Keating
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-02-03 19:14 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
This problem seems to be a mismatch between the mode of the
if_then_else in the generated RTL versus the machine description. I think
this mixed mode pattern only can be generated by GCC internally, not any
machine description pattern, so we might as well follow the canonical
modes that GCC chooses.
Does this seem correct to you, Geoff? Or should the if_then_else
be the other mode?
David
Index: rs6000.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.162
diff -c -p -r1.162 rs6000.md
*** rs6000.md 2002/01/29 22:49:55 1.162
--- rs6000.md 2002/02/04 00:46:26
***************
*** 5084,5090 ****
(define_insn "*fseldfsf4"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
! (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
(match_operand:DF 4 "zero_fp_constant" "F"))
(match_operand:SF 2 "gpc_reg_operand" "f")
(match_operand:SF 3 "gpc_reg_operand" "f")))]
--- 5084,5090 ----
(define_insn "*fseldfsf4"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
! (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
(match_operand:DF 4 "zero_fp_constant" "F"))
(match_operand:SF 2 "gpc_reg_operand" "f")
(match_operand:SF 3 "gpc_reg_operand" "f")))]
***************
*** 5248,5254 ****
(define_insn "*fselsfdf4"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
! (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
(match_operand:SF 4 "zero_fp_constant" "F"))
(match_operand:DF 2 "gpc_reg_operand" "f")
(match_operand:DF 3 "gpc_reg_operand" "f")))]
--- 5248,5254 ----
(define_insn "*fselsfdf4"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
! (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
(match_operand:SF 4 "zero_fp_constant" "F"))
(match_operand:DF 2 "gpc_reg_operand" "f")
(match_operand:DF 3 "gpc_reg_operand" "f")))]
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] PowerPC fsel PR5217
2002-02-03 19:14 [PATCH] PowerPC fsel PR5217 David Edelsohn
@ 2002-02-03 21:14 ` Geoff Keating
2002-02-03 21:40 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-02-03 21:14 UTC (permalink / raw)
To: dje; +Cc: gcc-patches
> cc: gcc-patches@gcc.gnu.org
> Date: Sun, 03 Feb 2002 19:57:07 -0500
> From: David Edelsohn <dje@watson.ibm.com>
>
> This problem seems to be a mismatch between the mode of the
> if_then_else in the generated RTL versus the machine description. I think
> this mixed mode pattern only can be generated by GCC internally, not any
> machine description pattern, so we might as well follow the canonical
> modes that GCC chooses.
>
> Does this seem correct to you, Geoff? Or should the if_then_else
> be the other mode?
The patterns you're changing seem to have been correct originally.
The IF_THEN_ELSE should have the same mode as the two alternatives and
the same mode as the destination of the SET, correct?
> (define_insn "*fseldfsf4"
> [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
> ! (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
> (match_operand:DF 4 "zero_fp_constant" "F"))
> (match_operand:SF 2 "gpc_reg_operand" "f")
> (match_operand:SF 3 "gpc_reg_operand" "f")))]
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] PowerPC fsel PR5217
2002-02-03 21:14 ` Geoff Keating
@ 2002-02-03 21:40 ` David Edelsohn
2002-02-03 22:08 ` Geoff Keating
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-02-03 21:40 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
>>>>> Geoff Keating writes:
Geoff> The patterns you're changing seem to have been correct originally.
Geoff> The IF_THEN_ELSE should have the same mode as the two alternatives and
Geoff> the same mode as the destination of the SET, correct?
This is what I am not sure about. I am pretty sure that I created
those patterns because GCC was not generating fsel for those mixed cases.
I am pretty sure that I created the patterns to match what GCC was
generating, not because the RTL was canonically correct.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] PowerPC fsel PR5217
2002-02-03 21:40 ` David Edelsohn
@ 2002-02-03 22:08 ` Geoff Keating
2002-02-03 22:45 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-02-03 22:08 UTC (permalink / raw)
To: dje; +Cc: gcc-patches
> cc: gcc-patches@gcc.gnu.org
> Date: Sun, 03 Feb 2002 23:50:12 -0500
> From: David Edelsohn <dje@watson.ibm.com>
>
> >>>>> Geoff Keating writes:
>
> Geoff> The patterns you're changing seem to have been correct originally.
> Geoff> The IF_THEN_ELSE should have the same mode as the two alternatives and
> Geoff> the same mode as the destination of the SET, correct?
>
> This is what I am not sure about. I am pretty sure that I created
> those patterns because GCC was not generating fsel for those mixed cases.
> I am pretty sure that I created the patterns to match what GCC was
> generating, not because the RTL was canonically correct.
In ifcvt.c, there is:
tmp = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), cmp_a, cmp_b);
tmp = gen_rtx_IF_THEN_ELSE (GET_MODE (x), tmp, vtrue, vfalse);
tmp = gen_rtx_SET (VOIDmode, x, tmp);
which generates an IF_THEN_ELSE with the same mode as the destination
of the SET.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] PowerPC fsel PR5217
2002-02-03 22:08 ` Geoff Keating
@ 2002-02-03 22:45 ` David Edelsohn
2002-02-03 23:14 ` Geoff Keating
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-02-03 22:45 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
>>>>> Geoff Keating writes:
Geoff> tmp = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), cmp_a, cmp_b);
Geoff> tmp = gen_rtx_IF_THEN_ELSE (GET_MODE (x), tmp, vtrue, vfalse);
Geoff> tmp = gen_rtx_SET (VOIDmode, x, tmp);
Geoff> which generates an IF_THEN_ELSE with the same mode as the destination
Geoff> of the SET.
combine.c uses VOIDmode and cselib.c appears to use the mode of
the source:
src = gen_rtx_IF_THEN_ELSE (GET_MODE (src), cond, src, dest);
which is what my pattern matches.
So the question is which way do we want to canonicalize this?
Then we can document it and match the decision in the PowerPC port.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] PowerPC fsel PR5217
2002-02-03 22:45 ` David Edelsohn
@ 2002-02-03 23:14 ` Geoff Keating
2002-02-04 9:26 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-02-03 23:14 UTC (permalink / raw)
To: dje; +Cc: gcc-patches
> cc: gcc-patches@gcc.gnu.org
> Date: Mon, 04 Feb 2002 00:14:23 -0500
> From: David Edelsohn <dje@watson.ibm.com>
>
> >>>>> Geoff Keating writes:
>
> Geoff> tmp = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), cmp_a, cmp_b);
> Geoff> tmp = gen_rtx_IF_THEN_ELSE (GET_MODE (x), tmp, vtrue, vfalse);
> Geoff> tmp = gen_rtx_SET (VOIDmode, x, tmp);
>
> Geoff> which generates an IF_THEN_ELSE with the same mode as the destination
> Geoff> of the SET.
>
> combine.c uses VOIDmode and cselib.c appears to use the mode of
> the source:
>
> src = gen_rtx_IF_THEN_ELSE (GET_MODE (src), cond, src, dest);
>
> which is what my pattern matches.
Um... In your patch, you had
***************
*** 5084,5090 ****
(define_insn "*fseldfsf4"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
! (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
(match_operand:DF 4 "zero_fp_constant" "F"))
(match_operand:SF 2 "gpc_reg_operand" "f")
(match_operand:SF 3 "gpc_reg_operand" "f")))]
--- 5084,5090 ----
(define_insn "*fseldfsf4"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
! (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
(match_operand:DF 4 "zero_fp_constant" "F"))
(match_operand:SF 2 "gpc_reg_operand" "f")
(match_operand:SF 3 "gpc_reg_operand" "f")))]
In this case, 'src' is '(match_operand:SF 2 "gpc_reg_operand" "f")',
and has mode SFmode.
> So the question is which way do we want to canonicalize this?
> Then we can document it and match the decision in the PowerPC port.
We certainly want the mode of the IF_THEN_ELSE to be the mode of the
value it produces; this is how almost all other RTL is done. VOIDmode
would just be annoying.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] PowerPC fsel PR5217
2002-02-03 23:14 ` Geoff Keating
@ 2002-02-04 9:26 ` David Edelsohn
2002-02-04 10:24 ` Geoff Keating
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-02-04 9:26 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
I do not understand your reply. The current version of the
pattern expects the MODE of IF_THEN_ELSE to match the source. The code in
cselib.c creates IF_THEN_ELSE with the MODE based on src, not on cond. I
am not saying it is correct.
My patch changes the MODE of IF_THEN_ELSE to match the condition,
which is what the code in ifcvt.c creates. The purpose of my patch was to
create a strawman to start a discussion because I have been harshly
criticized before when simply asking for guidance without a patch.
Changing the pattern without having GCC consistently generating
matching RTL is not effective. If the canonical form should have the MODE
match the condition, then cselib.c appears that it should be changed.
I am reporting facts of contradictions within GCC, not making
recommendations. I am asking for people familiar with this code and this
design to give some advice and help make the necessary changes in the
common parts of GCC.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] PowerPC fsel PR5217
2002-02-04 9:26 ` David Edelsohn
@ 2002-02-04 10:24 ` Geoff Keating
2002-02-04 10:40 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-02-04 10:24 UTC (permalink / raw)
To: dje; +Cc: gcc-patches
> cc: gcc-patches@gcc.gnu.org
> Date: Mon, 04 Feb 2002 12:10:09 -0500
> From: David Edelsohn <dje@watson.ibm.com>
>
> I do not understand your reply. The current version of the
> pattern expects the MODE of IF_THEN_ELSE to match the source. The code in
> cselib.c creates IF_THEN_ELSE with the MODE based on src, not on cond. I
> am not saying it is correct.
>
> My patch changes the MODE of IF_THEN_ELSE to match the condition,
> which is what the code in ifcvt.c creates.
This is what I am trying to say:
On my reading, ifcvt.c does not create IF_THEN_ELSE RTL in which the
mode of the IF_THEN_ELSE matches the condition.
Why do you think that it does?
I think it doesn't because in this chunk of code from ifcvt.c:
tmp = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), cmp_a, cmp_b);
tmp = gen_rtx_IF_THEN_ELSE (GET_MODE (x), tmp, vtrue, vfalse);
tmp = gen_rtx_SET (VOIDmode, x, tmp);
the mode of the condition will be GET_MODE (if_info->cond), but
the IF_THEN_ELSE is created with mode GET_MODE (x).
Since GET_MODE(x) and GET_MODE(vtrue) and GET_MODE(vfalse) should be
the same thing (unless vtrue or vfalse are CONST_INTs), that makes
this code equivalent to the code in cselib.c:
src = gen_rtx_IF_THEN_ELSE (GET_MODE (src), cond, src, dest);
... except in the case where 'src' has VOIDmode, which is probably a
bug in cselib.c. It should really be using GET_MODE (dest) which we
know isn't a CONST_INT.
> The purpose of my patch was to
> create a strawman to start a discussion because I have been harshly
> criticized before when simply asking for guidance without a patch.
Yes, your patch was very helpful. It indicated that we're somehow
talking at cross purposes.
> Changing the pattern without having GCC consistently generating
> matching RTL is not effective.
Yes, I agree. GCC should be generating the correct RTL.
> If the canonical form should have the MODE
> match the condition, then cselib.c appears that it should be
> changed.
It certainly shouldn't be matching the condition. It should be
matching the mode of the result of the IF_THEN_ELSE.
> I am reporting facts of contradictions within GCC, not making
> recommendations. I am asking for people familiar with this code and this
> design to give some advice and help make the necessary changes in the
> common parts of GCC.
I hope I am being helpful...
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] PowerPC fsel PR5217
2002-02-04 10:24 ` Geoff Keating
@ 2002-02-04 10:40 ` David Edelsohn
2002-02-04 11:18 ` Dale Johannesen
2002-02-04 11:44 ` Geoff Keating
0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2002-02-04 10:40 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
I somehow thought you were saying that ifcvt.c uses the mode of
the operands of the condition, sorry.
So this patch should be all that is necessary. Do you have any
objection to the patch?
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] PowerPC fsel PR5217
2002-02-04 10:40 ` David Edelsohn
@ 2002-02-04 11:18 ` Dale Johannesen
2002-02-04 11:44 ` Geoff Keating
1 sibling, 0 replies; 875+ messages in thread
From: Dale Johannesen @ 2002-02-04 11:18 UTC (permalink / raw)
To: David Edelsohn; +Cc: Dale Johannesen, Geoff Keating, gcc-patches
This earlier fix
http://gcc.gnu.org/ml/gcc-patches/2001-11/msg00236.html
is related, but it seems I did not fix the entire problem.
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] PowerPC fsel PR5217
2002-02-04 10:40 ` David Edelsohn
2002-02-04 11:18 ` Dale Johannesen
@ 2002-02-04 11:44 ` Geoff Keating
2002-02-05 11:20 ` David Edelsohn
1 sibling, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-02-04 11:44 UTC (permalink / raw)
To: dje; +Cc: gcc-patches
> cc: gcc-patches@gcc.gnu.org
> Date: Mon, 04 Feb 2002 13:24:31 -0500
> From: David Edelsohn <dje@watson.ibm.com>
>
> I somehow thought you were saying that ifcvt.c uses the mode of
> the operands of the condition, sorry.
>
> So this patch should be all that is necessary. Do you have any
> objection to the patch?
The patch does exactly the opposite thing to what I was recommending!
Did you perhaps generate it reversed?
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] PowerPC fsel PR5217
2002-02-04 11:44 ` Geoff Keating
@ 2002-02-05 11:20 ` David Edelsohn
2002-02-05 12:47 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-02-05 11:20 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
Okay, so those patterns already are correct. The problem is that
something in GCC is generating
(set (reg:SF)
(if_then_else:DF (ge (reg:DF)
(const_double:DF 0)
(reg:SF)
(reg:SF))))
Note that the if_then_else:DF. This only exists in gcc-3.0 branch.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] PowerPC fsel PR5217
2002-02-05 11:20 ` David Edelsohn
@ 2002-02-05 12:47 ` David Edelsohn
2002-02-05 14:17 ` Mark Mitchell
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-02-05 12:47 UTC (permalink / raw)
To: Geoff Keating, Mark Mitchell; +Cc: gcc-patches
So the problem is probably that the GET_MODE (dest) patch was not
back-ported to the GCC-3.0 branch.
http://gcc.gnu.org/ml/gcc-patches/2001-11/msg00236.html
2001-11-05 Dale Johannesen <dalej@apple.com>
* config/rs6000/rs6000.c (rs6000_emit_cmove): Derive mode
of the IF_THEN_ELSE from the result, not the operands.
Mark: may this patch be back-ported to GCC 3.0 branch?
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] PowerPC fsel PR5217
2002-02-05 12:47 ` David Edelsohn
@ 2002-02-05 14:17 ` Mark Mitchell
0 siblings, 0 replies; 875+ messages in thread
From: Mark Mitchell @ 2002-02-05 14:17 UTC (permalink / raw)
To: David Edelsohn, Geoff Keating; +Cc: gcc-patches
--On Tuesday, February 05, 2002 03:27:00 PM -0500 David Edelsohn
<dje@watson.ibm.com> wrote:
> So the problem is probably that the GET_MODE (dest) patch was not
> back-ported to the GCC-3.0 branch.
Yes, it's fine to apply this patch.
Thanks,
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
^ permalink raw reply [flat|nested] 875+ messages in thread
* f build dies with: undefined reference to `lookup_name'
@ 2002-03-06 6:54 Andrew Cagney
2002-03-06 8:29 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Andrew Cagney @ 2002-03-06 6:54 UTC (permalink / raw)
To: gcc-patches
Hello,
I'm trying to get some patches committed but am finding that my build
dies in while building fortran with:
gcc -DIN_GCC -g -O -W -Wall -Wwrite-strings -Wstrict-prototypes
-Wmissing-prototypes -Wtraditional -pedantic -Wno-long-long
-DHAVE_CONFIG_H -o f771 f/bad.o f/bit.o f/bld.o f/com.o f/data.o
f/equiv.o f/expr.o f/global.o f/implic.o f/info.o f/intrin.o f/lab.o
f/lex.o f/malloc.o f/name.o f/parse.o f/src.o f/st.o f/sta.o f/stb.o
f/stc.o f/std.o f/ste.o f/storag.o f/stp.o f/str.o f/sts.o f/stt.o
f/stu.o f/stv.o f/stw.o f/symbol.o f/target.o f/top.o f/type.o
f/version.o f/where.o main.o libbackend.a ../libiberty/libiberty.a
libbackend.a(varasm.o): In function `weak_finish':
/home/scratch/PENDING/GCC-2002-02-02-switch-default/gcc/gcc/varasm.c:5111:
undefined reference to `lookup_name'
on a powerpc-unknown-netbsd1.5ZA native build.
I suspect this change:
2002-03-01 Alan Modra <amodra@bigpond.net.au>
David Edelsohn <edelsohn@gnu.org>
.....
(weak_finish): Use ASM_WEAKEN_DECL. Try to find decl.
(remove_from_pending_weak_list): Declare and define for
ASM_WEAKEN_DECL.
Andrew
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 6:54 f build dies with: undefined reference to `lookup_name' Andrew Cagney
@ 2002-03-06 8:29 ` David Edelsohn
2002-03-06 8:53 ` Andrew Cagney
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-03-06 8:29 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gcc-patches
I'm trying to get some patches committed but am finding that my build
dies in while building fortran with:
/home/scratch/PENDING/GCC-2002-02-02-switch-default/gcc/gcc/varasm.c:5111:
undefined reference to `lookup_name'
The patch works on Linux and AIX and eABI. What is different
about the NetBSD configuration? The function is declared in c-tree.h and
defined in c-decl.c.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 8:29 ` David Edelsohn
@ 2002-03-06 8:53 ` Andrew Cagney
2002-03-06 10:18 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Andrew Cagney @ 2002-03-06 8:53 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
>> I'm trying to get some patches committed but am finding that my build
>> dies in while building fortran with:
>> /home/scratch/PENDING/GCC-2002-02-02-switch-default/gcc/gcc/varasm.c:5111:
>> undefined reference to `lookup_name'
>
> The patch works on Linux and AIX and eABI. What is different
> about the NetBSD configuration? The function is declared in c-tree.h and
> defined in c-decl.c.
Fortran? The archive libbackend.a (which the fortran compiler linked
against) contains varasm.o but not contain c-decl.o. Looking at
gcc/Makefile.in, C_AND_OBJC_OBJS includes c-decl.o but OBJS (used for
libbackend.a) does not.
Andrew
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 8:53 ` Andrew Cagney
@ 2002-03-06 10:18 ` David Edelsohn
2002-03-06 10:59 ` Richard Henderson
2002-03-06 11:43 ` Stan Shebs
0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2002-03-06 10:18 UTC (permalink / raw)
To: Andrew Cagney, Alan Modra, Richard Henderson; +Cc: gcc-patches
>>>>> Andrew Cagney writes:
Andrew> Fortran? The archive libbackend.a (which the fortran compiler linked
Andrew> against) contains varasm.o but not contain c-decl.o. Looking at
Andrew> gcc/Makefile.in, C_AND_OBJC_OBJS includes c-decl.o but OBJS (used for
Andrew> libbackend.a) does not.
I am surprised that this did not cause any bootstrap problems
during all of the testing.
The problem appears to be that all of the pragma and weak support
is in varasm.c, but it only is needed for C-like languages. Because this
is tied with varasm, I don't think that one can separate it out into a
file only compiled for C-like languages.
varasm.c includes c-tree.h, so there was no reason to believe that
those symbols were not safe.
gcc/cp/decl.c defines lookup_name, but with an extra parameter
which currently is random garbage when this is used from the C++
front-end. Sigh.
gcc/f/com.c defines lookup_name_current_level, but not
lookup_name, copied directly from c-decl.c (even the comment referring to
lookup_name!)
I think that one needs to define lookup_name in each language or
define a similar function in common code included in libbackend.a. I
don't see how one can avoid referencing some symbol from varasm.c, even if
it never is called for some languages.
Maybe someone else has a better idea which I am missing.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 10:18 ` David Edelsohn
@ 2002-03-06 10:59 ` Richard Henderson
2002-03-06 11:27 ` David Edelsohn
` (3 more replies)
2002-03-06 11:43 ` Stan Shebs
1 sibling, 4 replies; 875+ messages in thread
From: Richard Henderson @ 2002-03-06 10:59 UTC (permalink / raw)
To: David Edelsohn; +Cc: Andrew Cagney, Alan Modra, gcc-patches
On Wed, Mar 06, 2002 at 01:17:59PM -0500, David Edelsohn wrote:
> I think that one needs to define lookup_name in each language or
> define a similar function in common code included in libbackend.a. I
> don't see how one can avoid referencing some symbol from varasm.c, even if
> it never is called for some languages.
>
> Maybe someone else has a better idea which I am missing.
You can't look up decls from varasm.c. You have to have
them passed down to you.
And you're right. All the queueing of identifiers should
probably happen in c-common.c or something.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 10:59 ` Richard Henderson
@ 2002-03-06 11:27 ` David Edelsohn
2002-03-06 12:41 ` Richard Henderson
2002-03-06 15:40 ` David Edelsohn
` (2 subsequent siblings)
3 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-03-06 11:27 UTC (permalink / raw)
To: Richard Henderson, Andrew Cagney, Alan Modra, gcc-patches
>>>>> Richard Henderson writes:
Richard> You can't look up decls from varasm.c. You have to have
Richard> them passed down to you.
The whole problem, and what Alan is trying to get around, is that
one may not know the DECL at the time one sees the #pragma weak. This is
why I had my ugly patch to c-pragma.c differentiating identifiers from
strings, which also did not work in all cases covered by Alan's patch.
One wants to be able to say
#pragma weak foo
extern int foo(void);
int main (void)
{
if (foo)
return (*foo) ();
return 0;
}
At the point that the pragma is parsed, one has not seen the DECL for foo.
GCC's attribute extension weakens the DECL, but #pragma weak just puts the
string on a list. Even if we walk the weak list when creating any DECL to
mark it weak if we have seen a #pragma weak, we still need to be able to
find the DECL again when we finish the weak symbols if the weak symbol was
not already emitted.
The names of the symbols that need to be weakened need to be
deferred as long as possible, which is why Alan is looking up the names in
weak_finish when GCC is about to emit the symbols. That is the point
where we have committed to emitting the symbol names and have our last
chance to find a DECL corresponding to the string. Otherwise, we are back
to weakening strings without any knowledge of a DECL to which it might
correspond.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 10:18 ` David Edelsohn
2002-03-06 10:59 ` Richard Henderson
@ 2002-03-06 11:43 ` Stan Shebs
1 sibling, 0 replies; 875+ messages in thread
From: Stan Shebs @ 2002-03-06 11:43 UTC (permalink / raw)
To: David Edelsohn; +Cc: Andrew Cagney, Alan Modra, Richard Henderson, gcc-patches
David Edelsohn wrote:
>
> The problem appears to be that all of the pragma and weak support
> is in varasm.c, but it only is needed for C-like languages. Because this
> is tied with varasm, I don't think that one can separate it out into a
> file only compiled for C-like languages.
>
> varasm.c includes c-tree.h, so there was no reason to believe that
> those symbols were not safe.
That sounds like a bogosity in varasm.c.
> gcc/cp/decl.c defines lookup_name, but with an extra parameter
> which currently is random garbage when this is used from the C++
> front-end. Sigh.
I can recount my personal unfortunate experience with this; Apple's
2.95.2 port called lookup_name from the backend, but I was never
able to get this to work completely correctly in 3.x for all the
languages, despite various experiments with lookup_name workalikes
in the C++ frontend. Shouldn't have been surprising, because
"names" in C++ are not flat and global as in other languages.
In the end, I went to section info encoding, which worked much
better.
For your case, it sounds like you want code in c-common.c and
friends, and maybe some new langhooks called from varasm.c.
Stan
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 11:27 ` David Edelsohn
@ 2002-03-06 12:41 ` Richard Henderson
2002-03-06 14:18 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-03-06 12:41 UTC (permalink / raw)
To: David Edelsohn; +Cc: Andrew Cagney, Alan Modra, gcc-patches
On Wed, Mar 06, 2002 at 02:27:36PM -0500, David Edelsohn wrote:
> The whole problem, and what Alan is trying to get around, is that
> one may not know the DECL at the time one sees the #pragma weak.
Yes, I know.
> Otherwise, we are back to weakening strings without any knowledge of a
> DECL to which it might correspond.
Not at all. You just have to do it in the C/C++ front end rather
than in the generic part of the compiler.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 12:41 ` Richard Henderson
@ 2002-03-06 14:18 ` David Edelsohn
2002-03-06 14:22 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-03-06 14:18 UTC (permalink / raw)
To: Richard Henderson, Andrew Cagney, Alan Modra, gcc-patches
>>>>> Richard Henderson writes:
>> Otherwise, we are back to weakening strings without any knowledge of a
>> DECL to which it might correspond.
Richard> Not at all. You just have to do it in the C/C++ front end rather
Richard> than in the generic part of the compiler.
Do what? What is "it"? Have each language provide its own
definition of weak_finish() instead of lookup_name()?
Maybe Alan understands what you mean. I think moving some of this
into the C/C++ front-end is going to start a domino effect of other
dependencies. I cannot see a clean place to make a modular cut, but I
guess I'm just being dense.
Sorry, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 14:18 ` David Edelsohn
@ 2002-03-06 14:22 ` Richard Henderson
2002-03-06 15:06 ` David Edelsohn
2002-03-06 15:18 ` Alan Modra
0 siblings, 2 replies; 875+ messages in thread
From: Richard Henderson @ 2002-03-06 14:22 UTC (permalink / raw)
To: David Edelsohn; +Cc: Andrew Cagney, Alan Modra, gcc-patches
On Wed, Mar 06, 2002 at 05:18:16PM -0500, David Edelsohn wrote:
> Do what? What is "it"? Have each language provide its own
> definition of weak_finish() instead of lookup_name()?
Basically, yes. Though I would actually remove weak_finish
entirely and process #pragma weak forward declarations in
finish_decl and finish_function or something.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 14:22 ` Richard Henderson
@ 2002-03-06 15:06 ` David Edelsohn
2002-03-06 15:07 ` Richard Henderson
2002-03-06 15:18 ` Alan Modra
1 sibling, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-03-06 15:06 UTC (permalink / raw)
To: Richard Henderson, Andrew Cagney, Alan Modra, gcc-patches
>>>>> Richard Henderson writes:
Richard> Basically, yes. Though I would actually remove weak_finish
Richard> entirely and process #pragma weak forward declarations in
Richard> finish_decl and finish_function or something.
That means weak_decls now needs to be global, but it is defined in
varasm.c so we will not have any undefined symbols.
As far as finish_decl or finish_function or sometihng, what if I
have
#pragma weak a
#pragma weak b
#pragma weak c
extern a();
/* use a */
extern b();
/* use b */
extern c();
/* use c */
Current weak_finish() is run at the end of the file, not each function.
There isn't any language-dependent finish_file(). It seems that we would
need to add that to each language, or just add weak_finish to each
language, possibly a no-op.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 15:06 ` David Edelsohn
@ 2002-03-06 15:07 ` Richard Henderson
2002-03-06 15:09 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-03-06 15:07 UTC (permalink / raw)
To: David Edelsohn; +Cc: Andrew Cagney, Alan Modra, gcc-patches
On Wed, Mar 06, 2002 at 05:39:05PM -0500, David Edelsohn wrote:
> That means weak_decls now needs to be global, but it is defined in
> varasm.c so we will not have any undefined symbols.
No, the *entire* processing of #pragma weak should be moved.
> Current weak_finish() is run at the end of the file, not each function.
Yeah, so? Means we'd properly get DECL_WEAK set asap.
Which in fact fixes a bug. Consider
#pragma weak a
int a;
int foo() { return a; }
int b __attribute__((weak));
int bar() { return b; }
Compiled on alpha-linux, with ./cc1 -O -fno-common,
foo:
ldah $1,a($29) !gprelhigh
ldl $0,a($1) !gprellow
ret $31,($26),1
bar:
ldq $1,b($29) !literal
ldl $0,0($1)
ret $31,($26),1
We've miscompiled foo. It should look like bar, since the weak
binding means that the variable may not be resolved within the
current module.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 15:07 ` Richard Henderson
@ 2002-03-06 15:09 ` David Edelsohn
2002-03-06 15:13 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-03-06 15:09 UTC (permalink / raw)
To: Richard Henderson, Andrew Cagney, Alan Modra, gcc-patches
>>>>> Richard Henderson writes:
Richard> On Wed, Mar 06, 2002 at 05:39:05PM -0500, David Edelsohn wrote:
>> That means weak_decls now needs to be global, but it is defined in
>> varasm.c so we will not have any undefined symbols.
Richard> No, the *entire* processing of #pragma weak should be moved.
I don't mean move everything. weak_finish walks weak_decls list.
We now need to walk the list outside varasm.c which means that the list
head cannot be static.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 15:09 ` David Edelsohn
@ 2002-03-06 15:13 ` Richard Henderson
0 siblings, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-03-06 15:13 UTC (permalink / raw)
To: David Edelsohn; +Cc: Andrew Cagney, Alan Modra, gcc-patches
On Wed, Mar 06, 2002 at 06:09:36PM -0500, David Edelsohn wrote:
> Richard> No, the *entire* processing of #pragma weak should be moved.
>
> I don't mean move everything.
I do.
> weak_finish walks weak_decls list.
Yes.
> We now need to walk the list outside varasm.c which means that the list
> head cannot be static.
No, it means all of
weak_decls
mark_weak_decls
add_weak
weak_finish
remove_from_pending_weak_list
should be moved and/or rewritten for c-common.c.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 14:22 ` Richard Henderson
2002-03-06 15:06 ` David Edelsohn
@ 2002-03-06 15:18 ` Alan Modra
2002-03-06 19:01 ` Alan Modra
1 sibling, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-03-06 15:18 UTC (permalink / raw)
To: Richard Henderson, David Edelsohn, Andrew Cagney, gcc-patches
On Wed, Mar 06, 2002 at 02:22:49PM -0800, Richard Henderson wrote:
> On Wed, Mar 06, 2002 at 05:18:16PM -0500, David Edelsohn wrote:
> > Do what? What is "it"? Have each language provide its own
> > definition of weak_finish() instead of lookup_name()?
>
> Basically, yes. Though I would actually remove weak_finish
> entirely and process #pragma weak forward declarations in
> finish_decl and finish_function or something.
How about looking through the weak_decls list from pushdecl?
Something like the following. Totally untested btw; I'm not even
sure I've got the list handling right. I'd need to do something
similar in cp/decl.c too.
Index: gcc/c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.305
diff -u -p -r1.305 c-decl.c
--- c-decl.c 2002/03/05 02:34:05 1.305
+++ c-decl.c 2002/03/06 23:11:24
@@ -2289,6 +2289,8 @@ pushdecl (x)
pedwarn ("`%s' was declared `extern' and later `static'",
IDENTIFIER_POINTER (name));
}
+
+ tie_decl_to_weaks (x);
}
else
{
Index: gcc/varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.255
diff -u -p -r1.255 varasm.c
--- varasm.c 2002/03/03 04:50:53 1.255
+++ varasm.c 2002/03/06 23:11:28
@@ -42,7 +42,6 @@ Software Foundation, 59 Temple Place - S
#include "obstack.h"
#include "hashtab.h"
#include "c-pragma.h"
-#include "c-tree.h"
#include "ggc.h"
#include "langhooks.h"
#include "tm_p.h"
@@ -5036,6 +5035,7 @@ struct weak_syms
};
static struct weak_syms * weak_decls;
+static struct weak_syms ** weak_decls_tail = weak_decls;
/* Mark weak_decls for garbage collection. */
@@ -5065,15 +5065,37 @@ add_weak (decl, name, value)
if (weak == NULL)
return 0;
- weak->next = weak_decls;
weak->decl = decl;
weak->name = name;
weak->value = value;
- weak_decls = weak;
+ weak->next = *weak_decls_tail;
+ *weak_decls_tail = weak;
+ if (decl)
+ weak_decls_tail = &weak->next;
return 1;
}
+void
+tie_decl_to_weaks (decl)
+ tree decl;
+{
+ tree name = DECL_NAME (decl);
+ struct weak_syms **p;
+ struct weak_syms *weak;
+
+ for (p = weak_decls_tail; (weak = *p) != NULL; p = &weak->next)
+ if (weak->name == name)
+ {
+ weak->decl = decl;
+ *p = weak->next;
+ weak->next = *weak_decls_tail;
+ *weak_decls_tail = weak;
+ weak_decls_tail = &weak->next;
+ break;
+ }
+}
+
/* Declare DECL to be a weak symbol. */
void
@@ -5103,14 +5125,7 @@ weak_finish ()
for (t = weak_decls; t != NULL; t = t->next)
{
#ifdef ASM_WEAKEN_DECL
- tree decl = t->decl;
- if (decl == NULL_TREE)
- {
- tree name = get_identifier (t->name);
- if (name)
- decl = lookup_name (name);
- }
- ASM_WEAKEN_DECL (asm_out_file, decl, t->name, t->value);
+ ASM_WEAKEN_DECL (asm_out_file, t->decl, t->name, t->value);
#else
#ifdef ASM_OUTPUT_WEAK_ALIAS
ASM_OUTPUT_WEAK_ALIAS (asm_out_file, t->name, t->value);
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 10:59 ` Richard Henderson
2002-03-06 11:27 ` David Edelsohn
@ 2002-03-06 15:40 ` David Edelsohn
2002-03-14 11:34 ` David Edelsohn
2002-03-14 16:00 ` David Edelsohn
3 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-03-06 15:40 UTC (permalink / raw)
To: Richard Henderson, Andrew Cagney, Alan Modra, gcc-patches
I thought that the other varasm.c functions called into the weak
functions, but they only look at flags in DECLs. Moving all of the
functions supporting weak in varasm.c to c-common.c is a clean solution.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 15:18 ` Alan Modra
@ 2002-03-06 19:01 ` Alan Modra
2002-03-10 14:27 ` Andrew Cagney
0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-03-06 19:01 UTC (permalink / raw)
To: Richard Henderson, David Edelsohn, Andrew Cagney, gcc-patches
On Thu, Mar 07, 2002 at 09:48:29AM +1030, Alan Modra wrote:
> How about looking through the weak_decls list from pushdecl?
This seems to work. Tested by building c,c++,f powerpc64-linux, and
using the following testcase.
cat >weakf.c <<EOF
extern int foo (void) __attribute__ ((weak));
#pragma weak bar
extern int bar (void);
extern int var1 __attribute__ ((weak));
#pragma weak var2
extern int var2;
extern int def (void) __attribute__ ((weak));
int def (void) { return var1; }
#pragma weak zzz = def
#pragma weak xxx = def2
#pragma weak def2
int def2 (void) { return var2; }
#pragma weak oops
static int oops (void) { return zzz () + xxx (); }
int main (void)
{
if (foo)
return (*foo) ();
if (bar)
return (*bar) ();
if (&var1)
return var1;
if (&var2)
return var2;
return def ();
}
EOF
powerpc-linux and i686-linux bootstrap in progress.
BTW, how should we treat "#pragma weak foo = foo" ? My c-pragma.c patch
makes it the same as "#pragma weak foo", but maybe an error is more
appropriate. This change (or doing something slightly different in
decl_pending_weak) is necessary as decl_pending_weak needs to look
through the weak list twice to handle:
#pragma weak fun
#pragma weak fun2 = fun
int fun (void);
gcc/ChangeLog
* c-decl.c (pushdecl): Call decl_pending_weak.
* output.h (decl_pending_weak): Declare.
* varasm.c (weak_decls_tail): New.
(add_weak): Manipulate weak_decls_tail.
(decl_pending_weak): New.
(weak_finish): Don't lookup_name here.
(remove_from_pending_weak_list): Fix up weak_decls_tail. Don't
strcmp identifiers.
* c-pragma.c (handle_pragma_weak): Try to find a decl for value.
Check value != name.
gcc/cp/ChangeLog
* decl.c (pushdecl): Call decl_pending_weak.
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.305
diff -u -p -r1.305 c-decl.c
--- c-decl.c 2002/03/05 02:34:05 1.305
+++ c-decl.c 2002/03/07 02:44:37
@@ -2242,6 +2242,14 @@ pushdecl (x)
IDENTIFIER_GLOBAL_VALUE (name) = x;
+ /* Check for a function or var decl weakened by "#pragma weak". */
+ if ((TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
+ && decl_pending_weak (x))
+ {
+ TREE_PUBLIC (name) = 1;
+ DECL_WEAK (x) = 1;
+ }
+
/* We no longer care about any previous block level declarations. */
IDENTIFIER_LIMBO_VALUE (name) = 0;
Index: c-pragma.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pragma.c,v
retrieving revision 1.47
diff -u -p -r1.47 c-pragma.c
--- c-pragma.c 2002/03/01 06:00:32 1.47
+++ c-pragma.c 2002/03/07 02:44:37
@@ -26,6 +26,7 @@ Software Foundation, 59 Temple Place - S
#include "function.h"
#include "cpplib.h"
#include "c-pragma.h"
+#include "c-tree.h"
#include "flags.h"
#include "toplev.h"
#include "ggc.h"
@@ -281,8 +282,9 @@ static void
handle_pragma_weak (dummy)
cpp_reader *dummy ATTRIBUTE_UNUSED;
{
- tree name, value, x;
+ tree name, value, x, decl;
enum cpp_ttype t;
+ const char *valstr;
value = 0;
@@ -298,8 +300,14 @@ handle_pragma_weak (dummy)
if (t != CPP_EOF)
warning ("junk at end of #pragma weak");
- add_weak (NULL_TREE, IDENTIFIER_POINTER (name),
- value ? IDENTIFIER_POINTER (value) : NULL);
+ decl = NULL_TREE;
+ valstr = NULL;
+ if (value && value != name)
+ {
+ decl = lookup_name (value);
+ valstr = IDENTIFIER_POINTER (value);
+ }
+ add_weak (decl, IDENTIFIER_POINTER (name), valstr);
}
#endif
Index: output.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/output.h,v
retrieving revision 1.96
diff -u -p -r1.96 output.h
--- output.h 2002/03/01 06:00:33 1.96
+++ output.h 2002/03/07 02:44:37
@@ -231,6 +231,10 @@ extern void mergeable_constant_section P
/* Declare DECL to be a weak symbol. */
extern void declare_weak PARAMS ((tree));
+
+/* Look for DECL on "#pragma weak" list. If found return 1 and tie
+ decl to list, otherwise return 0. */
+extern int decl_pending_weak PARAMS ((tree));
#endif /* TREE_CODE */
/* Emit any pending weak declarations. */
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.255
diff -u -p -r1.255 varasm.c
--- varasm.c 2002/03/03 04:50:53 1.255
+++ varasm.c 2002/03/07 02:44:43
@@ -42,7 +42,6 @@ Software Foundation, 59 Temple Place - S
#include "obstack.h"
#include "hashtab.h"
#include "c-pragma.h"
-#include "c-tree.h"
#include "ggc.h"
#include "langhooks.h"
#include "tm_p.h"
@@ -5036,6 +5035,7 @@ struct weak_syms
};
static struct weak_syms * weak_decls;
+static struct weak_syms ** weak_decls_tail = &weak_decls;
/* Mark weak_decls for garbage collection. */
@@ -5050,7 +5050,8 @@ mark_weak_decls (arg)
}
/* Add function NAME to the weak symbols list. VALUE is a weak alias
- associated with NAME. */
+ associated with NAME. IF DECL is 0, we are being called from
+ #pragma weak handler. *WEAK_DECLS_TAIL points to such entries. */
int
add_weak (decl, name, value)
@@ -5065,15 +5066,53 @@ add_weak (decl, name, value)
if (weak == NULL)
return 0;
- weak->next = weak_decls;
weak->decl = decl;
weak->name = name;
weak->value = value;
- weak_decls = weak;
+ weak->next = *weak_decls_tail;
+ *weak_decls_tail = weak;
+ if (decl)
+ weak_decls_tail = &weak->next;
return 1;
}
+/* Look for DECL on "#pragma weak" list. If found return 1 and tie
+ decl to list, otherwise return 0. */
+
+int
+decl_pending_weak (decl)
+ tree decl;
+{
+ const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
+ struct weak_syms **p;
+ struct weak_syms *weak;
+
+ for (p = weak_decls_tail; (weak = *p) != NULL; p = &weak->next)
+ if (weak->value == name)
+ {
+ weak->decl = decl;
+ *p = weak->next;
+ weak->next = *weak_decls_tail;
+ *weak_decls_tail = weak;
+ weak_decls_tail = &weak->next;
+ break;
+ }
+
+ for (p = weak_decls_tail; (weak = *p) != NULL; p = &weak->next)
+ if (weak->name == name)
+ {
+ weak->decl = decl;
+ *p = weak->next;
+ weak->next = *weak_decls_tail;
+ *weak_decls_tail = weak;
+ weak_decls_tail = &weak->next;
+ return 1;
+ }
+
+ return 0;
+}
+
/* Declare DECL to be a weak symbol. */
void
@@ -5103,14 +5142,7 @@ weak_finish ()
for (t = weak_decls; t != NULL; t = t->next)
{
#ifdef ASM_WEAKEN_DECL
- tree decl = t->decl;
- if (decl == NULL_TREE)
- {
- tree name = get_identifier (t->name);
- if (name)
- decl = lookup_name (name);
- }
- ASM_WEAKEN_DECL (asm_out_file, decl, t->name, t->value);
+ ASM_WEAKEN_DECL (asm_out_file, t->decl, t->name, t->value);
#else
#ifdef ASM_OUTPUT_WEAK_ALIAS
ASM_OUTPUT_WEAK_ALIAS (asm_out_file, t->name, t->value);
@@ -5140,9 +5172,11 @@ remove_from_pending_weak_list (name)
for (p = &weak_decls; *p; )
{
t = *p;
- if (strcmp (name, t->name) == 0)
+ if (name == t->name)
{
*p = t->next;
+ if (weak_decls_tail == &t->next)
+ weak_decls_tail = p;
free (t);
}
else
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.869
diff -u -p -r1.869 decl.c
--- decl.c 2002/03/03 14:07:29 1.869
+++ decl.c 2002/03/07 02:44:58
@@ -4087,6 +4087,14 @@ pushdecl (x)
|| TREE_CODE (x) == TEMPLATE_DECL))
SET_IDENTIFIER_NAMESPACE_VALUE (name, x);
+ /* Check for a function or var decl weakened by "#pragma weak". */
+ if ((TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
+ && decl_pending_weak (x))
+ {
+ TREE_PUBLIC (name) = 1;
+ DECL_WEAK (x) = 1;
+ }
+
/* Don't forget if the function was used via an implicit decl. */
if (IDENTIFIER_IMPLICIT_DECL (name)
&& TREE_USED (IDENTIFIER_IMPLICIT_DECL (name)))
^ permalink raw reply [flat|nested] 875+ messages in thread
* biggest alignment for sysv4.h altivec
@ 2002-03-08 14:25 Aldy Hernandez
2002-03-08 14:49 ` Geoff Keating
0 siblings, 1 reply; 875+ messages in thread
From: Aldy Hernandez @ 2002-03-08 14:25 UTC (permalink / raw)
To: dje, gcc-patches
obvious.
committing to branch and mainline.
2002-03-08 Aldy Hernandez <aldyh@redhat.com>
* config/rs6000/sysv4.h (BIGGEST_ALIGNMENT): Change for altivec.
Index: config/rs6000/sysv4.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.84
diff -c -p -r1.84 sysv4.h
*** sysv4.h 2002/02/19 19:40:41 1.84
--- sysv4.h 2002/03/08 22:23:47
*************** do { \
*** 385,391 ****
/* No data type wants to be aligned rounder than this. */
#undef BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT (TARGET_EABI ? 64 : 128)
/* An expression for the alignment of a structure field FIELD if the
alignment computed in the usual way is COMPUTED. */
--- 385,391 ----
/* No data type wants to be aligned rounder than this. */
#undef BIGGEST_ALIGNMENT
! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC) ? 64 : 128)
/* An expression for the alignment of a structure field FIELD if the
alignment computed in the usual way is COMPUTED. */
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: biggest alignment for sysv4.h altivec
2002-03-08 14:25 biggest alignment for sysv4.h altivec Aldy Hernandez
@ 2002-03-08 14:49 ` Geoff Keating
2002-03-08 14:52 ` Aldy Hernandez
0 siblings, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-03-08 14:49 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: gcc-patches
Aldy Hernandez <aldyh@redhat.com> writes:
> obvious.
Not obvious to me.
Why didn't you just change it to 128 always?
> committing to branch and mainline.
>
> 2002-03-08 Aldy Hernandez <aldyh@redhat.com>
>
> * config/rs6000/sysv4.h (BIGGEST_ALIGNMENT): Change for altivec.
>
> Index: config/rs6000/sysv4.h
> ===================================================================
> RCS file: /cvs/uberbaum/gcc/config/rs6000/sysv4.h,v
> retrieving revision 1.84
> diff -c -p -r1.84 sysv4.h
> *** sysv4.h 2002/02/19 19:40:41 1.84
> --- sysv4.h 2002/03/08 22:23:47
> *************** do { \
> *** 385,391 ****
>
> /* No data type wants to be aligned rounder than this. */
> #undef BIGGEST_ALIGNMENT
> ! #define BIGGEST_ALIGNMENT (TARGET_EABI ? 64 : 128)
>
> /* An expression for the alignment of a structure field FIELD if the
> alignment computed in the usual way is COMPUTED. */
> --- 385,391 ----
>
> /* No data type wants to be aligned rounder than this. */
> #undef BIGGEST_ALIGNMENT
> ! #define BIGGEST_ALIGNMENT ((TARGET_EABI && !TARGET_ALTIVEC) ? 64 : 128)
>
> /* An expression for the alignment of a structure field FIELD if the
> alignment computed in the usual way is COMPUTED. */
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: biggest alignment for sysv4.h altivec
2002-03-08 14:49 ` Geoff Keating
@ 2002-03-08 14:52 ` Aldy Hernandez
2002-03-08 15:16 ` Geoff Keating
0 siblings, 1 reply; 875+ messages in thread
From: Aldy Hernandez @ 2002-03-08 14:52 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
On Saturday, March 9, 2002, at 09:49 AM, Geoff Keating wrote:
> Aldy Hernandez <aldyh@redhat.com> writes:
>
>> obvious.
>
> Not obvious to me.
this is for the sysv4.h header file, not just for altivec.
do you want me to change BIGGEST_ALIGNMENT to 128 for every
sysv4.h variant?
aldy
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: biggest alignment for sysv4.h altivec
2002-03-08 14:52 ` Aldy Hernandez
@ 2002-03-08 15:16 ` Geoff Keating
2002-03-08 15:26 ` Aldy Hernandez
` (2 more replies)
0 siblings, 3 replies; 875+ messages in thread
From: Geoff Keating @ 2002-03-08 15:16 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: gcc-patches
Aldy Hernandez <aldyh@redhat.com> writes:
> On Saturday, March 9, 2002, at 09:49 AM, Geoff Keating wrote:
>
> > Aldy Hernandez <aldyh@redhat.com> writes:
> >
> >> obvious.
> >
> > Not obvious to me.
>
> this is for the sysv4.h header file, not just for altivec.
>
> do you want me to change BIGGEST_ALIGNMENT to 128 for every
> sysv4.h variant?
I would look at it the other way. Why should BIGGEST_ALIGNMENT
differ? It doesn't change when we switch on -msoft-float, even though
if we don't have hardware doubles then we don't need 64-bit alignment.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: biggest alignment for sysv4.h altivec
2002-03-08 15:16 ` Geoff Keating
@ 2002-03-08 15:26 ` Aldy Hernandez
2002-03-08 15:48 ` Geoff Keating
2002-03-08 18:52 ` Richard Henderson
2002-03-08 20:09 ` David Edelsohn
2 siblings, 1 reply; 875+ messages in thread
From: Aldy Hernandez @ 2002-03-08 15:26 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
>> this is for the sysv4.h header file, not just for altivec.
>>
>> do you want me to change BIGGEST_ALIGNMENT to 128 for every
>> sysv4.h variant?
>
> I would look at it the other way. Why should BIGGEST_ALIGNMENT
> differ? It doesn't change when we switch on -msoft-float, even though
> if we don't have hardware doubles then we don't need 64-bit alignment.
BIGGEST_ALIGNMENT was already set to 64 in the eabi case, all i'm
doing it is enforcing it to 128 when eabi && altivec.
i can come up with a testcase that fails without the patch.
jeff johnston has some code for printf with vectors that either needs
this patch or needs -mstrict-align (or -mno-eabi :)).
cheers
--
Aldy Hernandez E-mail: aldyh@redhat.com
Professional Gypsy Lost in Australia
Red Hat, Inc.
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: biggest alignment for sysv4.h altivec
2002-03-08 15:26 ` Aldy Hernandez
@ 2002-03-08 15:48 ` Geoff Keating
2002-03-08 15:53 ` Aldy Hernandez
0 siblings, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-03-08 15:48 UTC (permalink / raw)
To: aldyh; +Cc: gcc-patches
> Date: Sat, 9 Mar 2002 10:27:15 +1100
> Cc: gcc-patches@gcc.gnu.org
> From: Aldy Hernandez <aldyh@redhat.com>
> X-OriginalArrivalTime: 08 Mar 2002 23:26:28.0054 (UTC) FILETIME=[ABDB2760:01C1C6F8]
>
> >> this is for the sysv4.h header file, not just for altivec.
> >>
> >> do you want me to change BIGGEST_ALIGNMENT to 128 for every
> >> sysv4.h variant?
> >
> > I would look at it the other way. Why should BIGGEST_ALIGNMENT
> > differ? It doesn't change when we switch on -msoft-float, even though
> > if we don't have hardware doubles then we don't need 64-bit alignment.
>
> BIGGEST_ALIGNMENT was already set to 64 in the eabi case, all i'm
> doing it is enforcing it to 128 when eabi && altivec.
Sure. Why only when altivec? Why not always?
> i can come up with a testcase that fails without the patch.
Yes, I'm sure some patch is needed. The question is whether this
particular patch is the best choice.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: biggest alignment for sysv4.h altivec
2002-03-08 15:48 ` Geoff Keating
@ 2002-03-08 15:53 ` Aldy Hernandez
2002-03-08 17:34 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: Aldy Hernandez @ 2002-03-08 15:53 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
>> BIGGEST_ALIGNMENT was already set to 64 in the eabi case, all i'm
>> doing it is enforcing it to 128 when eabi && altivec.
>
> Sure. Why only when altivec? Why not always?
pffttt, sure i don't care. i don't know why it was conditionalized
on TARGET_EABI in the first place? it could have been me for all
i know.
i don't think increasing alignment is ever a problem :)
if dje and you agree, i'm all about setting it to 128.
better yet, removing the definition altogether, since rs6000.h
already sets it to 128 unconditionally.
cheerios
aldy
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: biggest alignment for sysv4.h altivec
2002-03-08 15:53 ` Aldy Hernandez
@ 2002-03-08 17:34 ` Richard Henderson
0 siblings, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-03-08 17:34 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: Geoff Keating, gcc-patches
On Sat, Mar 09, 2002 at 10:53:57AM +1100, Aldy Hernandez wrote:
> i don't think increasing alignment is ever a problem :)
Yes, it is. BIGGEST_ALIGNMENT affects structure layout.
It affects how __attribute__((aligned)) is treated.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: biggest alignment for sysv4.h altivec
2002-03-08 15:16 ` Geoff Keating
2002-03-08 15:26 ` Aldy Hernandez
@ 2002-03-08 18:52 ` Richard Henderson
2002-03-08 20:09 ` David Edelsohn
2 siblings, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-03-08 18:52 UTC (permalink / raw)
To: Geoff Keating; +Cc: Aldy Hernandez, gcc-patches
On Fri, Mar 08, 2002 at 03:16:39PM -0800, Geoff Keating wrote:
> I would look at it the other way. Why should BIGGEST_ALIGNMENT
> differ?
BIGGEST_ALIGNMENT affects the ABI. You can't change it
arbitrarily.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: biggest alignment for sysv4.h altivec
2002-03-08 15:16 ` Geoff Keating
2002-03-08 15:26 ` Aldy Hernandez
2002-03-08 18:52 ` Richard Henderson
@ 2002-03-08 20:09 ` David Edelsohn
2002-03-09 2:11 ` Geoff Keating
2 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-03-08 20:09 UTC (permalink / raw)
To: Geoff Keating, aldyh; +Cc: gcc-patches
>>>>> Geoff Keating writes:
| I would look at it the other way. Why should BIGGEST_ALIGNMENT
| differ? It doesn't change when we switch on -msoft-float, even though
| if we don't have hardware doubles then we don't need 64-bit alignment.
The Altivec ABI is an extension to the SVR4 and Darwin/AIX ABIs.
It increases the biggest alignment to 128 bits.
-msoft-float is not a new or extended ABI. It is the original ABI
with FPRs disabled and floating point emulated in GPRs. It is intended to
be compatible with the original ABI and the original ABI's alignment
rules.
The two issues are not similar enough to use as justification or
precedent for the other.
BIGGEST_ALIGNMENT needs to change because the Altivec ABI says
that it is different. One cannot uniformly change BIGGEST_ALIGNMENT to
128 because that is not what the SVR4 ABI specifies. One needs the
conditional as Aldy has proposed.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: biggest alignment for sysv4.h altivec
2002-03-08 20:09 ` David Edelsohn
@ 2002-03-09 2:11 ` Geoff Keating
2002-03-09 15:09 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-03-09 2:11 UTC (permalink / raw)
To: dje; +Cc: aldyh, gcc-patches
> cc: gcc-patches@gcc.gnu.org
> Date: Fri, 08 Mar 2002 23:08:18 -0500
> From: David Edelsohn <dje@watson.ibm.com>
>
> >>>>> Geoff Keating writes:
>
> | I would look at it the other way. Why should BIGGEST_ALIGNMENT
> | differ? It doesn't change when we switch on -msoft-float, even though
> | if we don't have hardware doubles then we don't need 64-bit alignment.
>
> The Altivec ABI is an extension to the SVR4 and Darwin/AIX ABIs.
> It increases the biggest alignment to 128 bits.
>
> -msoft-float is not a new or extended ABI. It is the original ABI
> with FPRs disabled and floating point emulated in GPRs. It is intended to
> be compatible with the original ABI and the original ABI's alignment
> rules.
>
> The two issues are not similar enough to use as justification or
> precedent for the other.
>
> BIGGEST_ALIGNMENT needs to change because the Altivec ABI says
> that it is different. One cannot uniformly change BIGGEST_ALIGNMENT to
> 128 because that is not what the SVR4 ABI specifies. One needs the
> conditional as Aldy has proposed.
That's an interesting point, and helped clarify my thinking on this a
lot. Thanks!
I presume you meant EABI when you said SVR4 ABI. The SVR4 ABI has
always had 128-bit alignment of the stack frame and other objects.
The published EABI also has certain objects that do require 128-bit
alignment. Although the stack is not 128-bit aligned, for
compatibility with the SVR4 ABI it has always been the case that, if
'long double' was implemented (as in the -mlong-double-128 flag), then
struct x {
int a;
long double d;
};
has had 'd' aligned to a 128-bit boundary (even though if it was on
the stack or a global it would be aligned only to a 64-bit boundary,
and in fact there's no guarantee the structure will be properly
aligned). I don't think we do this properly now; we should, and one
step towards doing it is changing BIGGEST_ALIGNMENT.
And now, in a neat twist of logic, I can argue that -mno-long-double-128
is just like -msoft-float.
We have different restrictions on changing GCC's EABI implementation
than changing the SVR4 ABI implementation, especially if it's fixing
bugs. Changing the SVR4 ABI implementation, even to fix a bug, is
difficult because of the problems it causes with binary compatibility
under Linux. The EABI is intended at embedded targets and so has
fewer compatibility requirements.
I will therefore commit a patch to change BIGGEST_ALIGNMENT and a
testcase to check that the long-double structure alignment is correct.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: biggest alignment for sysv4.h altivec
2002-03-09 2:11 ` Geoff Keating
@ 2002-03-09 15:09 ` David Edelsohn
2002-03-09 16:17 ` Geoff Keating
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-03-09 15:09 UTC (permalink / raw)
To: Geoff Keating; +Cc: aldyh, gcc-patches
>>>>> Geoff Keating writes:
Geoff> I will therefore commit a patch to change BIGGEST_ALIGNMENT and a
Geoff> testcase to check that the long-double structure alignment is correct.
Does correct mean correct for the long double mode in effect or
uniformly 128 bit alignment? While long double is implemented as 64-bit
double, the object is only 64 bits, not 64 bits embedded in 128 bits.
Having eABI use 128-bit alignment when -mlong-double=128 does seem
correct.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: biggest alignment for sysv4.h altivec
2002-03-09 15:09 ` David Edelsohn
@ 2002-03-09 16:17 ` Geoff Keating
0 siblings, 0 replies; 875+ messages in thread
From: Geoff Keating @ 2002-03-09 16:17 UTC (permalink / raw)
To: dje; +Cc: aldyh, gcc-patches
> cc: aldyh@redhat.com, gcc-patches@gcc.gnu.org
> Date: Sat, 09 Mar 2002 18:08:52 -0500
> From: David Edelsohn <dje@watson.ibm.com>
>
> >>>>> Geoff Keating writes:
>
> Geoff> I will therefore commit a patch to change BIGGEST_ALIGNMENT and a
> Geoff> testcase to check that the long-double structure alignment is correct.
>
> Does correct mean correct for the long double mode in effect or
> uniformly 128 bit alignment? While long double is implemented as 64-bit
> double, the object is only 64 bits, not 64 bits embedded in 128 bits.
> Having eABI use 128-bit alignment when -mlong-double=128 does seem
> correct.
The change should have effect only when 'long double' is 128 bits.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 19:01 ` Alan Modra
@ 2002-03-10 14:27 ` Andrew Cagney
2002-03-10 14:34 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Andrew Cagney @ 2002-03-10 14:27 UTC (permalink / raw)
To: Alan Modra; +Cc: Richard Henderson, David Edelsohn, gcc-patches
> gcc/ChangeLog
> * c-decl.c (pushdecl): Call decl_pending_weak.
> * output.h (decl_pending_weak): Declare.
> * varasm.c (weak_decls_tail): New.
> (add_weak): Manipulate weak_decls_tail.
> (decl_pending_weak): New.
> (weak_finish): Don't lookup_name here.
> (remove_from_pending_weak_list): Fix up weak_decls_tail. Don't
> strcmp identifiers.
> * c-pragma.c (handle_pragma_weak): Try to find a decl for value.
> Check value != name.
How is this patch going?
Andrew
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-10 14:27 ` Andrew Cagney
@ 2002-03-10 14:34 ` David Edelsohn
2002-03-10 16:00 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-03-10 14:34 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Alan Modra, Richard Henderson, gcc-patches
>>>>> Andrew Cagney writes:
Andrew> How is this patch going?
We have two proposed patches: Alan's patch moving the weak support
for pushdecl and Richard's proposal to move the current weak support from
varasm.c to c-common.c.
Alan has not commented on Richard's proposal and Richard has not
commented on Alan's proposal. Moving the weak machinery to c-common seems
like a good shift to me because it is self-containted and pragma weak is
C/C++/Obj-C specific.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-10 14:34 ` David Edelsohn
@ 2002-03-10 16:00 ` Richard Henderson
0 siblings, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-03-10 16:00 UTC (permalink / raw)
To: David Edelsohn; +Cc: Andrew Cagney, Alan Modra, gcc-patches
On Sun, Mar 10, 2002 at 05:34:14PM -0500, David Edelsohn wrote:
> Alan has not commented on Richard's proposal and Richard has not
> commented on Alan's proposal. Moving the weak machinery to c-common seems
> like a good shift to me because it is self-containted and pragma weak is
> C/C++/Obj-C specific.
I started on a patch, but got sidetracked in the middle.
Perhaps today or tomorrow.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 10:59 ` Richard Henderson
2002-03-06 11:27 ` David Edelsohn
2002-03-06 15:40 ` David Edelsohn
@ 2002-03-14 11:34 ` David Edelsohn
2002-03-14 12:02 ` Neil Booth
2002-03-14 13:47 ` Geoff Keating
2002-03-14 16:00 ` David Edelsohn
3 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2002-03-14 11:34 UTC (permalink / raw)
To: Richard Henderson, Andrew Cagney, Alan Modra, gcc-patches
How about a patch like the following?
Note that remove_from_pending_list now needs to be global because
it is accessed by the recently added varasm.c:globalize_decl().
Thanks, David
* output.h: Declare remove_from_pending_list.
* langhooks.h (lang_hooks): Add symbol_finish.
* langhooks-def.h (LANG_HOOKS_SYMBOL_FINISH): New.
(LANG_HOOKS_INITIALIZER): Use it.
* varasm.c: Move weak support from here ...
* c-common.c: ... to here.
(c_common_init): Add weak_decls to ggc roots.
* c-lang.c (LANG_HOOKS_SYMBOL_FINISH): Define.
* objc/objc-lang.c: Same.
* cp/cp-lang.c: Same.
Index: output.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/output.h,v
retrieving revision 1.96
diff -c -p -r1.96 output.h
*** output.h 2002/03/01 06:00:33 1.96
--- output.h 2002/03/14 19:23:50
*************** extern const char *get_insn_template PAR
*** 139,144 ****
--- 139,147 ----
associated with NAME. */
extern int add_weak PARAMS ((tree, const char *, const char *));
+ /* Remove function NAME from the weak symbols list. */
+ extern void remove_from_pending_weak_list PARAMS ((const char *));
+
/* Functions in flow.c */
extern void allocate_for_life_analysis PARAMS ((void));
extern int regno_uninitialized PARAMS ((unsigned int));
Index: langhooks-def.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/langhooks-def.h,v
retrieving revision 1.10
diff -c -p -r1.10 langhooks-def.h
*** langhooks-def.h 2002/03/08 19:20:47 1.10
--- langhooks-def.h 2002/03/14 19:23:50
*************** void lhd_tree_inlining_end_inlining PAR
*** 67,72 ****
--- 67,73 ----
#define LANG_HOOKS_NAME "GNU unknown"
#define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier)
#define LANG_HOOKS_INIT lhd_do_nothing
+ #define LANG_HOOKS_SYMBOL_FINISH lhd_do_nothing
#define LANG_HOOKS_FINISH lhd_do_nothing
#define LANG_HOOKS_CLEAR_BINDING_STACK lhd_clear_binding_stack
#define LANG_HOOKS_INIT_OPTIONS lhd_do_nothing
*************** int lhd_tree_dump_type_quals PARAMS ((
*** 140,145 ****
--- 141,147 ----
LANG_HOOKS_DECODE_OPTION, \
LANG_HOOKS_POST_OPTIONS, \
LANG_HOOKS_INIT, \
+ LANG_HOOKS_SYMBOL_FINISH, \
LANG_HOOKS_FINISH, \
LANG_HOOKS_CLEAR_BINDING_STACK, \
LANG_HOOKS_GET_ALIAS_SET, \
Index: langhooks.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/langhooks.h,v
retrieving revision 1.17
diff -c -p -r1.17 langhooks.h
*** langhooks.h 2002/03/08 19:20:47 1.17
--- langhooks.h 2002/03/14 19:23:50
*************** struct lang_hooks
*** 101,106 ****
--- 101,110 ----
immediately. */
const char * (*init) PARAMS ((const char *));
+ /* Called near the end of compilation, to emit any pending symbols,
+ such as weak delclarations. */
+ void (*symbol_finish) PARAMS ((void));
+
/* Called at the end of compilation, as a finalizer. */
void (*finish) PARAMS ((void));
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.c,v
retrieving revision 1.297
diff -c -p -r1.297 c-common.c
*** c-common.c 2002/03/13 01:42:29 1.297
--- c-common.c 2002/03/14 19:23:50
*************** boolean_increment (code, arg)
*** 4023,4028 ****
--- 4023,4156 ----
return val;
}
\f
+ /* This structure contains any weak symbol declarations waiting
+ to be emitted. */
+ struct weak_syms
+ {
+ struct weak_syms * next;
+ tree decl;
+ const char * name;
+ const char * value;
+ };
+
+ static struct weak_syms * weak_decls;
+
+ static void mark_weak_decls PARAMS ((void *));
+
+ /* Mark weak_decls for garbage collection. */
+
+ static void
+ mark_weak_decls (arg)
+ void *arg;
+ {
+ struct weak_syms *t;
+
+ for (t = *(struct weak_syms **) arg; t != NULL; t = t->next)
+ ggc_mark_tree (t->decl);
+ }
+
+ /* Add function NAME to the weak symbols list. VALUE is a weak alias
+ associated with NAME. */
+
+ int
+ add_weak (decl, name, value)
+ tree decl;
+ const char *name;
+ const char *value;
+ {
+ struct weak_syms *weak;
+
+ weak = (struct weak_syms *) xmalloc (sizeof (struct weak_syms));
+
+ if (weak == NULL)
+ return 0;
+
+ weak->next = weak_decls;
+ weak->decl = decl;
+ weak->name = name;
+ weak->value = value;
+ weak_decls = weak;
+
+ return 1;
+ }
+
+ /* Declare DECL to be a weak symbol. */
+
+ void
+ declare_weak (decl)
+ tree decl;
+ {
+ if (! TREE_PUBLIC (decl))
+ error_with_decl (decl, "weak declaration of `%s' must be public");
+ else if (TREE_ASM_WRITTEN (decl))
+ error_with_decl (decl, "weak declaration of `%s' must precede definition");
+ else if (SUPPORTS_WEAK)
+ add_weak (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), NULL);
+ else
+ warning_with_decl (decl, "weak declaration of `%s' not supported");
+
+ DECL_WEAK (decl) = 1;
+ }
+
+ /* Emit any pending weak declarations. */
+
+ void
+ weak_finish ()
+ {
+ if (SUPPORTS_WEAK)
+ {
+ struct weak_syms *t;
+ for (t = weak_decls; t != NULL; t = t->next)
+ {
+ #ifdef ASM_WEAKEN_DECL
+ tree decl = t->decl;
+ if (decl == NULL_TREE)
+ {
+ tree name = get_identifier (t->name);
+ if (name)
+ decl = lookup_name (name);
+ }
+ ASM_WEAKEN_DECL (asm_out_file, decl, t->name, t->value);
+ #else
+ #ifdef ASM_OUTPUT_WEAK_ALIAS
+ ASM_OUTPUT_WEAK_ALIAS (asm_out_file, t->name, t->value);
+ #else
+ #ifdef ASM_WEAKEN_LABEL
+ if (t->value)
+ abort ();
+ ASM_WEAKEN_LABEL (asm_out_file, t->name);
+ #endif
+ #endif
+ #endif
+ }
+ }
+ }
+
+ /* Remove NAME from the pending list of weak symbols. This prevents
+ the compiler from emitting multiple .weak directives which confuses
+ some assemblers. */
+ #if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
+ static void
+ remove_from_pending_weak_list (name)
+ const char *name;
+ {
+ struct weak_syms *t;
+ struct weak_syms **p;
+
+ for (p = &weak_decls; *p; )
+ {
+ t = *p;
+ if (strcmp (name, t->name) == 0)
+ {
+ *p = t->next;
+ free (t);
+ }
+ else
+ p = &(t->next);
+ }
+ }
+ #endif /* defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL) */
+ \f
/* Handle C and C++ default attributes. */
enum built_in_attribute
*************** c_common_init_options (lang)
*** 4058,4063 ****
--- 4186,4193 ----
/* Mark as "unspecified" (see c_common_post_options). */
flag_bounds_check = -1;
+
+ ggc_add_root (&weak_decls, 1, sizeof weak_decls, mark_weak_decls);
}
/* Post-switch processing. */
Index: c-lang.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-lang.c,v
retrieving revision 1.76
diff -c -p -r1.76 c-lang.c
*** c-lang.c 2002/03/13 01:42:30 1.76
--- c-lang.c 2002/03/14 19:23:50
*************** Software Foundation, 59 Temple Place - S
*** 23,28 ****
--- 23,29 ----
#include "config.h"
#include "system.h"
#include "tree.h"
+ #include "output.h"
#include "c-tree.h"
#include "langhooks.h"
#include "langhooks-def.h"
*************** static void c_post_options PARAMS ((void
*** 37,42 ****
--- 38,46 ----
#define LANG_HOOKS_NAME "GNU C"
#undef LANG_HOOKS_INIT
#define LANG_HOOKS_INIT c_init
+ #undef LANG_HOOKS_SYMBOL_FINISH
+ #define LANG_HOOKS_SYMBOL_FINISH weak_finish
+ #undef LANG_HOOKS_INIT_OPTIONS
#undef LANG_HOOKS_FINISH
#define LANG_HOOKS_FINISH c_common_finish
#undef LANG_HOOKS_INIT_OPTIONS
Index: cp/cp-lang.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-lang.c,v
retrieving revision 1.13
diff -c -p -r1.13 cp-lang.c
*** cp-lang.c 2002/03/13 01:42:39 1.13
--- cp-lang.c 2002/03/14 19:23:50
*************** Boston, MA 02111-1307, USA. */
*** 22,27 ****
--- 22,28 ----
#include "config.h"
#include "system.h"
#include "tree.h"
+ #include "output.h"
#include "cp-tree.h"
#include "c-common.h"
#include "toplev.h"
*************** static bool ok_to_generate_alias_set_for
*** 35,40 ****
--- 36,43 ----
#define LANG_HOOKS_NAME "GNU C++"
#undef LANG_HOOKS_INIT
#define LANG_HOOKS_INIT cxx_init
+ #undef LANG_HOOKS_SYMBOL_FINISH
+ #define LANG_HOOKS_SYMBOL_FINISH weak_finish
#undef LANG_HOOKS_FINISH
#define LANG_HOOKS_FINISH cxx_finish
#undef LANG_HOOKS_CLEAR_BINDING_STACK
Index: objc/objc-lang.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/objc/objc-lang.c,v
retrieving revision 1.4
diff -c -p -r1.4 objc-lang.c
*** objc-lang.c 2002/03/13 01:42:43 1.4
--- objc-lang.c 2002/03/14 19:23:50
*************** Boston, MA 02111-1307, USA. */
*** 22,27 ****
--- 22,28 ----
#include "config.h"
#include "system.h"
#include "tree.h"
+ #include "output.h"
#include "c-tree.h"
#include "c-common.h"
#include "toplev.h"
*************** static void objc_post_options
*** 36,41 ****
--- 37,44 ----
#define LANG_HOOKS_NAME "GNU Objective-C"
#undef LANG_HOOKS_INIT
#define LANG_HOOKS_INIT objc_init
+ #undef LANG_HOOKS_SYMBOL_FINISH
+ #define LANG_HOOKS_SYMBOL_FINISH weak_finish
#undef LANG_HOOKS_FINISH
#define LANG_HOOKS_FINISH c_common_finish
#undef LANG_HOOKS_INIT_OPTIONS
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-14 11:34 ` David Edelsohn
@ 2002-03-14 12:02 ` Neil Booth
2002-03-14 13:47 ` Geoff Keating
1 sibling, 0 replies; 875+ messages in thread
From: Neil Booth @ 2002-03-14 12:02 UTC (permalink / raw)
To: David Edelsohn; +Cc: Richard Henderson, Andrew Cagney, Alan Modra, gcc-patches
David Edelsohn wrote:-
> + void
> + weak_finish ()
> + {
Since this is a hook common to the 3 C languages, could you call it
c_weak_finish instead? The other hooks (mostly) follow this convention.
Thanks,
Neil.
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-14 11:34 ` David Edelsohn
2002-03-14 12:02 ` Neil Booth
@ 2002-03-14 13:47 ` Geoff Keating
2002-03-14 14:07 ` David Edelsohn
2002-03-14 15:24 ` David Edelsohn
1 sibling, 2 replies; 875+ messages in thread
From: Geoff Keating @ 2002-03-14 13:47 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
David Edelsohn <dje@watson.ibm.com> writes:
> How about a patch like the following?
>
> Note that remove_from_pending_list now needs to be global because
> it is accessed by the recently added varasm.c:globalize_decl().
With the change that Neil suggested, suitable testing, and the posting
of the missing patch to varasm.c (which I presume just deletes stuff),
this patch is OK.
BTW, the reason the regression tester didn't notice this is because it
thinks the assembler is very old and doesn't support weak symbols :-(.
This is a bug in configure.in, it needs to search for the assembler
the same way as the C code does (and then we could stop the C code
from searching at all and get it to just use the configured location).
> * output.h: Declare remove_from_pending_list.
> * langhooks.h (lang_hooks): Add symbol_finish.
> * langhooks-def.h (LANG_HOOKS_SYMBOL_FINISH): New.
> (LANG_HOOKS_INITIALIZER): Use it.
> * varasm.c: Move weak support from here ...
> * c-common.c: ... to here.
> (c_common_init): Add weak_decls to ggc roots.
> * c-lang.c (LANG_HOOKS_SYMBOL_FINISH): Define.
> * objc/objc-lang.c: Same.
> * cp/cp-lang.c: Same.
>
> Index: output.h
> ===================================================================
> RCS file: /cvs/gcc/egcs/gcc/output.h,v
> retrieving revision 1.96
> diff -c -p -r1.96 output.h
> *** output.h 2002/03/01 06:00:33 1.96
> --- output.h 2002/03/14 19:23:50
> *************** extern const char *get_insn_template PAR
> *** 139,144 ****
> --- 139,147 ----
> associated with NAME. */
> extern int add_weak PARAMS ((tree, const char *, const char *));
>
> + /* Remove function NAME from the weak symbols list. */
> + extern void remove_from_pending_weak_list PARAMS ((const char *));
> +
> /* Functions in flow.c */
> extern void allocate_for_life_analysis PARAMS ((void));
> extern int regno_uninitialized PARAMS ((unsigned int));
> Index: langhooks-def.h
> ===================================================================
> RCS file: /cvs/gcc/egcs/gcc/langhooks-def.h,v
> retrieving revision 1.10
> diff -c -p -r1.10 langhooks-def.h
> *** langhooks-def.h 2002/03/08 19:20:47 1.10
> --- langhooks-def.h 2002/03/14 19:23:50
> *************** void lhd_tree_inlining_end_inlining PAR
> *** 67,72 ****
> --- 67,73 ----
> #define LANG_HOOKS_NAME "GNU unknown"
> #define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier)
> #define LANG_HOOKS_INIT lhd_do_nothing
> + #define LANG_HOOKS_SYMBOL_FINISH lhd_do_nothing
> #define LANG_HOOKS_FINISH lhd_do_nothing
> #define LANG_HOOKS_CLEAR_BINDING_STACK lhd_clear_binding_stack
> #define LANG_HOOKS_INIT_OPTIONS lhd_do_nothing
> *************** int lhd_tree_dump_type_quals PARAMS ((
> *** 140,145 ****
> --- 141,147 ----
> LANG_HOOKS_DECODE_OPTION, \
> LANG_HOOKS_POST_OPTIONS, \
> LANG_HOOKS_INIT, \
> + LANG_HOOKS_SYMBOL_FINISH, \
> LANG_HOOKS_FINISH, \
> LANG_HOOKS_CLEAR_BINDING_STACK, \
> LANG_HOOKS_GET_ALIAS_SET, \
> Index: langhooks.h
> ===================================================================
> RCS file: /cvs/gcc/egcs/gcc/langhooks.h,v
> retrieving revision 1.17
> diff -c -p -r1.17 langhooks.h
> *** langhooks.h 2002/03/08 19:20:47 1.17
> --- langhooks.h 2002/03/14 19:23:50
> *************** struct lang_hooks
> *** 101,106 ****
> --- 101,110 ----
> immediately. */
> const char * (*init) PARAMS ((const char *));
>
> + /* Called near the end of compilation, to emit any pending symbols,
> + such as weak delclarations. */
> + void (*symbol_finish) PARAMS ((void));
> +
> /* Called at the end of compilation, as a finalizer. */
> void (*finish) PARAMS ((void));
>
> Index: c-common.c
> ===================================================================
> RCS file: /cvs/gcc/egcs/gcc/c-common.c,v
> retrieving revision 1.297
> diff -c -p -r1.297 c-common.c
> *** c-common.c 2002/03/13 01:42:29 1.297
> --- c-common.c 2002/03/14 19:23:50
> *************** boolean_increment (code, arg)
> *** 4023,4028 ****
> --- 4023,4156 ----
> return val;
> }
> \f
> + /* This structure contains any weak symbol declarations waiting
> + to be emitted. */
> + struct weak_syms
> + {
> + struct weak_syms * next;
> + tree decl;
> + const char * name;
> + const char * value;
> + };
> +
> + static struct weak_syms * weak_decls;
> +
> + static void mark_weak_decls PARAMS ((void *));
> +
> + /* Mark weak_decls for garbage collection. */
> +
> + static void
> + mark_weak_decls (arg)
> + void *arg;
> + {
> + struct weak_syms *t;
> +
> + for (t = *(struct weak_syms **) arg; t != NULL; t = t->next)
> + ggc_mark_tree (t->decl);
> + }
> +
> + /* Add function NAME to the weak symbols list. VALUE is a weak alias
> + associated with NAME. */
> +
> + int
> + add_weak (decl, name, value)
> + tree decl;
> + const char *name;
> + const char *value;
> + {
> + struct weak_syms *weak;
> +
> + weak = (struct weak_syms *) xmalloc (sizeof (struct weak_syms));
> +
> + if (weak == NULL)
> + return 0;
> +
> + weak->next = weak_decls;
> + weak->decl = decl;
> + weak->name = name;
> + weak->value = value;
> + weak_decls = weak;
> +
> + return 1;
> + }
> +
> + /* Declare DECL to be a weak symbol. */
> +
> + void
> + declare_weak (decl)
> + tree decl;
> + {
> + if (! TREE_PUBLIC (decl))
> + error_with_decl (decl, "weak declaration of `%s' must be public");
> + else if (TREE_ASM_WRITTEN (decl))
> + error_with_decl (decl, "weak declaration of `%s' must precede definition");
> + else if (SUPPORTS_WEAK)
> + add_weak (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), NULL);
> + else
> + warning_with_decl (decl, "weak declaration of `%s' not supported");
> +
> + DECL_WEAK (decl) = 1;
> + }
> +
> + /* Emit any pending weak declarations. */
> +
> + void
> + weak_finish ()
> + {
> + if (SUPPORTS_WEAK)
> + {
> + struct weak_syms *t;
> + for (t = weak_decls; t != NULL; t = t->next)
> + {
> + #ifdef ASM_WEAKEN_DECL
> + tree decl = t->decl;
> + if (decl == NULL_TREE)
> + {
> + tree name = get_identifier (t->name);
> + if (name)
> + decl = lookup_name (name);
> + }
> + ASM_WEAKEN_DECL (asm_out_file, decl, t->name, t->value);
> + #else
> + #ifdef ASM_OUTPUT_WEAK_ALIAS
> + ASM_OUTPUT_WEAK_ALIAS (asm_out_file, t->name, t->value);
> + #else
> + #ifdef ASM_WEAKEN_LABEL
> + if (t->value)
> + abort ();
> + ASM_WEAKEN_LABEL (asm_out_file, t->name);
> + #endif
> + #endif
> + #endif
> + }
> + }
> + }
> +
> + /* Remove NAME from the pending list of weak symbols. This prevents
> + the compiler from emitting multiple .weak directives which confuses
> + some assemblers. */
> + #if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
> + static void
> + remove_from_pending_weak_list (name)
> + const char *name;
> + {
> + struct weak_syms *t;
> + struct weak_syms **p;
> +
> + for (p = &weak_decls; *p; )
> + {
> + t = *p;
> + if (strcmp (name, t->name) == 0)
> + {
> + *p = t->next;
> + free (t);
> + }
> + else
> + p = &(t->next);
> + }
> + }
> + #endif /* defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL) */
> + \f
> /* Handle C and C++ default attributes. */
>
> enum built_in_attribute
> *************** c_common_init_options (lang)
> *** 4058,4063 ****
> --- 4186,4193 ----
>
> /* Mark as "unspecified" (see c_common_post_options). */
> flag_bounds_check = -1;
> +
> + ggc_add_root (&weak_decls, 1, sizeof weak_decls, mark_weak_decls);
> }
>
> /* Post-switch processing. */
> Index: c-lang.c
> ===================================================================
> RCS file: /cvs/gcc/egcs/gcc/c-lang.c,v
> retrieving revision 1.76
> diff -c -p -r1.76 c-lang.c
> *** c-lang.c 2002/03/13 01:42:30 1.76
> --- c-lang.c 2002/03/14 19:23:50
> *************** Software Foundation, 59 Temple Place - S
> *** 23,28 ****
> --- 23,29 ----
> #include "config.h"
> #include "system.h"
> #include "tree.h"
> + #include "output.h"
> #include "c-tree.h"
> #include "langhooks.h"
> #include "langhooks-def.h"
> *************** static void c_post_options PARAMS ((void
> *** 37,42 ****
> --- 38,46 ----
> #define LANG_HOOKS_NAME "GNU C"
> #undef LANG_HOOKS_INIT
> #define LANG_HOOKS_INIT c_init
> + #undef LANG_HOOKS_SYMBOL_FINISH
> + #define LANG_HOOKS_SYMBOL_FINISH weak_finish
> + #undef LANG_HOOKS_INIT_OPTIONS
> #undef LANG_HOOKS_FINISH
> #define LANG_HOOKS_FINISH c_common_finish
> #undef LANG_HOOKS_INIT_OPTIONS
> Index: cp/cp-lang.c
> ===================================================================
> RCS file: /cvs/gcc/egcs/gcc/cp/cp-lang.c,v
> retrieving revision 1.13
> diff -c -p -r1.13 cp-lang.c
> *** cp-lang.c 2002/03/13 01:42:39 1.13
> --- cp-lang.c 2002/03/14 19:23:50
> *************** Boston, MA 02111-1307, USA. */
> *** 22,27 ****
> --- 22,28 ----
> #include "config.h"
> #include "system.h"
> #include "tree.h"
> + #include "output.h"
> #include "cp-tree.h"
> #include "c-common.h"
> #include "toplev.h"
> *************** static bool ok_to_generate_alias_set_for
> *** 35,40 ****
> --- 36,43 ----
> #define LANG_HOOKS_NAME "GNU C++"
> #undef LANG_HOOKS_INIT
> #define LANG_HOOKS_INIT cxx_init
> + #undef LANG_HOOKS_SYMBOL_FINISH
> + #define LANG_HOOKS_SYMBOL_FINISH weak_finish
> #undef LANG_HOOKS_FINISH
> #define LANG_HOOKS_FINISH cxx_finish
> #undef LANG_HOOKS_CLEAR_BINDING_STACK
> Index: objc/objc-lang.c
> ===================================================================
> RCS file: /cvs/gcc/egcs/gcc/objc/objc-lang.c,v
> retrieving revision 1.4
> diff -c -p -r1.4 objc-lang.c
> *** objc-lang.c 2002/03/13 01:42:43 1.4
> --- objc-lang.c 2002/03/14 19:23:50
> *************** Boston, MA 02111-1307, USA. */
> *** 22,27 ****
> --- 22,28 ----
> #include "config.h"
> #include "system.h"
> #include "tree.h"
> + #include "output.h"
> #include "c-tree.h"
> #include "c-common.h"
> #include "toplev.h"
> *************** static void objc_post_options
> *** 36,41 ****
> --- 37,44 ----
> #define LANG_HOOKS_NAME "GNU Objective-C"
> #undef LANG_HOOKS_INIT
> #define LANG_HOOKS_INIT objc_init
> + #undef LANG_HOOKS_SYMBOL_FINISH
> + #define LANG_HOOKS_SYMBOL_FINISH weak_finish
> #undef LANG_HOOKS_FINISH
> #define LANG_HOOKS_FINISH c_common_finish
> #undef LANG_HOOKS_INIT_OPTIONS
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-14 13:47 ` Geoff Keating
@ 2002-03-14 14:07 ` David Edelsohn
2002-03-14 15:02 ` Geoff Keating
2002-03-14 15:24 ` David Edelsohn
1 sibling, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-03-14 14:07 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
Okay now?
David
* output.h (remove_from_pending_list): Declare.
(weak_finish): Delete.
* langhooks.h (lang_hooks): Add symbol_finish.
* langhooks-def.h (LANG_HOOKS_SYMBOL_FINISH): New.
(LANG_HOOKS_INITIALIZER): Use it.
* c-common.h (c_weak_finish): Declare.
* varasm.c: Move weak support from here ...
* c-common.c: ... to here.
(c_common_init): Add weak_decls to ggc roots.
* c-lang.c (LANG_HOOKS_SYMBOL_FINISH): Define.
* objc/objc-lang.c: Same.
* cp/cp-lang.c: Same.
* Makefile.in (c-lang.o): Depend on c-common.h.
Index: output.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/output.h,v
retrieving revision 1.96
diff -c -p -r1.96 output.h
*** output.h 2002/03/01 06:00:33 1.96
--- output.h 2002/03/14 22:01:38
*************** extern const char *get_insn_template PAR
*** 139,144 ****
--- 139,147 ----
associated with NAME. */
extern int add_weak PARAMS ((tree, const char *, const char *));
+ /* Remove function NAME from the weak symbols list. */
+ extern void remove_from_pending_weak_list PARAMS ((const char *));
+
/* Functions in flow.c */
extern void allocate_for_life_analysis PARAMS ((void));
extern int regno_uninitialized PARAMS ((unsigned int));
*************** extern void mergeable_constant_section P
*** 232,240 ****
/* Declare DECL to be a weak symbol. */
extern void declare_weak PARAMS ((tree));
#endif /* TREE_CODE */
-
- /* Emit any pending weak declarations. */
- extern void weak_finish PARAMS ((void));
/* Decode an `asm' spec for a declaration as a register name.
Return the register number, or -1 if nothing specified,
--- 235,240 ----
Index: langhooks-def.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/langhooks-def.h,v
retrieving revision 1.10
diff -c -p -r1.10 langhooks-def.h
*** langhooks-def.h 2002/03/08 19:20:47 1.10
--- langhooks-def.h 2002/03/14 22:01:39
*************** void lhd_tree_inlining_end_inlining PAR
*** 67,72 ****
--- 67,73 ----
#define LANG_HOOKS_NAME "GNU unknown"
#define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier)
#define LANG_HOOKS_INIT lhd_do_nothing
+ #define LANG_HOOKS_SYMBOL_FINISH lhd_do_nothing
#define LANG_HOOKS_FINISH lhd_do_nothing
#define LANG_HOOKS_CLEAR_BINDING_STACK lhd_clear_binding_stack
#define LANG_HOOKS_INIT_OPTIONS lhd_do_nothing
*************** int lhd_tree_dump_type_quals PARAMS ((
*** 140,145 ****
--- 141,147 ----
LANG_HOOKS_DECODE_OPTION, \
LANG_HOOKS_POST_OPTIONS, \
LANG_HOOKS_INIT, \
+ LANG_HOOKS_SYMBOL_FINISH, \
LANG_HOOKS_FINISH, \
LANG_HOOKS_CLEAR_BINDING_STACK, \
LANG_HOOKS_GET_ALIAS_SET, \
Index: langhooks.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/langhooks.h,v
retrieving revision 1.17
diff -c -p -r1.17 langhooks.h
*** langhooks.h 2002/03/08 19:20:47 1.17
--- langhooks.h 2002/03/14 22:01:39
*************** struct lang_hooks
*** 101,106 ****
--- 101,110 ----
immediately. */
const char * (*init) PARAMS ((const char *));
+ /* Called near the end of compilation, to emit any pending symbols,
+ such as weak delclarations. */
+ void (*symbol_finish) PARAMS ((void));
+
/* Called at the end of compilation, as a finalizer. */
void (*finish) PARAMS ((void));
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.256
diff -c -p -r1.256 varasm.c
*** varasm.c 2002/03/13 14:20:17 1.256
--- varasm.c 2002/03/14 22:01:40
*************** static unsigned HOST_WIDE_INT array_size
*** 167,176 ****
static unsigned min_align PARAMS ((unsigned, unsigned));
static void output_constructor PARAMS ((tree, HOST_WIDE_INT,
unsigned int));
- static void mark_weak_decls PARAMS ((void *));
- #if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
- static void remove_from_pending_weak_list PARAMS ((const char *));
- #endif
static void globalize_decl PARAMS ((tree));
static void maybe_assemble_visibility PARAMS ((tree));
static int in_named_entry_eq PARAMS ((const PTR, const PTR));
--- 167,172 ----
*************** output_constructor (exp, size, align)
*** 4995,5126 ****
}
- /* This structure contains any weak symbol declarations waiting
- to be emitted. */
- struct weak_syms
- {
- struct weak_syms * next;
- tree decl;
- const char * name;
- const char * value;
- };
-
- static struct weak_syms * weak_decls;
-
- /* Mark weak_decls for garbage collection. */
-
- static void
- mark_weak_decls (arg)
- void *arg;
- {
- struct weak_syms *t;
-
- for (t = *(struct weak_syms **) arg; t != NULL; t = t->next)
- ggc_mark_tree (t->decl);
- }
-
- /* Add function NAME to the weak symbols list. VALUE is a weak alias
- associated with NAME. */
-
- int
- add_weak (decl, name, value)
- tree decl;
- const char *name;
- const char *value;
- {
- struct weak_syms *weak;
-
- weak = (struct weak_syms *) xmalloc (sizeof (struct weak_syms));
-
- if (weak == NULL)
- return 0;
-
- weak->next = weak_decls;
- weak->decl = decl;
- weak->name = name;
- weak->value = value;
- weak_decls = weak;
-
- return 1;
- }
-
- /* Declare DECL to be a weak symbol. */
-
- void
- declare_weak (decl)
- tree decl;
- {
- if (! TREE_PUBLIC (decl))
- error_with_decl (decl, "weak declaration of `%s' must be public");
- else if (TREE_ASM_WRITTEN (decl))
- error_with_decl (decl, "weak declaration of `%s' must precede definition");
- else if (SUPPORTS_WEAK)
- add_weak (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), NULL);
- else
- warning_with_decl (decl, "weak declaration of `%s' not supported");
-
- DECL_WEAK (decl) = 1;
- }
-
- /* Emit any pending weak declarations. */
-
- void
- weak_finish ()
- {
- if (SUPPORTS_WEAK)
- {
- struct weak_syms *t;
- for (t = weak_decls; t != NULL; t = t->next)
- {
- #ifdef ASM_WEAKEN_DECL
- tree decl = t->decl;
- if (decl == NULL_TREE)
- {
- tree name = get_identifier (t->name);
- if (name)
- decl = lookup_name (name);
- }
- ASM_WEAKEN_DECL (asm_out_file, decl, t->name, t->value);
- #else
- #ifdef ASM_OUTPUT_WEAK_ALIAS
- ASM_OUTPUT_WEAK_ALIAS (asm_out_file, t->name, t->value);
- #else
- #ifdef ASM_WEAKEN_LABEL
- if (t->value)
- abort ();
- ASM_WEAKEN_LABEL (asm_out_file, t->name);
- #endif
- #endif
- #endif
- }
- }
- }
-
- /* Remove NAME from the pending list of weak symbols. This prevents
- the compiler from emitting multiple .weak directives which confuses
- some assemblers. */
- #if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
- static void
- remove_from_pending_weak_list (name)
- const char *name;
- {
- struct weak_syms *t;
- struct weak_syms **p;
-
- for (p = &weak_decls; *p; )
- {
- t = *p;
- if (strcmp (name, t->name) == 0)
- {
- *p = t->next;
- free (t);
- }
- else
- p = &(t->next);
- }
- }
- #endif /* defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL) */
-
/* Emit the assembly bits to indicate that DECL is globally visible. */
static void
--- 4991,4996 ----
*************** init_varasm_once ()
*** 5282,5288 ****
mark_const_hash_entry);
ggc_add_root (&const_str_htab, 1, sizeof const_str_htab,
mark_const_str_htab);
- ggc_add_root (&weak_decls, 1, sizeof weak_decls, mark_weak_decls);
const_alias_set = new_alias_set ();
}
--- 5152,5157 ----
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.c,v
retrieving revision 1.297
diff -c -p -r1.297 c-common.c
*** c-common.c 2002/03/13 01:42:29 1.297
--- c-common.c 2002/03/14 22:01:40
*************** boolean_increment (code, arg)
*** 4023,4028 ****
--- 4023,4156 ----
return val;
}
\f
+ /* This structure contains any weak symbol declarations waiting
+ to be emitted. */
+ struct weak_syms
+ {
+ struct weak_syms * next;
+ tree decl;
+ const char * name;
+ const char * value;
+ };
+
+ static struct weak_syms * weak_decls;
+
+ static void mark_weak_decls PARAMS ((void *));
+
+ /* Mark weak_decls for garbage collection. */
+
+ static void
+ mark_weak_decls (arg)
+ void *arg;
+ {
+ struct weak_syms *t;
+
+ for (t = *(struct weak_syms **) arg; t != NULL; t = t->next)
+ ggc_mark_tree (t->decl);
+ }
+
+ /* Add function NAME to the weak symbols list. VALUE is a weak alias
+ associated with NAME. */
+
+ int
+ add_weak (decl, name, value)
+ tree decl;
+ const char *name;
+ const char *value;
+ {
+ struct weak_syms *weak;
+
+ weak = (struct weak_syms *) xmalloc (sizeof (struct weak_syms));
+
+ if (weak == NULL)
+ return 0;
+
+ weak->next = weak_decls;
+ weak->decl = decl;
+ weak->name = name;
+ weak->value = value;
+ weak_decls = weak;
+
+ return 1;
+ }
+
+ /* Declare DECL to be a weak symbol. */
+
+ void
+ declare_weak (decl)
+ tree decl;
+ {
+ if (! TREE_PUBLIC (decl))
+ error_with_decl (decl, "weak declaration of `%s' must be public");
+ else if (TREE_ASM_WRITTEN (decl))
+ error_with_decl (decl, "weak declaration of `%s' must precede definition");
+ else if (SUPPORTS_WEAK)
+ add_weak (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), NULL);
+ else
+ warning_with_decl (decl, "weak declaration of `%s' not supported");
+
+ DECL_WEAK (decl) = 1;
+ }
+
+ /* Emit any pending weak declarations. */
+
+ void
+ c_weak_finish ()
+ {
+ if (SUPPORTS_WEAK)
+ {
+ struct weak_syms *t;
+ for (t = weak_decls; t != NULL; t = t->next)
+ {
+ #ifdef ASM_WEAKEN_DECL
+ tree decl = t->decl;
+ if (decl == NULL_TREE)
+ {
+ tree name = get_identifier (t->name);
+ if (name)
+ decl = lookup_name (name);
+ }
+ ASM_WEAKEN_DECL (asm_out_file, decl, t->name, t->value);
+ #else
+ #ifdef ASM_OUTPUT_WEAK_ALIAS
+ ASM_OUTPUT_WEAK_ALIAS (asm_out_file, t->name, t->value);
+ #else
+ #ifdef ASM_WEAKEN_LABEL
+ if (t->value)
+ abort ();
+ ASM_WEAKEN_LABEL (asm_out_file, t->name);
+ #endif
+ #endif
+ #endif
+ }
+ }
+ }
+
+ /* Remove NAME from the pending list of weak symbols. This prevents
+ the compiler from emitting multiple .weak directives which confuses
+ some assemblers. */
+ #if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
+ static void
+ remove_from_pending_weak_list (name)
+ const char *name;
+ {
+ struct weak_syms *t;
+ struct weak_syms **p;
+
+ for (p = &weak_decls; *p; )
+ {
+ t = *p;
+ if (strcmp (name, t->name) == 0)
+ {
+ *p = t->next;
+ free (t);
+ }
+ else
+ p = &(t->next);
+ }
+ }
+ #endif /* defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL) */
+ \f
/* Handle C and C++ default attributes. */
enum built_in_attribute
*************** c_common_init (filename)
*** 4112,4117 ****
--- 4240,4247 ----
if (!c_attrs_initialized)
c_init_attributes ();
+
+ ggc_add_root (&weak_decls, 1, sizeof weak_decls, mark_weak_decls);
return filename;
}
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.h,v
retrieving revision 1.117
diff -c -p -r1.117 c-common.h
*** c-common.h 2002/03/13 01:42:29 1.117
--- c-common.h 2002/03/14 22:01:41
*************** extern tree build_va_arg PARAMS ((tree
*** 551,556 ****
--- 551,557 ----
extern void c_common_init_options PARAMS ((enum c_language_kind));
extern void c_common_post_options PARAMS ((void));
extern const char *c_common_init PARAMS ((const char *));
+ extern void c_weak_finish PARAMS ((void));
extern void c_common_finish PARAMS ((void));
extern HOST_WIDE_INT c_common_get_alias_set PARAMS ((tree));
extern bool c_promoting_integer_type_p PARAMS ((tree));
Index: c-lang.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-lang.c,v
retrieving revision 1.76
diff -c -p -r1.76 c-lang.c
*** c-lang.c 2002/03/13 01:42:30 1.76
--- c-lang.c 2002/03/14 22:01:41
*************** Software Foundation, 59 Temple Place - S
*** 23,29 ****
--- 23,30 ----
#include "config.h"
#include "system.h"
#include "tree.h"
#include "c-tree.h"
+ #include "c-common.h"
#include "langhooks.h"
#include "langhooks-def.h"
*************** static void c_post_options PARAMS ((void
*** 37,42 ****
--- 39,46 ----
#define LANG_HOOKS_NAME "GNU C"
#undef LANG_HOOKS_INIT
#define LANG_HOOKS_INIT c_init
+ #undef LANG_HOOKS_SYMBOL_FINISH
+ #define LANG_HOOKS_SYMBOL_FINISH c_weak_finish
#undef LANG_HOOKS_FINISH
#define LANG_HOOKS_FINISH c_common_finish
#undef LANG_HOOKS_INIT_OPTIONS
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Makefile.in,v
retrieving revision 1.837
diff -c -p -r1.837 Makefile.in
*** Makefile.in 2002/03/12 05:40:30 1.837
--- Makefile.in 2002/03/14 22:01:42
*************** c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM
*** 1152,1158 ****
c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
$(TARGET_H) flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h $(TM_P_H)
c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
! langhooks.h langhooks-def.h
c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) c-lex.h \
debug.h $(C_TREE_H) \
c-pragma.h input.h intl.h flags.h toplev.h output.h \
--- 1152,1158 ----
c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
$(TARGET_H) flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h $(TM_P_H)
c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
! langhooks.h langhooks-def.h c-common.h
c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) c-lex.h \
debug.h $(C_TREE_H) \
c-pragma.h input.h intl.h flags.h toplev.h output.h \
Index: objc/objc-lang.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/objc/objc-lang.c,v
retrieving revision 1.4
diff -c -p -r1.4 objc-lang.c
*** objc-lang.c 2002/03/13 01:42:43 1.4
--- objc-lang.c 2002/03/14 22:01:42
*************** static void objc_post_options
*** 36,41 ****
--- 36,43 ----
#define LANG_HOOKS_NAME "GNU Objective-C"
#undef LANG_HOOKS_INIT
#define LANG_HOOKS_INIT objc_init
+ #undef LANG_HOOKS_SYMBOL_FINISH
+ #define LANG_HOOKS_SYMBOL_FINISH c_weak_finish
#undef LANG_HOOKS_FINISH
#define LANG_HOOKS_FINISH c_common_finish
#undef LANG_HOOKS_INIT_OPTIONS
Index: cp/cp-lang.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-lang.c,v
retrieving revision 1.13
diff -c -p -r1.13 cp-lang.c
*** cp-lang.c 2002/03/13 01:42:39 1.13
--- cp-lang.c 2002/03/14 22:01:42
*************** static bool ok_to_generate_alias_set_for
*** 35,40 ****
--- 35,42 ----
#define LANG_HOOKS_NAME "GNU C++"
#undef LANG_HOOKS_INIT
#define LANG_HOOKS_INIT cxx_init
+ #undef LANG_HOOKS_SYMBOL_FINISH
+ #define LANG_HOOKS_SYMBOL_FINISH c_weak_finish
#undef LANG_HOOKS_FINISH
#define LANG_HOOKS_FINISH cxx_finish
#undef LANG_HOOKS_CLEAR_BINDING_STACK
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-14 14:07 ` David Edelsohn
@ 2002-03-14 15:02 ` Geoff Keating
0 siblings, 0 replies; 875+ messages in thread
From: Geoff Keating @ 2002-03-14 15:02 UTC (permalink / raw)
To: dje; +Cc: gcc-patches
> Okay now?
Yes, this is OK. Thanks!
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-14 13:47 ` Geoff Keating
2002-03-14 14:07 ` David Edelsohn
@ 2002-03-14 15:24 ` David Edelsohn
2002-03-14 16:57 ` Alan Modra
1 sibling, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-03-14 15:24 UTC (permalink / raw)
To: Geoff Keating, Richard Henderson; +Cc: gcc-patches
Actually, this doesn't work for the reason that I originally
thought: other parts of varasm.c reach into the weak support, e.g.,
globalize_decl() calls remove_from_pending_weak_list().
remove_from_pending_weak_list() now is in c-common, so that fails for F77
and Java.
I can turn globalize_decl() into a hook and maybe assemble_alias()
and assemble_visibility() while I am at it. globalize_decl() now wants
asm_out_file.
Basically, this is leading back to varasm.c and pulling things
out of varasm.c that seem appropriate for that file. Basically this is
turning varasm.c into a giant lang_hook.
I think a better approach may be to turn lookup_name into a
lang_hook because we still need to distinguish between the different
languages for that anyway.
I am going to roll this back and follow that path.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-06 10:59 ` Richard Henderson
` (2 preceding siblings ...)
2002-03-14 11:34 ` David Edelsohn
@ 2002-03-14 16:00 ` David Edelsohn
3 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-03-14 16:00 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
Okay, how about this patch?
* langhooks.h (lang_hooks): Add lookup_name.
* langhooks-def.h (LANG_HOOKS_LOOKUP_NAME): Define.
(LANG_HOOKS_INITIALIZER): Use it.
* varasm.c (weak_finish): Call lookup_name via lang_hooks.
* c-lang.c (LANG_HOOKS_LOOKUP_NAME): Define.
* objc/objc-lang.c (LANG_HOOKS_LOOKUP_NAME): Define.
* cp/cp-lang.c (cxx_lookup_name): New function.
(LANG_HOOKS_LOOKUP_NAME): Use it.
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.256
diff -c -p -r1.256 varasm.c
*** varasm.c 2002/03/13 14:20:17 1.256
--- varasm.c 2002/03/14 23:53:33
*************** weak_finish ()
*** 5078,5084 ****
{
tree name = get_identifier (t->name);
if (name)
! decl = lookup_name (name);
}
ASM_WEAKEN_DECL (asm_out_file, decl, t->name, t->value);
#else
--- 5078,5084 ----
{
tree name = get_identifier (t->name);
if (name)
! decl = (*lang_hooks.lookup_name) (name);
}
ASM_WEAKEN_DECL (asm_out_file, decl, t->name, t->value);
#else
Index: langhooks-def.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/langhooks-def.h,v
retrieving revision 1.10
diff -c -p -r1.10 langhooks-def.h
*** langhooks-def.h 2002/03/08 19:20:47 1.10
--- langhooks-def.h 2002/03/14 23:53:33
*************** void lhd_tree_inlining_end_inlining PAR
*** 78,83 ****
--- 78,84 ----
#define LANG_HOOKS_STATICP lhd_staticp
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL lhd_do_nothing_t
#define LANG_HOOKS_UNSAVE_EXPR_NOW lhd_unsave_expr_now
+ #define LANG_HOOKS_LOOKUP_NAME lhd_return_tree
#define LANG_HOOKS_HONOR_READONLY false
#define LANG_HOOKS_PRINT_STATISTICS lhd_do_nothing
#define LANG_HOOKS_PRINT_XNODE lhd_print_tree_nothing
*************** int lhd_tree_dump_type_quals PARAMS ((
*** 148,153 ****
--- 149,155 ----
LANG_HOOKS_STATICP, \
LANG_HOOKS_DUP_LANG_SPECIFIC_DECL, \
LANG_HOOKS_UNSAVE_EXPR_NOW, \
+ LANG_HOOKS_LOOKUP_NAME, \
LANG_HOOKS_HONOR_READONLY, \
LANG_HOOKS_PRINT_STATISTICS, \
LANG_HOOKS_PRINT_XNODE, \
Index: langhooks.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/langhooks.h,v
retrieving revision 1.17
diff -c -p -r1.17 langhooks.h
*** langhooks.h 2002/03/08 19:20:47 1.17
--- langhooks.h 2002/03/14 23:53:33
*************** struct lang_hooks
*** 137,142 ****
--- 137,145 ----
things are cleared out. */
tree (*unsave_expr_now) PARAMS ((tree));
+ /* Find DECL for NAME. */
+ tree (*lookup_name) PARAMS ((tree));
+
/* Nonzero if TYPE_READONLY and TREE_READONLY should always be honored. */
bool honor_readonly;
Index: c-lang.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-lang.c,v
retrieving revision 1.76
diff -c -p -r1.76 c-lang.c
*** c-lang.c 2002/03/13 01:42:30 1.76
--- c-lang.c 2002/03/14 23:53:33
*************** static void c_post_options PARAMS ((void
*** 57,62 ****
--- 57,64 ----
#define LANG_HOOKS_SET_YYDEBUG c_set_yydebug
#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL c_dup_lang_specific_decl
+ #undef LANG_HOOKS_LOOKUP_NAME
+ #define LANG_HOOKS_LOOKUP_NAME lookup_name
#undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN
#define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \
Index: objc/objc-lang.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/objc/objc-lang.c,v
retrieving revision 1.4
diff -c -p -r1.4 objc-lang.c
*** objc-lang.c 2002/03/13 01:42:43 1.4
--- objc-lang.c 2002/03/14 23:53:33
*************** static void objc_post_options
*** 52,57 ****
--- 52,60 ----
#define LANG_HOOKS_PRINT_IDENTIFIER c_print_identifier
#undef LANG_HOOKS_SET_YYDEBUG
#define LANG_HOOKS_SET_YYDEBUG c_set_yydebug
+ #undef LANG_HOOKS_LOOKUP_NAME
+ #define LANG_HOOKS_LOOKUP_NAME lookup_name
+
/* Inlining hooks same as the C front end. */
#undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN
#define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \
Index: cp/cp-lang.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-lang.c,v
retrieving revision 1.13
diff -c -p -r1.13 cp-lang.c
*** cp-lang.c 2002/03/13 01:42:39 1.13
--- cp-lang.c 2002/03/14 23:53:33
*************** Boston, MA 02111-1307, USA. */
*** 28,33 ****
--- 28,34 ----
#include "langhooks.h"
#include "langhooks-def.h"
+ static tree cxx_lookup_name PARAMS ((tree));
static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
static bool ok_to_generate_alias_set_for_type PARAMS ((tree));
*************** static bool ok_to_generate_alias_set_for
*** 55,60 ****
--- 56,63 ----
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL cxx_dup_lang_specific_decl
#undef LANG_HOOKS_UNSAVE_EXPR_NOW
#define LANG_HOOKS_UNSAVE_EXPR_NOW cxx_unsave_expr_now
+ #undef LANG_HOOKS_LOOKUP_NAME
+ #define LANG_HOOKS_LOOKUP_NAME cxx_lookup_name
#undef LANG_HOOKS_PRINT_STATISTICS
#define LANG_HOOKS_PRINT_STATISTICS cxx_print_statistics
#undef LANG_HOOKS_PRINT_XNODE
*************** static bool ok_to_generate_alias_set_for
*** 99,104 ****
--- 102,116 ----
/* Each front end provides its own hooks, for toplev.c. */
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
+
+ /* Lookup NAME. */
+
+ static tree
+ cxx_lookup_name (t)
+ tree t;
+ {
+ return lookup_name (t, 0);
+ }
/* Check if a C++ type is safe for aliasing.
Return TRUE if T safe for aliasing FALSE otherwise. */
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-14 15:24 ` David Edelsohn
@ 2002-03-14 16:57 ` Alan Modra
2002-03-14 18:05 ` Geoff Keating
0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-03-14 16:57 UTC (permalink / raw)
To: David Edelsohn; +Cc: Geoff Keating, Richard Henderson, gcc-patches
On Thu, Mar 14, 2002 at 06:24:04PM -0500, David Edelsohn wrote:
>
> I think a better approach may be to turn lookup_name into a
> lang_hook because we still need to distinguish between the different
> languages for that anyway.
>
> I am going to roll this back and follow that path.
IMO adding these hooks isn't improving matters at all. The major
problem with the code as of a day or so ago was the call to lookup_decl
from varasm.c. The patch I posted at
http://gcc.gnu.org/ml/gcc-patches/2002-03/msg00308.html cures this, and
also addresses the problem rth mentioned in
http://gcc.gnu.org/ml/gcc-patches/2002-03/msg00298.html
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-14 16:57 ` Alan Modra
@ 2002-03-14 18:05 ` Geoff Keating
2002-03-14 18:35 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-03-14 18:05 UTC (permalink / raw)
To: amodra; +Cc: dje, rth, gcc-patches
> Date: Fri, 15 Mar 2002 11:26:41 +1030
> From: Alan Modra <amodra@bigpond.net.au>
> On Thu, Mar 14, 2002 at 06:24:04PM -0500, David Edelsohn wrote:
> >
> > I think a better approach may be to turn lookup_name into a
> > lang_hook because we still need to distinguish between the different
> > languages for that anyway.
> >
> > I am going to roll this back and follow that path.
>
> IMO adding these hooks isn't improving matters at all. The major
> problem with the code as of a day or so ago was the call to lookup_decl
> from varasm.c. The patch I posted at
> http://gcc.gnu.org/ml/gcc-patches/2002-03/msg00308.html cures this, and
> also addresses the problem rth mentioned in
> http://gcc.gnu.org/ml/gcc-patches/2002-03/msg00298.html
OK, we have two proposals, both of which I've looked at and I think I
understand:
- David's (revised) proposal, which is to add an extra lang_hook to
allow varasm.c to call into the language backends to do name lookup;
and
- Alan Modra's proposal, which moves the initial name lookup to the
backends, and provides a routine in varasm.c which backends can call
before creating a decl to see if they should mark the decl weak.
Now, I have two comments about these that makes me think neither is
the final answer, although they both represent progress.
Firstly, how do these work in C++? In particular, if I write
void bar(void);
namespace foo {
#pragma weak bar
extern void bar(void);
struct c {
void bar(void);
};
}
namespace bat {
extern void bar(void);
}
void doit(void)
{
struct foo::c cc;
bar();
foo::bar();
cc.bar();
bat::bar();
}
do I get foo::bar weak, ::bar weak, everything named 'bar' weak, or
something else? I believe the correct thing is to have foo::bar,
only, be weak. The current compiler seems to make
'extern "C" bar' weak, which indicates (at least to me) that no-one
thought about this at all :-). I believe that Alan's patch will
change this behaviour in an improving direction, but I think from the
description it will pick ::bar, because ::bar's decl is visible at the
point of the pragma under the name 'bar'.
[It's this question that makes me think that the code should really be
part of a language backend. Anything that can't work right for both C
and C++ is clearly so language-specific that it probably doesn't make
any sense at all for, say, Ada, and so it's not surprising that
there are compile errors.]
Secondly, why is this particular code in varasm.c at all? I liked
what David originally tried to do by moving it out (to c-common.c?),
but I think it will require at least part of Alan's patch to avoid the
problems that David hit.
The reason I ask this question is that in some other languages, you
can do this sort of thing in a more organized fashion by writting
things like
attribute bar weak;
attribute bar watched, synchronized;
...
type bar procedure;
and so on, and those languages wouldn't be able to use this mechanism;
it's very specialized for the C languages, and so I would think it
should be somewhere like c-common.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-14 18:05 ` Geoff Keating
@ 2002-03-14 18:35 ` David Edelsohn
2002-03-14 20:07 ` Geoff Keating
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-03-14 18:35 UTC (permalink / raw)
To: Geoff Keating; +Cc: amodra, rth, gcc-patches
>>>>> Geoff Keating writes:
Geoff> Firstly, how do these work in C++? In particular, if I write
Geoff> do I get foo::bar weak, ::bar weak, everything named 'bar' weak, or
Geoff> something else? I believe the correct thing is to have foo::bar,
Geoff> only, be weak. The current compiler seems to make
Geoff> 'extern "C" bar' weak, which indicates (at least to me) that no-one
Geoff> thought about this at all :-). I believe that Alan's patch will
Geoff> change this behaviour in an improving direction, but I think from the
Geoff> description it will pick ::bar, because ::bar's decl is visible at the
Geoff> point of the pragma under the name 'bar'.
Your intuition is wrong with respect to the Solaris C Compiler
semantics for #pragma.
#pragma weak bar
makes "bar" weak. No mangling. If you want mangled bar weak, you need to
explicitly state the mangled string in the pragma. If you want to define
some new, incompatible semantics for #pragma, that is fine, but I'm not
working on it.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-14 18:35 ` David Edelsohn
@ 2002-03-14 20:07 ` Geoff Keating
2002-03-14 21:10 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-03-14 20:07 UTC (permalink / raw)
To: dje; +Cc: amodra, rth, gcc-patches
> cc: amodra@bigpond.net.au, rth@redhat.com, gcc-patches@gcc.gnu.org
> Date: Thu, 14 Mar 2002 21:35:25 -0500
> From: David Edelsohn <dje@watson.ibm.com>
>
> >>>>> Geoff Keating writes:
>
> Geoff> Firstly, how do these work in C++? In particular, if I write
>
> Geoff> do I get foo::bar weak, ::bar weak, everything named 'bar' weak, or
> Geoff> something else? I believe the correct thing is to have foo::bar,
> Geoff> only, be weak. The current compiler seems to make
> Geoff> 'extern "C" bar' weak, which indicates (at least to me) that no-one
> Geoff> thought about this at all :-). I believe that Alan's patch will
> Geoff> change this behaviour in an improving direction, but I think from the
> Geoff> description it will pick ::bar, because ::bar's decl is visible at the
> Geoff> point of the pragma under the name 'bar'.
>
> Your intuition is wrong with respect to the Solaris C Compiler
> semantics for #pragma.
I presume you mean 'C++'.
> #pragma weak bar
>
> makes "bar" weak. No mangling. If you want mangled bar weak, you need to
> explicitly state the mangled string in the pragma. If you want to define
> some new, incompatible semantics for #pragma, that is fine, but I'm not
> working on it.
In that case, the existing code and Alan's patch are incorrect,
because lookup_name doesn't look up mangled names. Problems should be
experienced with something like the following:
namespace bar {
extern "C" void foo(void);
#pragma weak foo
}
extern int foo;
because when weak_finish is being run, 'foo' binds to the toplevel,
which is not the right thing.
Now, this is a different kind of problem. Mangled names are certainly
in the scope of the middle-end. So perhaps the correct fix is to stop
using lookup_name and instead search through the assembler names.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-14 20:07 ` Geoff Keating
@ 2002-03-14 21:10 ` Richard Henderson
2002-03-14 23:03 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-03-14 21:10 UTC (permalink / raw)
To: Geoff Keating; +Cc: dje, amodra, gcc-patches
On Thu, Mar 14, 2002 at 08:07:37PM -0800, Geoff Keating wrote:
> Now, this is a different kind of problem. Mangled names are certainly
> in the scope of the middle-end. So perhaps the correct fix is to stop
> using lookup_name and instead search through the assembler names.
Indeed, identifier_global_value is the function we want.
Sorry for taking so long to get back to this, David. I'm
currently testing the following, which I believe addresses
the issues I raised wrt moving code for the pragma itself,
that Geoff raised wrt C++, and that I raise wrt getting
DECL_WEAK set on the decl.
I also need to formalize the rest of my test cases for
aliases and c++.
r~
* c-decl.c: Include c-pragma.h.
(start_decl, start_function): Invoke maybe_apply_pragma_weak.
(finish_function): Tidy.
* c-pragma.c: Include c-common.h.
(pending_weaks, apply_pragma_weak, maybe_apply_pragma_weak): New.
(handle_pragma_weak): Use them.
(init_pragma): Register pending_weaks.
* c-pragma.h (maybe_apply_pragma_weak): Declare.
* print-tree.c (print_node): Print DECL_WEAK.
* varasm.c (mark_weak_decls): Remove.
(remove_from_pending_weak_list): Remove.
(add_weak): Remove.
(asm_emit_uninitialised): Call globalize_decl for weak commons.
(weak_decls): Make a tree_list.
(declare_weak): Cons weak_decls directly.
(globalize_decl): Remove weak_decls elements directly.
(weak_finish): Simplify weak_decls walk. Don't weaken unused
symbols. Don't pretend to handle aliases.
(init_varasm_once): Update weak_decls registry.
* cp/decl.c: Include c-pragma.h.
(start_decl, start_function): Invoke maybe_apply_pragma_weak.
* gcc.dg/weak-1.c: New.
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.305
diff -c -p -d -u -r1.305 c-decl.c
--- c-decl.c 2002/03/05 02:34:05 1.305
+++ c-decl.c 2002/03/15 05:02:16
@@ -46,6 +46,7 @@ Software Foundation, 59 Temple Place - S
#include "debug.h"
#include "timevar.h"
#include "c-common.h"
+#include "c-pragma.h"
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
enum decl_context
@@ -3403,6 +3404,10 @@ start_decl (declarator, declspecs, initi
/* Set attributes here so if duplicate decl, will have proper attributes. */
decl_attributes (&decl, attributes, 0);
+ /* If #pragma weak was used, mark the decl weak now. */
+ if (current_binding_level == global_binding_level)
+ maybe_apply_pragma_weak (decl);
+
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl)
&& DECL_UNINLINABLE (decl)
@@ -6042,6 +6047,10 @@ start_function (declspecs, declarator, a
decl_attributes (&decl1, attributes, 0);
+ /* If #pragma weak was used, mark the decl weak now. */
+ if (current_binding_level == global_binding_level)
+ maybe_apply_pragma_weak (decl1);
+
if (DECL_DECLARED_INLINE_P (decl1)
&& DECL_UNINLINABLE (decl1)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
@@ -6691,9 +6700,11 @@ finish_function (nested)
{
tree fndecl = current_function_decl;
-/* TREE_READONLY (fndecl) = 1;
- This caused &foo to be of type ptr-to-const-function
- which then got a warning when stored in a ptr-to-function variable. */
+#if 0
+ /* This caused &foo to be of type ptr-to-const-function which then
+ got a warning when stored in a ptr-to-function variable. */
+ TREE_READONLY (fndecl) = 1;
+#endif
poplevel (1, 0, 1);
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
@@ -6755,6 +6766,7 @@ finish_function (nested)
{
/* Generate RTL for the body of this function. */
c_expand_body (fndecl, nested, 1);
+
/* Let the error reporting routines know that we're outside a
function. For a nested function, this value is used in
pop_c_function_context and then reset via pop_function_context. */
Index: c-pragma.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pragma.c,v
retrieving revision 1.47
diff -c -p -d -u -r1.47 c-pragma.c
--- c-pragma.c 2002/03/01 06:00:32 1.47
+++ c-pragma.c 2002/03/15 05:02:16
@@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - S
#include "toplev.h"
#include "ggc.h"
#include "c-lex.h"
+#include "c-common.h"
#include "output.h"
#include "tm_p.h"
@@ -55,9 +56,9 @@ static struct align_stack * alignment_st
maximum_field_alignment in effect. When the final pop_alignment()
happens, we restore the value to this, not to a value of 0 for
maximum_field_alignment. Value is in bits. */
-static int default_alignment;
+static int default_alignment;
#define SET_GLOBAL_ALIGNMENT(ALIGN) \
-(default_alignment = maximum_field_alignment = (ALIGN))
+ (default_alignment = maximum_field_alignment = (ALIGN))
static void push_alignment PARAMS ((int, tree));
static void pop_alignment PARAMS ((tree));
@@ -69,7 +70,6 @@ push_alignment (alignment, id)
int alignment;
tree id;
{
-
if (alignment_stack == NULL
|| alignment_stack->alignment != alignment
|| id != NULL_TREE)
@@ -274,14 +274,53 @@ handle_pragma_pack (dummy)
#endif /* HANDLE_PRAGMA_PACK */
#ifdef HANDLE_PRAGMA_WEAK
+static void apply_pragma_weak PARAMS ((tree, tree));
static void handle_pragma_weak PARAMS ((cpp_reader *));
+static tree pending_weaks;
+
+static void
+apply_pragma_weak (decl, value)
+ tree decl, value;
+{
+ if (value)
+ decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
+ build_tree_list (NULL, value)),
+ 0);
+ declare_weak (decl);
+}
+
+void
+maybe_apply_pragma_weak (decl)
+ tree decl;
+{
+ tree *p, t, id;
+
+ /* Copied from the check in set_decl_assembler_name. */
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ || (TREE_CODE (decl) == VAR_DECL
+ && (TREE_STATIC (decl)
+ || DECL_EXTERNAL (decl)
+ || TREE_PUBLIC (decl))))
+ id = DECL_ASSEMBLER_NAME (decl);
+ else
+ return;
+
+ for (p = &pending_weaks; (t = *p) ; p = &TREE_CHAIN (t))
+ if (id == TREE_PURPOSE (t))
+ {
+ apply_pragma_weak (decl, TREE_VALUE (t));
+ *p = TREE_CHAIN (t);
+ break;
+ }
+}
+
/* #pragma weak name [= value] */
static void
handle_pragma_weak (dummy)
cpp_reader *dummy ATTRIBUTE_UNUSED;
{
- tree name, value, x;
+ tree name, value, x, decl;
enum cpp_ttype t;
value = 0;
@@ -298,10 +337,19 @@ handle_pragma_weak (dummy)
if (t != CPP_EOF)
warning ("junk at end of #pragma weak");
- add_weak (NULL_TREE, IDENTIFIER_POINTER (name),
- value ? IDENTIFIER_POINTER (value) : NULL);
+ decl = identifier_global_value (name);
+ if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+ apply_pragma_weak (decl, value);
+ else
+ pending_weaks = tree_cons (name, value, pending_weaks);
}
-#endif
+#else
+void
+maybe_apply_pragma_weak (decl)
+ tree decl ATTRIBUTE_UNUSED;
+{
+}
+#endif /* HANDLE_PRAGMA_WEAK */
void
init_pragma ()
@@ -311,6 +359,7 @@ init_pragma ()
#endif
#ifdef HANDLE_PRAGMA_WEAK
cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
+ ggc_add_tree_root (&pending_weaks, 1);
#endif
#ifdef REGISTER_TARGET_PRAGMAS
REGISTER_TARGET_PRAGMAS (parse_in);
Index: c-pragma.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pragma.h,v
retrieving revision 1.27
diff -c -p -d -u -r1.27 c-pragma.h
--- c-pragma.h 2002/03/01 06:00:32 1.27
+++ c-pragma.h 2002/03/15 05:02:16
@@ -53,4 +53,6 @@ extern void cpp_register_pragma PARAMS (
void (*) PARAMS ((cpp_reader *))));
#endif
+extern void maybe_apply_pragma_weak PARAMS ((tree));
+
#endif /* GCC_C_PRAGMA_H */
Index: print-tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/print-tree.c,v
retrieving revision 1.55
diff -c -p -d -u -r1.55 print-tree.c
--- print-tree.c 2002/03/03 21:09:46 1.55
+++ print-tree.c 2002/03/15 05:02:16
@@ -317,6 +317,8 @@ print_node (file, prefix, node, indent)
fputs (" common", file);
if (DECL_EXTERNAL (node))
fputs (" external", file);
+ if (DECL_WEAK (node))
+ fputs (" weak", file);
if (DECL_REGISTER (node) && TREE_CODE (node) != FIELD_DECL
&& TREE_CODE (node) != FUNCTION_DECL
&& TREE_CODE (node) != LABEL_DECL)
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.256
diff -c -p -d -u -r1.256 varasm.c
--- varasm.c 2002/03/13 14:20:17 1.256
+++ varasm.c 2002/03/15 05:02:16
@@ -167,10 +167,6 @@ static unsigned HOST_WIDE_INT array_size
static unsigned min_align PARAMS ((unsigned, unsigned));
static void output_constructor PARAMS ((tree, HOST_WIDE_INT,
unsigned int));
-static void mark_weak_decls PARAMS ((void *));
-#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
-static void remove_from_pending_weak_list PARAMS ((const char *));
-#endif
static void globalize_decl PARAMS ((tree));
static void maybe_assemble_visibility PARAMS ((tree));
static int in_named_entry_eq PARAMS ((const PTR, const PTR));
@@ -1399,6 +1395,17 @@ asm_emit_uninitialised (decl, name, size
destination = asm_dest_common;
}
+ switch (destination)
+ {
+ case asm_dest_common:
+ if (! DECL_WEAK (decl))
+ break;
+ case asm_dest_bss:
+ globalize_decl (decl);
+ default:
+ break;
+ }
+
if (flag_shared_data)
{
switch (destination)
@@ -1429,7 +1436,6 @@ asm_emit_uninitialised (decl, name, size
{
#ifdef ASM_EMIT_BSS
case asm_dest_bss:
- globalize_decl (decl);
ASM_EMIT_BSS (decl, name, size, rounded);
break;
#endif
@@ -4993,56 +4999,10 @@ output_constructor (exp, size, align)
if (total_bytes < size)
assemble_zeros (size - total_bytes);
}
-
-/* This structure contains any weak symbol declarations waiting
+/* This TREE_LIST contains any weak symbol declarations waiting
to be emitted. */
-struct weak_syms
-{
- struct weak_syms * next;
- tree decl;
- const char * name;
- const char * value;
-};
-
-static struct weak_syms * weak_decls;
-
-/* Mark weak_decls for garbage collection. */
-
-static void
-mark_weak_decls (arg)
- void *arg;
-{
- struct weak_syms *t;
-
- for (t = *(struct weak_syms **) arg; t != NULL; t = t->next)
- ggc_mark_tree (t->decl);
-}
-
-/* Add function NAME to the weak symbols list. VALUE is a weak alias
- associated with NAME. */
-
-int
-add_weak (decl, name, value)
- tree decl;
- const char *name;
- const char *value;
-{
- struct weak_syms *weak;
-
- weak = (struct weak_syms *) xmalloc (sizeof (struct weak_syms));
-
- if (weak == NULL)
- return 0;
-
- weak->next = weak_decls;
- weak->decl = decl;
- weak->name = name;
- weak->value = value;
- weak_decls = weak;
-
- return 1;
-}
+static tree weak_decls;
/* Declare DECL to be a weak symbol. */
@@ -5055,7 +5015,10 @@ declare_weak (decl)
else if (TREE_ASM_WRITTEN (decl))
error_with_decl (decl, "weak declaration of `%s' must precede definition");
else if (SUPPORTS_WEAK)
- add_weak (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), NULL);
+ {
+ if (! DECL_WEAK (decl))
+ weak_decls = tree_cons (NULL, decl, weak_decls);
+ }
else
warning_with_decl (decl, "weak declaration of `%s' not supported");
@@ -5067,59 +5030,30 @@ declare_weak (decl)
void
weak_finish ()
{
- if (SUPPORTS_WEAK)
+ tree t;
+
+ for (t = weak_decls; t ; t = TREE_CHAIN (t))
{
- struct weak_syms *t;
- for (t = weak_decls; t != NULL; t = t->next)
- {
+ tree decl = TREE_VALUE (t);
+ const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
+ if (! TREE_USED (decl))
+ continue;
+
#ifdef ASM_WEAKEN_DECL
- tree decl = t->decl;
- if (decl == NULL_TREE)
- {
- tree name = get_identifier (t->name);
- if (name)
- decl = lookup_name (name);
- }
- ASM_WEAKEN_DECL (asm_out_file, decl, t->name, t->value);
-#else
-#ifdef ASM_OUTPUT_WEAK_ALIAS
- ASM_OUTPUT_WEAK_ALIAS (asm_out_file, t->name, t->value);
+ ASM_WEAKEN_DECL (asm_out_file, decl, name, NULL);
#else
#ifdef ASM_WEAKEN_LABEL
- if (t->value)
- abort ();
- ASM_WEAKEN_LABEL (asm_out_file, t->name);
+ ASM_WEAKEN_LABEL (asm_out_file, name);
+#else
+#ifdef ASM_OUTPUT_WEAK_ALIAS
+ warning ("only weak aliases are supported in this configuration");
+ return;
#endif
#endif
#endif
- }
- }
-}
-
-/* Remove NAME from the pending list of weak symbols. This prevents
- the compiler from emitting multiple .weak directives which confuses
- some assemblers. */
-#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
-static void
-remove_from_pending_weak_list (name)
- const char *name;
-{
- struct weak_syms *t;
- struct weak_syms **p;
-
- for (p = &weak_decls; *p; )
- {
- t = *p;
- if (strcmp (name, t->name) == 0)
- {
- *p = t->next;
- free (t);
- }
- else
- p = &(t->next);
}
}
-#endif /* defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL) */
/* Emit the assembly bits to indicate that DECL is globally visible. */
@@ -5132,18 +5066,26 @@ globalize_decl (decl)
#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
if (DECL_WEAK (decl))
{
+ tree *p, t;
+
#ifdef ASM_WEAKEN_DECL
ASM_WEAKEN_DECL (asm_out_file, decl, name, 0);
#else
ASM_WEAKEN_LABEL (asm_out_file, name);
#endif
+
/* Remove this function from the pending weak list so that
we do not emit multiple .weak directives for it. */
- remove_from_pending_weak_list (name);
+ for (p = &weak_decls; (t = *p) ; p = &TREE_CHAIN (t))
+ if (TREE_VALUE (t) == decl)
+ {
+ *p = TREE_CHAIN (t);
+ break;
+ }
return;
}
- /* else */
#endif
+
ASM_GLOBALIZE_LABEL (asm_out_file, name);
}
@@ -5168,7 +5110,6 @@ assemble_alias (decl, target)
if (TREE_PUBLIC (decl))
{
globalize_decl (decl);
-
maybe_assemble_visibility (decl);
}
@@ -5282,7 +5223,7 @@ init_varasm_once ()
mark_const_hash_entry);
ggc_add_root (&const_str_htab, 1, sizeof const_str_htab,
mark_const_str_htab);
- ggc_add_root (&weak_decls, 1, sizeof weak_decls, mark_weak_decls);
+ ggc_add_tree_root (&weak_decls, 1);
const_alias_set = new_alias_set ();
}
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.873
diff -c -p -d -u -r1.873 decl.c
--- decl.c 2002/03/13 17:12:22 1.873
+++ decl.c 2002/03/15 05:02:16
@@ -46,6 +46,7 @@ Boston, MA 02111-1307, USA. */
#include "tm_p.h"
#include "target.h"
#include "c-common.h"
+#include "c-pragma.h"
#include "diagnostic.h"
extern const struct attribute_spec *lang_attribute_table;
@@ -7256,6 +7257,10 @@ start_decl (declarator, declspecs, initi
/* Set attributes here so if duplicate decl, will have proper attributes. */
cplus_decl_attributes (&decl, attributes, 0);
+ /* If #pragma weak was used, mark the decl weak now. */
+ if (current_binding_level == global_binding_level)
+ maybe_apply_pragma_weak (decl);
+
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl)
&& DECL_UNINLINABLE (decl)
@@ -13475,6 +13480,10 @@ start_function (declspecs, declarator, a
return 0;
cplus_decl_attributes (&decl1, attrs, 0);
+
+ /* If #pragma weak was used, mark the decl weak now. */
+ if (current_binding_level == global_binding_level)
+ maybe_apply_pragma_weak (decl1);
fntype = TREE_TYPE (decl1);
Index: testsuite/gcc.dg/weak-1.c
===================================================================
RCS file: weak-1.c
diff -N weak-1.c
--- /dev/null Tue May 5 13:32:27 1998
+++ weak-1.c Thu Mar 14 21:02:16 2002
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* COFF does not support weak, and dg doesn't support UNSUPPORTED. */
+/* { dg-do compile { xfail *-*-coff i?86-pc-cygwin } } */
+
+/* { dg-final { scan-assembler "weak[^ ]*[ ]_?a" } } */
+/* { dg-final { scan-assembler "weak[^ ]*[ ]_?b" } } */
+/* { dg-final { scan-assembler "weak[^ ]*[ ]_?c" } } */
+/* { dg-final { scan-assembler "weak[^ ]*[ ]_?d" } } */
+/* { dg-final { scan-assembler "weak[^ ]*[ ]_?e" } } */
+/* { dg-final { scan-assembler "weak[^ ]*[ ]_?g" } } */
+/* { dg-final { scan-assembler-not "weak[^ ]*[ ]_?i" } } */
+/* { dg-final { scan-assembler "weak[^ ]*[ ]_?j" } } */
+
+#pragma weak a
+int a;
+
+int b;
+#pragma weak b
+
+#pragma weak c
+extern int c;
+int c;
+
+extern int d;
+#pragma weak d
+int d;
+
+#pragma weak e
+void e(void) { }
+
+#if 0
+/* This permutation is illegal. */
+void f(void) { }
+#pragma weak f
+#endif
+
+#pragma weak g
+int g = 1;
+
+#if 0
+/* This permutation is illegal. */
+int h = 1;
+#pragma weak h
+#endif
+
+#pragma weak i
+extern int i;
+
+#pragma weak j
+extern int j;
+int use_j() { return j; }
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-14 21:10 ` Richard Henderson
@ 2002-03-14 23:03 ` Richard Henderson
2002-03-15 8:20 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-03-14 23:03 UTC (permalink / raw)
To: Geoff Keating, dje, amodra, gcc-patches
Ok, this passed regression testing on alpha-linux, so I went ahead
and checked it in to mainline. Did this need to get backported to
the branch?
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-14 23:03 ` Richard Henderson
@ 2002-03-15 8:20 ` David Edelsohn
2002-03-15 17:01 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-03-15 8:20 UTC (permalink / raw)
To: Richard Henderson, Geoff Keating, amodra, gcc-patches
>>>>> Richard Henderson writes:
Richard> Ok, this passed regression testing on alpha-linux, so I went ahead
Richard> and checked it in to mainline. Did this need to get backported to
Richard> the branch?
Yes, we need this patch on the 3.1 branch as well for glibc on
ppc64 Linux.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-15 8:20 ` David Edelsohn
@ 2002-03-15 17:01 ` Richard Henderson
2002-03-19 16:40 ` Alan Modra
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-03-15 17:01 UTC (permalink / raw)
To: David Edelsohn; +Cc: amodra, gcc-patches
On Fri, Mar 15, 2002 at 11:20:11AM -0500, David Edelsohn wrote:
> Richard> Ok, this passed regression testing on alpha-linux, so I went ahead
> Richard> and checked it in to mainline. Did this need to get backported to
> Richard> the branch?
>
> Yes, we need this patch on the 3.1 branch as well for glibc on
> ppc64 Linux.
Ok, applied. Note that Alan's ASM_WEAKEN_DECL patch is not
yet on the branch, which is what you were after in the first
place. I'll let him one of you merge that.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-15 17:01 ` Richard Henderson
@ 2002-03-19 16:40 ` Alan Modra
2002-03-19 17:02 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-03-19 16:40 UTC (permalink / raw)
To: Richard Henderson, gcc-patches
On Fri, Mar 15, 2002 at 05:00:59PM -0800, Richard Henderson wrote:
>
> Ok, applied. Note that Alan's ASM_WEAKEN_DECL patch is not
One or two things were missed.
* defaults.h (SUPPORTS_WEAK): Set if ASM_WEAKEN_DECL.
* varasm.c (assemble_alias): Use ASM_WEAKEN_DECL.
* doc/tm.texi (ASM_WEAKEN_DECL): Document.
(ASM_WEAKEN_LABEL): Mention ASM_WEAKEN_DECL.
(SUPPORTS_WEAK): Likewise.
OK to apply to 3.1 ?
--
Alan Modra
IBM OzLabs - Linux Technology Centre
diff -urpN -xCVS -x*~ -xTAGS gcc-ppc64-31.orig/gcc/defaults.h gcc-ppc64-31/gcc/defaults.h
--- gcc-ppc64-31.orig/gcc/defaults.h Mon Mar 18 19:16:31 2002
+++ gcc-ppc64-31/gcc/defaults.h Wed Mar 20 09:54:47 2002
@@ -1,5 +1,5 @@
/* Definitions of various defaults for tm.h macros.
- Copyright (C) 1992, 1996, 1997, 1998, 1999, 2000, 2001
+ Copyright (C) 1992, 1996, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com)
@@ -158,7 +158,7 @@ do { ASM_OUTPUT_LABEL(FILE,LABEL_ALTERNA
/* This determines whether or not we support weak symbols. */
#ifndef SUPPORTS_WEAK
-#ifdef ASM_WEAKEN_LABEL
+#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
#define SUPPORTS_WEAK 1
#else
#define SUPPORTS_WEAK 0
diff -urpN -xCVS -x*~ -xTAGS gcc-ppc64-31.orig/gcc/varasm.c gcc-ppc64-31/gcc/varasm.c
--- gcc-ppc64-31.orig/gcc/varasm.c Mon Mar 18 19:16:31 2002
+++ gcc-ppc64-31/gcc/varasm.c Wed Mar 20 09:54:47 2002
@@ -5106,12 +5106,16 @@ assemble_alias (decl, target)
ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
#endif
TREE_ASM_WRITTEN (decl) = 1;
-#else
-#ifdef ASM_OUTPUT_WEAK_ALIAS
+#else /* !ASM_OUTPUT_DEF */
+#if defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL)
if (! DECL_WEAK (decl))
warning ("only weak aliases are supported in this configuration");
+#ifdef ASM_WEAKEN_DECL
+ ASM_WEAKEN_DECL (asm_out_file, decl, name, IDENTIFIER_POINTER (target));
+#else
ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
+#endif
TREE_ASM_WRITTEN (decl) = 1;
#else
warning ("alias definitions not supported in this configuration; ignored");
diff -urpN -xCVS -x*~ -xTAGS gcc-ppc64-31.orig/gcc/doc/tm.texi gcc-ppc64-31/gcc/doc/tm.texi
--- gcc-ppc64-31.orig/gcc/doc/tm.texi Mon Mar 18 19:16:31 2002
+++ gcc-ppc64-31/gcc/doc/tm.texi Wed Mar 20 09:54:47 2002
@@ -6174,7 +6174,7 @@ itself; before and after that, output th
for making that name global, and a newline.
@findex ASM_WEAKEN_LABEL
-@item ASM_WEAKEN_LABEL
+@item ASM_WEAKEN_LABEL (@var{stream}, @var{name})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} some commands that will make the label @var{name} weak;
that is, available for reference from other files but only used if
@@ -6183,18 +6183,29 @@ no other definition is available. Use t
itself; before and after that, output the additional assembler syntax
for making that name weak, and a newline.
-If you don't define this macro, GCC will not support weak
-symbols and you should not define the @code{SUPPORTS_WEAK} macro.
+If you don't define this macro or @code{ASM_WEAKEN_DECL}, GCC will not
+support weak symbols and you should not define the @code{SUPPORTS_WEAK}
+macro.
+
+@findex ASM_WEAKEN_DECL
+@item ASM_WEAKEN_DECL (@var{stream}, @var{decl}, @var{name}, @var{value})
+Combines (and replaces) the function of @code{ASM_WEAKEN_LABEL} and
+@code{ASM_OUTPUT_WEAK_ALIAS}, allowing access to the associated function
+or variable decl. If @var{value} is not @code{NULL}, this C statement
+should output to the stdio stream @var{stream} assembler code which
+defines (equates) the weak symbol @var{name} to have the value
+@var{value}. If @var{value} is @code{NULL}, it should output commands
+to make @var{name} weak.
@findex SUPPORTS_WEAK
@item SUPPORTS_WEAK
A C expression which evaluates to true if the target supports weak symbols.
If you don't define this macro, @file{defaults.h} provides a default
-definition. If @code{ASM_WEAKEN_LABEL} is defined, the default
-definition is @samp{1}; otherwise, it is @samp{0}. Define this macro if
-you want to control weak symbol support with a compiler flag such as
-@option{-melf}.
+definition. If either @code{ASM_WEAKEN_LABEL} or @code{ASM_WEAKEN_DECL}
+is defined, the default definition is @samp{1}; otherwise, it is
+@samp{0}. Define this macro if you want to control weak symbol support
+with a compiler flag such as @option{-melf}.
@findex MAKE_DECL_ONE_ONLY (@var{decl})
@item MAKE_DECL_ONE_ONLY
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: f build dies with: undefined reference to `lookup_name'
2002-03-19 16:40 ` Alan Modra
@ 2002-03-19 17:02 ` Richard Henderson
0 siblings, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-03-19 17:02 UTC (permalink / raw)
To: gcc-patches
On Wed, Mar 20, 2002 at 11:10:17AM +1030, Alan Modra wrote:
> * defaults.h (SUPPORTS_WEAK): Set if ASM_WEAKEN_DECL.
> * varasm.c (assemble_alias): Use ASM_WEAKEN_DECL.
> * doc/tm.texi (ASM_WEAKEN_DECL): Document.
> (ASM_WEAKEN_LABEL): Mention ASM_WEAKEN_DECL.
> (SUPPORTS_WEAK): Likewise.
>
> OK to apply to 3.1 ?
Yes.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* thread-local storage: c front end and generic backend patch
@ 2002-05-21 18:54 Richard Henderson
2002-05-22 4:25 ` Joseph S. Myers
` (2 more replies)
0 siblings, 3 replies; 875+ messages in thread
From: Richard Henderson @ 2002-05-21 18:54 UTC (permalink / raw)
To: gcc-patches; +Cc: Joseph S. Myers
[-- Attachment #1: Type: text/plain, Size: 789 bytes --]
The following adds support in the C front end for a new
storage specifier keyword "__thread" that marks a variable
to be allocated in storage private to every extant thread.
A similar patch for the C++ front end will follow directly;
I wanted to split that out for ease of review by the C++
front end folk.
Joseph, the extend.texi documentation has some user-level
description of the extension. I've tried to come up with
a set of edits for C99, but I'm not sure where to put them,
or exactly what form they should take. Thoughts?
There is a fledgeling testsuite here, but it won't get run
until you have target support as well. I have x86 support
completed, and it'll get submitted as soon as I clean it up
properly and add some autoconf detection logic for binutils
support.
r~
[-- Attachment #2: tls-iso-changes --]
[-- Type: text/plain, Size: 1456 bytes --]
ISO/IEC 9899:1999 edits for thread-local storage:
6.2.4 Storage durations of objects
P3: Add new paragraph before
An object whose identifier is declared with the storage-class
specifier @code{__thread} has @dfn{thread storage duration}.
Its lifetime is the entire execution of the thread, and its
stored value is initialized only once, prior to thread startup.
6.5.3.2 Address and indirection operators
P3:
[ I don't think any change is required here. The explicit
semantics of @code{&} require that the result be the address
of the tls variable within the current thread, but I don't
see that at odds with "returns the address of its operand". ]
6.6 Constant expressions
P9:
[ No change here, since we've defined @code{__thread} variables
to have thread storage duration, not static storage duration,
and that isn't listed as legal. ]
6.7.1 Storage-class specifiers
P1: Add @code{__thread}.
P2: Change to
With the exception of @code{__thread}, at most one storage-class
specifier may be given [...]. The @code{__thread} specifier may
be used alone, or immediately following @code{extern} or
@code{static}.
P6: Add new paragraph after
The declaration of an identifier for a variable that has
block scope that specifies @code{__thread} shall also
specify either @code{extern} or @code{static}.
The @code{__thread} specifier shall be used only with
variables.
[-- Attachment #3: d-tls-32-1 --]
[-- Type: text/plain, Size: 37346 bytes --]
* c-common.h (enum rid): Add RID_THREAD.
* c-decl.c (start_decl): Do not set DECL_COMMON for tls variables.
(grokdeclarator): Grok __thread.
* c-parse.in (reswords): Add __thread.
(rid_to_yy): Add RID_THREAD.
* tree.h (DECL_THREAD_LOCAL): New.
(struct tree_decl): Add thread_local_flag.
* print-tree.c (print_node): Dump DECL_THREAD_LOCAL.
* tree.c (staticp): TLS variables are not static.
* target-def.h (TARGET_HAVE_TLS): New.
* target.h (have_tls): New.
* output.h (SECTION_TLS): New.
* varasm.c (assemble_variable): TLS variables can't be common for now.
(default_section_type_flags): Handle .tdata and .tbss.
(default_elf_asm_named_section): Handle SECTION_TLS.
(categorize_decl_for_section): Handle DECL_THREAD_LOCAL.
* flags.h (flag_tls_default): Declare.
* toplev.c (flag_tls_default): Define.
(display_help): Display help for it.
(decode_f_option): Set it.
* doc/extend.texi (Thread-Local): New node describing language-level
thread-local storage.
* doc/invoke.texi (-ftls-model): Document.
* fixinc/inclhack.def (thread_keyword): New.
* fixinc/fixincl.x: Rebuild.
cp/
* lex.c (rid_to_yy): Add RID_THREAD.
testsuite/
* gcc.dg/tls/tls.exp, gcc.dg/tls/trivial.c, gcc.dg/tls/diag-1.c,
gcc.dg/tls/diag-2.c, gcc.dg/tls/init-1.c: New directory and files.
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.136
diff -c -p -d -r1.136 c-common.h
*** c-common.h 18 May 2002 19:02:01 -0000 1.136
--- c-common.h 21 May 2002 22:10:18 -0000
*************** enum rid
*** 58,64 ****
RID_VOLATILE, RID_SIGNED, RID_AUTO, RID_RESTRICT,
/* C extensions */
! RID_BOUNDED, RID_UNBOUNDED, RID_COMPLEX,
/* C++ */
RID_FRIEND, RID_VIRTUAL, RID_EXPLICIT, RID_EXPORT, RID_MUTABLE,
--- 58,64 ----
RID_VOLATILE, RID_SIGNED, RID_AUTO, RID_RESTRICT,
/* C extensions */
! RID_BOUNDED, RID_UNBOUNDED, RID_COMPLEX, RID_THREAD,
/* C++ */
RID_FRIEND, RID_VIRTUAL, RID_EXPLICIT, RID_EXPORT, RID_MUTABLE,
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.326
diff -c -p -d -r1.326 c-decl.c
*** c-decl.c 18 May 2002 19:02:02 -0000 1.326
--- c-decl.c 21 May 2002 22:10:19 -0000
*************** start_decl (declarator, declspecs, initi
*** 3350,3358 ****
/* ANSI specifies that a tentative definition which is not merged with
a non-tentative definition behaves exactly like a definition with an
initializer equal to zero. (Section 3.7.2)
! -fno-common gives strict ANSI behavior. Usually you don't want it.
! This matters only for variables with external linkage. */
! if (!initialized && (! flag_no_common || ! TREE_PUBLIC (decl)))
DECL_COMMON (decl) = 1;
/* Set attributes here so if duplicate decl, will have proper attributes. */
--- 3350,3368 ----
/* ANSI specifies that a tentative definition which is not merged with
a non-tentative definition behaves exactly like a definition with an
initializer equal to zero. (Section 3.7.2)
!
! -fno-common gives strict ANSI behavior, though this tends to break
! a large body of code that grew up without this rule.
!
! Thread-local variables are never common, since there's no entrenched
! body of code to break, and it allows more efficient variable references
! in the presense of dynamic linking. */
!
! if (TREE_CODE (decl) == VAR_DECL
! && !initialized
! && TREE_PUBLIC (decl)
! && !DECL_THREAD_LOCAL (decl)
! && !flag_no_common)
DECL_COMMON (decl) = 1;
/* Set attributes here so if duplicate decl, will have proper attributes. */
*************** grokdeclarator (declarator, declspecs, d
*** 3933,3939 ****
enum rid i = C_RID_CODE (id);
if ((int) i <= (int) RID_LAST_MODIFIER)
{
! if (i == RID_LONG && (specbits & (1 << (int) i)))
{
if (longlong)
error ("`long long long' is too long for GCC");
--- 3943,3949 ----
enum rid i = C_RID_CODE (id);
if ((int) i <= (int) RID_LAST_MODIFIER)
{
! if (i == RID_LONG && (specbits & (1 << (int) RID_LONG)))
{
if (longlong)
error ("`long long long' is too long for GCC");
*************** grokdeclarator (declarator, declspecs, d
*** 3947,3952 ****
--- 3957,3975 ----
}
else if (specbits & (1 << (int) i))
pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
+
+ /* Diagnose "__thread extern". Recall that this list
+ is in the reverse order seen in the text. */
+ if (i == RID_THREAD
+ && (specbits & (1 << (int) RID_EXTERN
+ | 1 << (int) RID_STATIC)))
+ {
+ if (specbits & 1 << (int) RID_EXTERN)
+ error ("`__thread' before `extern'");
+ else
+ error ("`__thread' before `static'");
+ }
+
specbits |= 1 << (int) i;
goto found;
}
*************** grokdeclarator (declarator, declspecs, d
*** 4196,4201 ****
--- 4219,4230 ----
if (specbits & 1 << (int) RID_REGISTER) nclasses++;
if (specbits & 1 << (int) RID_TYPEDEF) nclasses++;
+ /* "static __thread" and "extern __thread" are allowed. */
+ if ((specbits & (1 << (int) RID_THREAD
+ | 1 << (int) RID_STATIC
+ | 1 << (int) RID_EXTERN)) == (1 << (int) RID_THREAD))
+ nclasses++;
+
/* Warn about storage classes that are invalid for certain
kinds of declarations (parameters, typenames, etc.). */
*************** grokdeclarator (declarator, declspecs, d
*** 4205,4211 ****
&& (specbits
& ((1 << (int) RID_REGISTER)
| (1 << (int) RID_AUTO)
! | (1 << (int) RID_TYPEDEF))))
{
if (specbits & 1 << (int) RID_AUTO
&& (pedantic || current_binding_level == global_binding_level))
--- 4234,4241 ----
&& (specbits
& ((1 << (int) RID_REGISTER)
| (1 << (int) RID_AUTO)
! | (1 << (int) RID_TYPEDEF)
! | (1 << (int) RID_THREAD))))
{
if (specbits & 1 << (int) RID_AUTO
&& (pedantic || current_binding_level == global_binding_level))
*************** grokdeclarator (declarator, declspecs, d
*** 4214,4221 ****
error ("function definition declared `register'");
if (specbits & 1 << (int) RID_TYPEDEF)
error ("function definition declared `typedef'");
specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
! | (1 << (int) RID_AUTO));
}
else if (decl_context != NORMAL && nclasses > 0)
{
--- 4244,4253 ----
error ("function definition declared `register'");
if (specbits & 1 << (int) RID_TYPEDEF)
error ("function definition declared `typedef'");
+ if (specbits & 1 << (int) RID_THREAD)
+ error ("function definition declared `__thread'");
specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
! | (1 << (int) RID_AUTO) | (1 << (int) RID_THREAD));
}
else if (decl_context != NORMAL && nclasses > 0)
{
*************** grokdeclarator (declarator, declspecs, d
*** 4238,4244 ****
}
specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
| (1 << (int) RID_AUTO) | (1 << (int) RID_STATIC)
! | (1 << (int) RID_EXTERN));
}
}
else if (specbits & 1 << (int) RID_EXTERN && initialized && ! funcdef_flag)
--- 4270,4276 ----
}
specbits &= ~((1 << (int) RID_TYPEDEF) | (1 << (int) RID_REGISTER)
| (1 << (int) RID_AUTO) | (1 << (int) RID_STATIC)
! | (1 << (int) RID_EXTERN) | (1 << (int) RID_THREAD));
}
}
else if (specbits & 1 << (int) RID_EXTERN && initialized && ! funcdef_flag)
*************** grokdeclarator (declarator, declspecs, d
*** 4249,4260 ****
else
error ("`%s' has both `extern' and initializer", name);
}
! else if (specbits & 1 << (int) RID_EXTERN && funcdef_flag
! && current_binding_level != global_binding_level)
! error ("nested function `%s' declared `extern'", name);
! else if (current_binding_level == global_binding_level
! && specbits & (1 << (int) RID_AUTO))
! error ("top-level declaration of `%s' specifies `auto'", name);
}
/* Now figure out the structure of the declarator proper.
--- 4281,4305 ----
else
error ("`%s' has both `extern' and initializer", name);
}
! else if (current_binding_level == global_binding_level)
! {
! if (specbits & 1 << (int) RID_AUTO)
! error ("top-level declaration of `%s' specifies `auto'", name);
! }
! else
! {
! if (specbits & 1 << (int) RID_EXTERN && funcdef_flag)
! error ("nested function `%s' declared `extern'", name);
! else if ((specbits & (1 << (int) RID_THREAD
! | 1 << (int) RID_EXTERN
! | 1 << (int) RID_STATIC))
! == (1 << (int) RID_THREAD))
! {
! error ("function-scope `%s' implicitly auto and declared `__thread'",
! name);
! specbits &= ~(1 << (int) RID_THREAD);
! }
! }
}
/* Now figure out the structure of the declarator proper.
*************** grokdeclarator (declarator, declspecs, d
*** 4842,4847 ****
--- 4887,4894 ----
pedwarn ("invalid storage class for function `%s'", name);
if (specbits & (1 << (int) RID_REGISTER))
error ("invalid storage class for function `%s'", name);
+ if (specbits & (1 << (int) RID_THREAD))
+ error ("invalid storage class for function `%s'", name);
/* Function declaration not at top level.
Storage classes other than `extern' are not allowed
and `extern' makes no difference. */
*************** grokdeclarator (declarator, declspecs, d
*** 4934,4955 ****
pedwarn_with_decl (decl, "variable `%s' declared `inline'");
DECL_EXTERNAL (decl) = extern_ref;
/* At top level, the presence of a `static' or `register' storage
class specifier, or the absence of all storage class specifiers
makes this declaration a definition (perhaps tentative). Also,
the absence of both `static' and `register' makes it public. */
if (current_binding_level == global_binding_level)
{
! TREE_PUBLIC (decl)
! = !(specbits
! & ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER)));
! TREE_STATIC (decl) = ! DECL_EXTERNAL (decl);
}
/* Not at top level, only `static' makes a static definition. */
else
{
TREE_STATIC (decl) = (specbits & (1 << (int) RID_STATIC)) != 0;
! TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);
}
}
--- 4981,5012 ----
pedwarn_with_decl (decl, "variable `%s' declared `inline'");
DECL_EXTERNAL (decl) = extern_ref;
+
/* At top level, the presence of a `static' or `register' storage
class specifier, or the absence of all storage class specifiers
makes this declaration a definition (perhaps tentative). Also,
the absence of both `static' and `register' makes it public. */
if (current_binding_level == global_binding_level)
{
! TREE_PUBLIC (decl) = !(specbits & ((1 << (int) RID_STATIC)
! | (1 << (int) RID_REGISTER)));
! TREE_STATIC (decl) = !extern_ref;
}
/* Not at top level, only `static' makes a static definition. */
else
{
TREE_STATIC (decl) = (specbits & (1 << (int) RID_STATIC)) != 0;
! TREE_PUBLIC (decl) = extern_ref;
! }
!
! if (specbits & 1 << (int) RID_THREAD)
! {
! if (targetm.have_tls)
! DECL_THREAD_LOCAL (decl) = 1;
! else
! /* A mere warning is sure to result in improper semantics
! at runtime. Don't bother to allow this to compile. */
! error ("thread-local storage not supported for this target");
}
}
Index: c-parse.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.139
diff -c -p -d -r1.139 c-parse.in
*** c-parse.in 27 Apr 2002 06:53:06 -0000 1.139
--- c-parse.in 21 May 2002 22:10:19 -0000
*************** static const struct resword reswords[] =
*** 3343,3348 ****
--- 3343,3349 ----
{ "__restrict__", RID_RESTRICT, 0 },
{ "__signed", RID_SIGNED, 0 },
{ "__signed__", RID_SIGNED, 0 },
+ { "__thread", RID_THREAD, 0 },
{ "__typeof", RID_TYPEOF, 0 },
{ "__typeof__", RID_TYPEOF, 0 },
{ "__unbounded", RID_UNBOUNDED, 0 },
*************** static const short rid_to_yy[RID_MAX] =
*** 3438,3443 ****
--- 3439,3445 ----
/* RID_BOUNDED */ TYPE_QUAL,
/* RID_UNBOUNDED */ TYPE_QUAL,
/* RID_COMPLEX */ TYPESPEC,
+ /* RID_THREAD */ SCSPEC,
/* C++ */
/* RID_FRIEND */ 0,
Index: flags.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flags.h,v
retrieving revision 1.84
diff -c -p -d -r1.84 flags.h
*** flags.h 15 May 2002 09:00:01 -0000 1.84
--- flags.h 21 May 2002 22:10:19 -0000
*************** extern int flag_dump_unnumbered;
*** 458,467 ****
extern int flag_pedantic_errors;
! /* Nonzero means generate position-independent code.
! This is not fully implemented yet. */
extern int flag_pic;
/* Nonzero means generate extra code for exception handling and enable
exception handling. */
--- 458,478 ----
extern int flag_pedantic_errors;
! /* Nonzero means generate position-independent code. 1 vs 2 for a
! target-dependent "small" or "large" mode. */
extern int flag_pic;
+
+ /* Set to the default thread-local storage (tls) model to use. */
+
+ enum tls_model {
+ TLS_MODEL_GLOBAL_DYNAMIC,
+ TLS_MODEL_LOCAL_DYNAMIC,
+ TLS_MODEL_INITIAL_EXEC,
+ TLS_MODEL_LOCAL_EXEC
+ };
+
+ extern enum tls_model flag_tls_default;
/* Nonzero means generate extra code for exception handling and enable
exception handling. */
Index: output.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/output.h,v
retrieving revision 1.105
diff -c -p -d -r1.105 output.h
*** output.h 19 May 2002 09:50:11 -0000 1.105
--- output.h 21 May 2002 22:10:19 -0000
*************** extern void no_asm_to_stream PARAMS ((FI
*** 507,513 ****
#define SECTION_STRINGS 0x10000 /* contains zero terminated strings without
embedded zeros */
#define SECTION_OVERRIDE 0x20000 /* allow override of default flags */
! #define SECTION_MACH_DEP 0x40000 /* subsequent bits reserved for target */
extern unsigned int get_named_section_flags PARAMS ((const char *));
extern bool set_named_section_flags PARAMS ((const char *, unsigned int));
--- 507,514 ----
#define SECTION_STRINGS 0x10000 /* contains zero terminated strings without
embedded zeros */
#define SECTION_OVERRIDE 0x20000 /* allow override of default flags */
! #define SECTION_TLS 0x40000 /* contains thread-local storage */
! #define SECTION_MACH_DEP 0x80000 /* subsequent bits reserved for target */
extern unsigned int get_named_section_flags PARAMS ((const char *));
extern bool set_named_section_flags PARAMS ((const char *, unsigned int));
Index: print-tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/print-tree.c,v
retrieving revision 1.57
diff -c -p -d -r1.57 print-tree.c
*** print-tree.c 20 May 2002 18:06:54 -0000 1.57
--- print-tree.c 21 May 2002 22:10:19 -0000
*************** print_node (file, prefix, node, indent)
*** 352,357 ****
--- 352,359 ----
if (TREE_CODE (node) == VAR_DECL && DECL_IN_TEXT_SECTION (node))
fputs (" in-text-section", file);
+ if (TREE_CODE (node) == VAR_DECL && DECL_THREAD_LOCAL (node))
+ fputs (" thread-local", file);
if (TREE_CODE (node) == PARM_DECL && DECL_TRANSPARENT_UNION (node))
fputs (" transparent-union", file);
Index: target-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target-def.h,v
retrieving revision 1.28
diff -c -p -d -r1.28 target-def.h
*** target-def.h 19 May 2002 09:50:12 -0000 1.28
--- target-def.h 21 May 2002 22:10:19 -0000
*************** Foundation, 59 Temple Place - Suite 330,
*** 110,115 ****
--- 110,119 ----
#define TARGET_HAVE_NAMED_SECTIONS false
#endif
+ #ifndef TARGET_HAVE_TLS
+ #define TARGET_HAVE_TLS false
+ #endif
+
#ifndef TARGET_ASM_EXCEPTION_SECTION
#define TARGET_ASM_EXCEPTION_SECTION default_exception_section
#endif
*************** Foundation, 59 Temple Place - Suite 330,
*** 244,249 ****
--- 248,254 ----
TARGET_STRIP_NAME_ENCODING, \
TARGET_HAVE_NAMED_SECTIONS, \
TARGET_HAVE_CTORS_DTORS, \
+ TARGET_HAVE_TLS \
}
#include "hooks.h"
Index: target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.30
diff -c -p -d -r1.30 target.h
*** target.h 19 May 2002 09:50:14 -0000 1.30
--- target.h 21 May 2002 22:10:19 -0000
*************** struct gcc_target
*** 256,261 ****
--- 256,264 ----
/* True if "native" constructors and destructors are supported,
false if we're using collect2 for the job. */
bool have_ctors_dtors;
+
+ /* True if thread-local storage is supported. */
+ bool have_tls;
};
extern struct gcc_target targetm;
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.628
diff -c -p -d -r1.628 toplev.c
*** toplev.c 19 May 2002 08:31:47 -0000 1.628
--- toplev.c 21 May 2002 22:10:19 -0000
*************** int flag_shared_data;
*** 685,696 ****
int flag_delayed_branch;
/* Nonzero if we are compiling pure (sharable) code.
! Value is 1 if we are doing reasonable (i.e. simple
! offset into offset table) pic. Value is 2 if we can
! only perform register offsets. */
int flag_pic;
/* Nonzero means generate extra code for exception handling and enable
exception handling. */
--- 685,699 ----
int flag_delayed_branch;
/* Nonzero if we are compiling pure (sharable) code.
! Value is 1 if we are doing "small" pic; value is 2 if we're doing
! "large" pic. */
int flag_pic;
+ /* Set to the default thread-local storage (tls) model to use. */
+
+ enum tls_model flag_tls_default;
+
/* Nonzero means generate extra code for exception handling and enable
exception handling. */
*************** display_help ()
*** 3547,3552 ****
--- 3550,3556 ----
printf (_(" -finline-limit=<number> Limits the size of inlined functions to <number>\n"));
printf (_(" -fmessage-length=<number> Limits diagnostics messages lengths to <number> characters per line. 0 suppresses line-wrapping\n"));
printf (_(" -fdiagnostics-show-location=[once | every-line] Indicates how often source location information should be emitted, as prefix, at the beginning of diagnostics when line-wrapping\n"));
+ printf (_(" -ftls-model=[global-dynamic | local-dynamic | initial-exec | local-exec] Indicates the default thread-local storage code generation model\n"));
for (i = ARRAY_SIZE (f_options); i--;)
{
*************** decode_f_option (arg)
*** 3824,3829 ****
--- 3828,3846 ----
read_integral_parameter (option_value, arg - 2,
MAX_INLINE_INSNS);
set_param_value ("max-inline-insns", val);
+ }
+ else if ((option_value = skip_leading_substring (arg, "tls-model=")))
+ {
+ if (strcmp (option_value, "global-dynamic") == 0)
+ flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
+ else if (strcmp (option_value, "local-dynamic") == 0)
+ flag_tls_default = TLS_MODEL_LOCAL_DYNAMIC;
+ else if (strcmp (option_value, "initial-exec") == 0)
+ flag_tls_default = TLS_MODEL_INITIAL_EXEC;
+ else if (strcmp (option_value, "local-exec") == 0)
+ flag_tls_default = TLS_MODEL_LOCAL_EXEC;
+ else
+ warning ("`%s': unknown tls-model option", arg - 2);
}
#ifdef INSN_SCHEDULING
else if ((option_value = skip_leading_substring (arg, "sched-verbose=")))
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.257
diff -c -p -d -r1.257 tree.c
*** tree.c 9 May 2002 22:48:33 -0000 1.257
--- tree.c 21 May 2002 22:10:19 -0000
*************** staticp (arg)
*** 1349,1360 ****
case FUNCTION_DECL:
/* Nested functions aren't static, since taking their address
involves a trampoline. */
! return (decl_function_context (arg) == 0 || DECL_NO_STATIC_CHAIN (arg))
! && ! DECL_NON_ADDR_CONST_P (arg);
case VAR_DECL:
! return (TREE_STATIC (arg) || DECL_EXTERNAL (arg))
! && ! DECL_NON_ADDR_CONST_P (arg);
case CONSTRUCTOR:
return TREE_STATIC (arg);
--- 1349,1361 ----
case FUNCTION_DECL:
/* Nested functions aren't static, since taking their address
involves a trampoline. */
! return ((decl_function_context (arg) == 0 || DECL_NO_STATIC_CHAIN (arg))
! && ! DECL_NON_ADDR_CONST_P (arg));
case VAR_DECL:
! return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
! && ! DECL_THREAD_LOCAL (arg)
! && ! DECL_NON_ADDR_CONST_P (arg));
case CONSTRUCTOR:
return TREE_STATIC (arg);
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.336
diff -c -p -d -r1.336 tree.h
*** tree.h 12 May 2002 21:42:00 -0000 1.336
--- tree.h 21 May 2002 22:10:19 -0000
*************** struct tree_type
*** 1615,1620 ****
--- 1615,1624 ----
/* In a FUNCTION_DECL, nonzero if the function cannot be inlined. */
#define DECL_UNINLINABLE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.uninlinable)
+ /* In a VAR_DECL, nonzero if the data should be allocated from
+ thread-local storage. */
+ #define DECL_THREAD_LOCAL(NODE) (VAR_DECL_CHECK (NODE)->decl.thread_local_flag)
+
/* In a FUNCTION_DECL, the saved representation of the body of the
entire function. Usually a COMPOUND_STMT, but in C++ this may also
be a RETURN_INIT, CTOR_INITIALIZER, or TRY_BLOCK. */
*************** struct tree_decl
*** 1793,1799 ****
unsigned non_addressable : 1;
unsigned user_align : 1;
unsigned uninlinable : 1;
! /* Three unused bits. */
unsigned lang_flag_0 : 1;
unsigned lang_flag_1 : 1;
--- 1797,1804 ----
unsigned non_addressable : 1;
unsigned user_align : 1;
unsigned uninlinable : 1;
! unsigned thread_local_flag : 1;
! /* Two unused bits. */
unsigned lang_flag_0 : 1;
unsigned lang_flag_1 : 1;
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.283
diff -c -p -d -r1.283 varasm.c
*** varasm.c 19 May 2002 20:17:50 -0000 1.283
--- varasm.c 21 May 2002 22:10:19 -0000
*************** assemble_variable (decl, top_level, at_e
*** 1586,1604 ****
/* Handle uninitialized definitions. */
! if ((DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node
! #if defined ASM_EMIT_BSS
! || (flag_zero_initialized_in_bss
! && initializer_zerop (DECL_INITIAL (decl)))
! #endif
! )
! /* If the target can't output uninitialized but not common global data
! in .bss, then we have to use .data. */
! #if ! defined ASM_EMIT_BSS
! && DECL_COMMON (decl)
#endif
! && DECL_SECTION_NAME (decl) == NULL_TREE
! && ! dont_output_data)
{
unsigned HOST_WIDE_INT size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
unsigned HOST_WIDE_INT rounded = size;
--- 1586,1613 ----
/* Handle uninitialized definitions. */
! /* If the decl has been given an explicit section name, then it
! isn't common, and shouldn't be handled as such. */
! if (DECL_SECTION_NAME (decl) || dont_output_data)
! ;
! /* We don't implement common thread-local data at present. */
! else if (DECL_THREAD_LOCAL (decl))
! {
! if (DECL_COMMON (decl))
! sorry ("thread-local COMMON data not implemented");
! }
! #ifndef ASM_EMIT_BSS
! /* If the target can't output uninitialized but not common global data
! in .bss, then we have to use .data. */
! /* ??? We should handle .bss via select_section mechanisms rather than
! via special target hooks. That would eliminate this special case. */
! else if (!DECL_COMMON (decl))
! ;
#endif
! else if (DECL_INITIAL (decl) == 0
! || DECL_INITIAL (decl) == error_mark_node
! || (flag_zero_initialized_in_bss
! && initializer_zerop (DECL_INITIAL (decl))))
{
unsigned HOST_WIDE_INT size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
unsigned HOST_WIDE_INT rounded = size;
*************** default_section_type_flags (decl, name,
*** 5101,5109 ****
|| strncmp (name, ".gnu.linkonce.b.", 16) == 0
|| strcmp (name, ".sbss") == 0
|| strncmp (name, ".sbss.", 6) == 0
! || strncmp (name, ".gnu.linkonce.sb.", 17) == 0)
flags |= SECTION_BSS;
return flags;
}
--- 5110,5123 ----
|| strncmp (name, ".gnu.linkonce.b.", 16) == 0
|| strcmp (name, ".sbss") == 0
|| strncmp (name, ".sbss.", 6) == 0
! || strncmp (name, ".gnu.linkonce.sb.", 17) == 0
! || strcmp (name, ".tbss") == 0)
flags |= SECTION_BSS;
+ if (strcmp (name, ".tdata") == 0
+ || strcmp (name, ".tbss") == 0)
+ flags |= SECTION_TLS;
+
return flags;
}
*************** default_elf_asm_named_section (name, fla
*** 5146,5151 ****
--- 5160,5167 ----
*f++ = 'M';
if (flags & SECTION_STRINGS)
*f++ = 'S';
+ if (flags & SECTION_TLS)
+ *f++ = 'T';
*f = '\0';
if (flags & SECTION_BSS)
*************** categorize_decl_for_section (decl, reloc
*** 5353,5360 ****
else
ret = SECCAT_RODATA;
/* If the target uses small data sections, select it. */
! if ((*targetm.in_small_data_p) (decl))
{
if (ret == SECCAT_BSS)
ret = SECCAT_SBSS;
--- 5369,5385 ----
else
ret = SECCAT_RODATA;
+ /* There are no read-only thread-local sections. */
+ if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
+ {
+ if (ret == SECCAT_BSS)
+ ret = SECCAT_TBSS;
+ else
+ ret = SECCAT_TDATA;
+ }
+
/* If the target uses small data sections, select it. */
! else if ((*targetm.in_small_data_p) (decl))
{
if (ret == SECCAT_BSS)
ret = SECCAT_SBSS;
Index: cp/lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/lex.c,v
retrieving revision 1.277
diff -c -p -d -r1.277 lex.c
*** cp/lex.c 25 Apr 2002 06:24:34 -0000 1.277
--- cp/lex.c 21 May 2002 22:10:21 -0000
*************** const short rid_to_yy[RID_MAX] =
*** 474,479 ****
--- 474,480 ----
/* RID_BOUNDED */ 0,
/* RID_UNBOUNDED */ 0,
/* RID_COMPLEX */ TYPESPEC,
+ /* RID_THREAD */ 0,
/* C++ */
/* RID_FRIEND */ SCSPEC,
Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.70
diff -c -p -d -r1.70 extend.texi
*** doc/extend.texi 11 May 2002 16:25:04 -0000 1.70
--- doc/extend.texi 21 May 2002 22:10:22 -0000
*************** extensions, accepted by GCC in C89 mode
*** 432,437 ****
--- 432,438 ----
* Target Builtins:: Built-in functions specific to particular targets.
* Pragmas:: Pragmas accepted by GCC.
* Unnamed Fields:: Unnamed struct/union fields within structs/unions.
+ * Thread-Local:: Per-thread variables.
@end menu
@node Statement Exprs
*************** struct @{
*** 6164,6169 ****
--- 6165,6219 ----
It is ambiguous which @code{a} is being referred to with @samp{foo.a}.
Such constructs are not supported and must be avoided. In the future,
such constructs may be detected and treated as compilation errors.
+
+ @node Thread-Local
+ @section Thread-Local Storage
+ @cindex Thread-Local Storage
+ @cindex TLS
+ @cindex __thread
+
+ Thread-local storage (TLS) is a mechanism by which variables are
+ allocated such that there is one instance of the variable per extant
+ thread. The run-time model GCC uses to implement this originates
+ in the IA-64 processor-specific ABI, but has since been migrated
+ to other processors as well. It requires significant support from
+ the linker (@command{ld}), dynamic linker (@command{ld.so}), and
+ system libraries (@file{libc.so} and @file{libpthread.so}), so it
+ is not supported everywhere.
+
+ At the user level, the extension is visible with a new storage
+ class keyword: @code{__thread}. For example:
+
+ @example
+ __thread int i;
+ extern __thread struct state s;
+ static __thread char *p;
+ @end example
+
+ The @code{__thread} specifier may be used alone, with the @code{extern}
+ or @code{static} specifiers, but with no other storage class specifier.
+ When used with @code{extern} or @code{static}, @code{__thread} must appear
+ immediately after the other storage class specifier.
+
+ The @code{__thread} specifier may be applied to any global, file-scoped
+ static, function-scoped static, or class-scoped static variable. It may
+ not be applied to function-scoped automatic or class-scoped member variables.
+
+ When the address-of operator is applied to a thread-local variable, it is
+ evaluated at run-time and returns the address of the current thread's
+ instance of that variable. An address so obtained may be used by any
+ thread. When a thread terminates, any pointers to thread-local variables
+ in that thread become invalid.
+
+ No static initialization may refer to the address of a thread-local variable.
+
+ In C++, a thread-local variable may not be initialized by a static
+ constructor.
+
+ See @uref{http://people.redhat.com/drepper/tls.pdf,
+ ELF Handling For Thread-Local Storage} for a detailed explanation of
+ the four thread-local storage addressing models, and how the run-time
+ is expected to function.
@node C++ Extensions
@chapter Extensions to the C++ Language
Index: doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.146
diff -c -p -d -r1.146 invoke.texi
*** doc/invoke.texi 18 May 2002 19:02:02 -0000 1.146
--- doc/invoke.texi 21 May 2002 22:10:22 -0000
*************** in the following sections.
*** 677,683 ****
-fverbose-asm -fpack-struct -fstack-check @gol
-fstack-limit-register=@var{reg} -fstack-limit-symbol=@var{sym} @gol
-fargument-alias -fargument-noalias @gol
! -fargument-noalias-global -fleading-underscore}
@end table
@menu
--- 677,683 ----
-fverbose-asm -fpack-struct -fstack-check @gol
-fstack-limit-register=@var{reg} -fstack-limit-symbol=@var{sym} @gol
-fargument-alias -fargument-noalias @gol
! -fargument-noalias-global -fleading-underscore -ftls-model=@var{model}}
@end table
@menu
*************** is to help link with legacy assembly cod
*** 9915,9920 ****
--- 9915,9928 ----
Be warned that you should know what you are doing when invoking this
option, and that not all targets provide complete support for it.
+
+ @item -ftls-model=@var{model}
+ Alter the thread-local storage model to be used (@pxref{Thread-Local}).
+ The @var{model} argument should be one of @code{global-dynamic},
+ @code{local-dynamic}, @code{initial-exec} or @code{local-exec}.
+
+ The default without @option{-fpic} is @code{initial-exec}; with
+ @option{-fpic} the default is @code{global-dynamic}.
@end table
@c man end
Index: fixinc/inclhack.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fixinc/inclhack.def,v
retrieving revision 1.128
diff -c -p -d -r1.128 inclhack.def
*** fixinc/inclhack.def 14 May 2002 00:33:14 -0000 1.128
--- fixinc/inclhack.def 21 May 2002 22:10:23 -0000
***************
*** 1,4 ****
-
/* -*- Mode: C -*- */
autogen definitions fixincl;
--- 1,3 ----
*************** fix = {
*** 2885,2890 ****
--- 2884,2903 ----
"extern char*\tbsearch(void*,size_t,size_t);\n";
};
+
+ /*
+ * __thread is now a keyword.
+ */
+ fix = {
+ hackname = thread_keyword;
+ files = "pthread.h";
+ files = "bits/sigthread.h";
+ select = "pthread_t __thread";
+
+ sed = "s/pthread_t __thread\\([^a-z0-9_]\\)/pthread_t __thr\\1/";
+
+ test_text = "extern int pthread_kill (pthread_t __thread, int __signo);";
+ };
/*
* if the #if says _cplusplus, not the double underscore __cplusplus
Index: testsuite/gcc.dg/tls/diag-1.c
===================================================================
RCS file: testsuite/gcc.dg/tls/diag-1.c
diff -N testsuite/gcc.dg/tls/diag-1.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/tls/diag-1.c 21 May 2002 22:51:13 -0000
***************
*** 0 ****
--- 1,11 ----
+ /* Valid __thread specifiers. */
+
+ __thread int g1;
+ extern __thread int g2;
+ static __thread int g3;
+
+ void foo()
+ {
+ extern __thread int l1;
+ static __thread int l2;
+ }
Index: testsuite/gcc.dg/tls/diag-2.c
===================================================================
RCS file: testsuite/gcc.dg/tls/diag-2.c
diff -N testsuite/gcc.dg/tls/diag-2.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/tls/diag-2.c 21 May 2002 22:51:13 -0000
***************
*** 0 ****
--- 1,21 ----
+ /* Invalid __thread specifiers. */
+
+ __thread extern int g1; /* { dg-error "`__thread' before `extern'" } */
+ __thread static int g2; /* { dg-error "`__thread' before `static'" } */
+ __thread __thread int g3; /* { dg-error "duplicate `__thread'" } */
+ typedef __thread int g4; /* { dg-error "multiple storage classes" } */
+
+ void foo()
+ {
+ __thread int l1; /* { dg-error "implicitly auto and declared `__thread'" } */
+ auto __thread int l2; /* { dg-error "multiple storage classes" } */
+ __thread extern int l3; /* { dg-error "`__thread' before `extern'" } */
+ register __thread int l4; /* { dg-error "multiple storage classes" } */
+ }
+
+ __thread void f1 (); /* { dg-error "invalid storage class for function" } */
+ extern __thread void f2 (); /* { dg-error "invalid storage class for function" } */
+ static __thread void f3 (); /* { dg-error "invalid storage class for function" } */
+ __thread void f4 () { } /* { dg-error "function definition declared `__thread'" } */
+
+ void bar(__thread int p1); /* { dg-error "storage class specified for parameter" } */
Index: testsuite/gcc.dg/tls/init-1.c
===================================================================
RCS file: testsuite/gcc.dg/tls/init-1.c
diff -N testsuite/gcc.dg/tls/init-1.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/tls/init-1.c 21 May 2002 22:51:13 -0000
***************
*** 0 ****
--- 1,4 ----
+ /* Invalid initializations. */
+
+ extern __thread int i;
+ int *p = &i; /* { dg-error "initializer element is not constant" } */
Index: testsuite/gcc.dg/tls/tls.exp
===================================================================
RCS file: testsuite/gcc.dg/tls/tls.exp
diff -N testsuite/gcc.dg/tls/tls.exp
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/tls/tls.exp 21 May 2002 22:51:13 -0000
***************
*** 0 ****
--- 1,45 ----
+ # Copyright (C) 2002 Free Software Foundation, Inc.
+
+ # This program is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU General Public License as published by
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ # GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ # GCC testsuite that uses the `dg.exp' driver.
+
+ # Load support procs.
+ load_lib gcc-dg.exp
+
+ # Test for thread-local data supported by the platform. If it
+ # isn't, everything will fail with the "not supported" message.
+
+ set comp_output [gcc_target_compile \
+ "$srcdir/$subdir/trivial.c" "trivial.S" assembly ""]
+ if { [string match "*not supported*" $comp_output] } {
+ return 0
+ }
+
+ # If a testcase doesn't have special options, use these.
+ global DEFAULT_CFLAGS
+ if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+ }
+
+ # Initialize `dg'.
+ dg-init
+
+ # Main loop.
+ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+ "" $DEFAULT_CFLAGS
+
+ # All done.
+ dg-finish
Index: testsuite/gcc.dg/tls/trivial.c
===================================================================
RCS file: testsuite/gcc.dg/tls/trivial.c
diff -N testsuite/gcc.dg/tls/trivial.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/tls/trivial.c 21 May 2002 22:51:13 -0000
***************
*** 0 ****
--- 1 ----
+ __thread int i;
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-21 18:54 thread-local storage: c front end and generic backend patch Richard Henderson
@ 2002-05-22 4:25 ` Joseph S. Myers
2002-05-22 13:53 ` Mark Mitchell
2002-07-11 9:00 ` David Edelsohn
2 siblings, 0 replies; 875+ messages in thread
From: Joseph S. Myers @ 2002-05-22 4:25 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches
On Tue, 21 May 2002, Richard Henderson wrote:
> Joseph, the extend.texi documentation has some user-level
> description of the extension. I've tried to come up with
> a set of edits for C99, but I'm not sure where to put them,
> or exactly what form they should take. Thoughts?
I think they should go in extend.texi just after the user-level
documentation.
--
Joseph S. Myers
jsm28@cam.ac.uk
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-21 18:54 thread-local storage: c front end and generic backend patch Richard Henderson
2002-05-22 4:25 ` Joseph S. Myers
@ 2002-05-22 13:53 ` Mark Mitchell
2002-05-22 14:22 ` Richard Henderson
2002-07-11 9:00 ` David Edelsohn
2 siblings, 1 reply; 875+ messages in thread
From: Mark Mitchell @ 2002-05-22 13:53 UTC (permalink / raw)
To: Richard Henderson, gcc-patches; +Cc: Joseph S. Myers
--On Tuesday, May 21, 2002 06:09:01 PM -0700 Richard Henderson
<rth@redhat.com> wrote:
> The following adds support in the C front end for a new
> storage specifier keyword "__thread" that marks a variable
> to be allocated in storage private to every extant thread.
Is this really necessary?
The traditional approach (i.e., make structures containing data
and then stuffing them into TLS) is workable, if slightly
cumbersome.
It's great to have the proposed standardese. That's very helpful.
There's no definition of "thread" in the standard, so saying that
these variables have the lifetime of "the thread" is probably
insufficient. "Prior to thread startup" is also a bit unclear; we
don't know how to start a thread or what it means for it to be
started. Does the initialization take place in the parent or the
child? (That matters if, say, longjmps occur in the midst of the
initializers.)
You probably also need to say something about interactions between
__thread variables and initialization order. For example:
__thread int i = j;
__thread int j = 7;
Does "i" get 0, or 7, or is this undefined behavior?
Similarly:
extern __thread int i;
int f() { return i + 2; }
__thread int i = f();
Is:
extern __thread int i;
extern int i;
int i;
legal? (Can you drop the "__thread" after you've said it once? What
if you don't say it the first time?)
In C++, what happens if an exception is thrown during construction of
a __thread variable?
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-22 13:53 ` Mark Mitchell
@ 2002-05-22 14:22 ` Richard Henderson
2002-05-22 14:44 ` Gabriel Dos Reis
` (2 more replies)
0 siblings, 3 replies; 875+ messages in thread
From: Richard Henderson @ 2002-05-22 14:22 UTC (permalink / raw)
To: Mark Mitchell; +Cc: gcc-patches, Joseph S. Myers
On Wed, May 22, 2002 at 01:41:51PM -0700, Mark Mitchell wrote:
> Is this really necessary?
>
> The traditional approach (i.e., make structures containing data
> and then stuffing them into TLS) is workable, if slightly
> cumbersome.
This mechanism, or rather the run-time mechanism behind this,
is significantly faster. It also solves a number of problems
with dynamic loading and wanting to share TLS data across DSO
boundaries.
> There's no definition of "thread" in the standard, so saying that
> these variables have the lifetime of "the thread" is probably
> insufficient. "Prior to thread startup" is also a bit unclear; we
> don't know how to start a thread or what it means for it to be
> started.
This is intentionally vague. Why would we mention pthread_create
here when the run-time might actually use some other thread library?
> Does the initialization take place in the parent or the
> child? (That matters if, say, longjmps occur in the midst of the
> initializers.)
There are no run-time initializers for TLS data. They are
specifically disallowed.
The run-time mechanism here is that TLS data is initialized via
block-copy from a PT_TLS ELF program segment. So we can't have
constructors of any form.
I should track down a copy of C++98 so that I can make similar
standardese changes there. That would have made this clearer
for you from the start.
> Is:
>
> extern __thread int i;
>
> extern int i;
>
> int i;
>
> legal? (Can you drop the "__thread" after you've said it once? What
> if you don't say it the first time?)
Ooo good point. I'd tend to want to force you to have it in the
earliest declaration, but allow it to be dropped subsequently.
The rationale being that while
extern int i;
int foo() { return i; }
static int i;
works, a similar case with __thread does not. Further, one would
like to be able to do
extern __thread int errno;
rather than the current best-effort in glibc:
#define errno (*__errno_location ())
But old programs have a tendancy to redefine errno themselves
"just in case".
Alternately, most of these programs have been fixed over the last
few years because of the above define. It might be sufficient to
have libc do
extern __thread int errno;
#define errno errno
since most of the fixes to the programs have been of the form
#ifndef errno
extern int errno
#endif
Then we can reasonably enforce the restriction that every declaration
must contain the __thread specifier.
Thoughts?
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-22 14:22 ` Richard Henderson
@ 2002-05-22 14:44 ` Gabriel Dos Reis
2002-05-22 14:55 ` Joseph S. Myers
2002-05-22 14:52 ` Mark Mitchell
2002-05-22 16:46 ` Alexandre Oliva
2 siblings, 1 reply; 875+ messages in thread
From: Gabriel Dos Reis @ 2002-05-22 14:44 UTC (permalink / raw)
To: Richard Henderson; +Cc: Mark Mitchell, gcc-patches, Joseph S. Myers
Richard Henderson <rth@redhat.com> writes:
[...]
| > There's no definition of "thread" in the standard, so saying that
| > these variables have the lifetime of "the thread" is probably
| > insufficient. "Prior to thread startup" is also a bit unclear; we
| > don't know how to start a thread or what it means for it to be
| > started.
|
| This is intentionally vague. Why would we mention pthread_create
| here when the run-time might actually use some other thread library?
Being more specifc about the semantics is really needed for proving
and/or maintaining the invariant that a change to compiler (be it an
advanced optimization or implementation of standard features) does not
break the semantics of that extension. In shrot, we need to know what
it is supposed to mean in order to prove that some change is correct.
I think the issue is important so that we don't gloss over it.
-- Gaby
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-22 14:22 ` Richard Henderson
2002-05-22 14:44 ` Gabriel Dos Reis
@ 2002-05-22 14:52 ` Mark Mitchell
2002-05-22 15:01 ` Richard Henderson
2002-05-22 16:46 ` Alexandre Oliva
2 siblings, 1 reply; 875+ messages in thread
From: Mark Mitchell @ 2002-05-22 14:52 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches, Joseph S. Myers
--On Wednesday, May 22, 2002 02:17:55 PM -0700 Richard Henderson
<rth@redhat.com> wrote:
> On Wed, May 22, 2002 at 01:41:51PM -0700, Mark Mitchell wrote:
>> Is this really necessary?
>>
>> The traditional approach (i.e., make structures containing data
>> and then stuffing them into TLS) is workable, if slightly
>> cumbersome.
>
> This mechanism, or rather the run-time mechanism behind this,
> is significantly faster. It also solves a number of problems
> with dynamic loading and wanting to share TLS data across DSO
> boundaries.
I see.
Well, heck, a new extension proposal gives me a chance to be an
annoying language lawyer. :-)
>> There's no definition of "thread" in the standard, so saying that
>> these variables have the lifetime of "the thread" is probably
>> insufficient. "Prior to thread startup" is also a bit unclear; we
>> don't know how to start a thread or what it means for it to be
>> started.
>
> This is intentionally vague. Why would we mention pthread_create
> here when the run-time might actually use some other thread library?
Agreed; still if we're going to talk about threads we have to have some
model of what a thread is. Even if we say "you create threads by some
implementation-defined means", we have to say that a thread is a flow
of control, that there are no guarantees about the values of
global variables that are not marked with __thread when accessed
simultaneously from multiple threads, etc.
In other words, by introducing __thread we've promoted threads to a
linguistic concept. When it was just "pthread_create", well, that's
just some function with whatever behavior it needs to have, it's not
our problem from a language point of view.
Now, all of a sudden, it is.
>> Does the initialization take place in the parent or the
>> child? (That matters if, say, longjmps occur in the midst of the
>> initializers.)
>
> There are no run-time initializers for TLS data. They are
> specifically disallowed.
I missed that point. That's great; it gets rid of one whole
set of issues.
(I assume that, in C++:
__thread const int i = 7;
__thread int j = i;
is OK. In C++, this would not be a dynamic initialization, if there
were no __thread modifier, and it seems like you could do this in
the implementation you're envisioning as well.)
> Ooo good point. I'd tend to want to force you to have it in the
> earliest declaration, but allow it to be dropped subsequently.
That seems best to me too.
We also need to note any GNU variable attributes don't work
with __thread variables. I don't see any reason any of them shouldn't
work, except maybe "section", if there are any restrictions on what
sections get into the ELF segment in question. (For example, if you
put a __thread variable in the ordinary .data section, is that going
to work?) We can just say you get undefined behavior if you use the
section attribute with __thread without noting which sections might
happen to work. Same might go for "shared" on Windows.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-22 14:44 ` Gabriel Dos Reis
@ 2002-05-22 14:55 ` Joseph S. Myers
0 siblings, 0 replies; 875+ messages in thread
From: Joseph S. Myers @ 2002-05-22 14:55 UTC (permalink / raw)
To: Gabriel Dos Reis; +Cc: Richard Henderson, Mark Mitchell, gcc-patches
On 22 May 2002, Gabriel Dos Reis wrote:
> | This is intentionally vague. Why would we mention pthread_create
> | here when the run-time might actually use some other thread library?
>
> Being more specifc about the semantics is really needed for proving
> and/or maintaining the invariant that a change to compiler (be it an
> advanced optimization or implementation of standard features) does not
> break the semantics of that extension. In shrot, we need to know what
> it is supposed to mean in order to prove that some change is correct.
>
> I think the issue is important so that we don't gloss over it.
There is the underlying problem here that POSIX needs to come with a set
of edits for the C standard to explain how it profiles that standard to
provide for threads (and for signal handling that isn't always undefined
behavior). However, it doesn't. In turn there are the problems of lack
of precise definition of object semantics in the C standard, which should
be addressed for it to serve properly as a base standard being profiled to
add threads, concurrency, etc..
--
Joseph S. Myers
jsm28@cam.ac.uk
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-22 14:52 ` Mark Mitchell
@ 2002-05-22 15:01 ` Richard Henderson
2002-05-22 15:13 ` Jakub Jelinek
2002-05-22 15:39 ` Mark Mitchell
0 siblings, 2 replies; 875+ messages in thread
From: Richard Henderson @ 2002-05-22 15:01 UTC (permalink / raw)
To: Mark Mitchell; +Cc: gcc-patches, Joseph S. Myers
On Wed, May 22, 2002 at 02:35:24PM -0700, Mark Mitchell wrote:
> Agreed; still if we're going to talk about threads we have to have some
> model of what a thread is. Even if we say "you create threads by some
> implementation-defined means", we have to say that a thread is a flow
> of control, that there are no guarantees about the values of
> global variables that are not marked with __thread when accessed
> simultaneously from multiple threads, etc.
Ok, I'll see what I can come up with.
> (I assume that, in C++:
>
> __thread const int i = 7;
> __thread int j = i;
>
> is OK. In C++, this would not be a dynamic initialization, if there
> were no __thread modifier, and it seems like you could do this in
> the implementation you're envisioning as well.)
*shrug* So long as the compiler does the constant propagation,
then sure this should be ok.
> I don't see any reason any of them shouldn't
> work, except maybe "section", if there are any restrictions on what
> sections get into the ELF segment in question.
There aren't. There's a new section flag SHF_TLS that can be
applied to any random section.
> (For example, if you put a __thread variable in the ordinary .data
> section, is that going to work?)
That should fail already because we already disallow variables
to be placed in sections for which there is a flag mismatch.
Thus you can't do
const int x __attribute__((section("foo"))) = 1;
int y __attribute__((section("foo"))) = 1;
because X wants FOO to have SHT_WRITE clear, and Y wants
SHF_WRITE set.
I'll add a test for it though, since it's quite a bit more
important here than with read-only vs read-write -- one could
have also taken the position that FOO receives the loosest
read/write/execute bits required for its contents.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-22 15:01 ` Richard Henderson
@ 2002-05-22 15:13 ` Jakub Jelinek
2002-05-22 15:36 ` Richard Henderson
2002-05-29 23:48 ` Fergus Henderson
2002-05-22 15:39 ` Mark Mitchell
1 sibling, 2 replies; 875+ messages in thread
From: Jakub Jelinek @ 2002-05-22 15:13 UTC (permalink / raw)
To: Richard Henderson, Mark Mitchell, gcc-patches, Joseph S. Myers
On Wed, May 22, 2002 at 02:55:18PM -0700, Richard Henderson wrote:
> > (I assume that, in C++:
> >
> > __thread const int i = 7;
> > __thread int j = i;
> >
> > is OK. In C++, this would not be a dynamic initialization, if there
> > were no __thread modifier, and it seems like you could do this in
> > the implementation you're envisioning as well.)
>
> *shrug* So long as the compiler does the constant propagation,
> then sure this should be ok.
Shouldn't be __thread const int i = 7; either forbidden, or __thread
ignored for it (in order of preference)?
It makes no sense to use __thread here (if the value is constant,
it has the same value for all the threads), there is no .trodata section
and we'd have problems with section flags...
Jakub
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-22 15:13 ` Jakub Jelinek
@ 2002-05-22 15:36 ` Richard Henderson
2002-05-22 15:42 ` Mark Mitchell
2002-05-29 23:48 ` Fergus Henderson
1 sibling, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-05-22 15:36 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Mark Mitchell, gcc-patches, Joseph S. Myers
On Wed, May 22, 2002 at 06:00:26PM -0400, Jakub Jelinek wrote:
> Shouldn't be __thread const int i = 7; either forbidden, or __thread
> ignored for it (in order of preference)?
It is questionable, sure, but illegal? I'll think about it.
Perhaps a warning only...
> It makes no sense to use __thread here (if the value is constant,
> it has the same value for all the threads), there is no .trodata section
> and we'd have problems with section flags...
Currently categorize_decl_for_section discards the read-only
bit for tls variables; default_section_type_flags could do the
same thing and solve the problem.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-22 15:01 ` Richard Henderson
2002-05-22 15:13 ` Jakub Jelinek
@ 2002-05-22 15:39 ` Mark Mitchell
2002-05-22 16:30 ` Richard Henderson
1 sibling, 1 reply; 875+ messages in thread
From: Mark Mitchell @ 2002-05-22 15:39 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches, Joseph S. Myers
--On Wednesday, May 22, 2002 02:55:18 PM -0700 Richard Henderson
<rth@redhat.com> wrote:
> On Wed, May 22, 2002 at 02:35:24PM -0700, Mark Mitchell wrote:
>> Agreed; still if we're going to talk about threads we have to have some
>> model of what a thread is. Even if we say "you create threads by some
>> implementation-defined means", we have to say that a thread is a flow
>> of control, that there are no guarantees about the values of
>> global variables that are not marked with __thread when accessed
>> simultaneously from multiple threads, etc.
>
> Ok, I'll see what I can come up with.
Great. As Joseph says, things are a bit of a mess in this regard.
It's probably not fair to ask you to solve all the problems...
>> (I assume that, in C++:
>>
>> __thread const int i = 7;
>> __thread int j = i;
>>
>> is OK. In C++, this would not be a dynamic initialization, if there
>> were no __thread modifier, and it seems like you could do this in
>> the implementation you're envisioning as well.)
>
> *shrug* So long as the compiler does the constant propagation,
> then sure this should be ok.
It should... I guess the language issue is that in C++ "const int i"
is an integral constant expression -- and it still is even with __thread.
I don't think we need to say anything about that; I'm just musing.
OK, I'm done picking it apart... :-)
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-22 15:36 ` Richard Henderson
@ 2002-05-22 15:42 ` Mark Mitchell
2002-05-22 15:56 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: Mark Mitchell @ 2002-05-22 15:42 UTC (permalink / raw)
To: Richard Henderson, Jakub Jelinek; +Cc: gcc-patches, Joseph S. Myers
--On Wednesday, May 22, 2002 03:13:07 PM -0700 Richard Henderson
<rth@redhat.com> wrote:
> On Wed, May 22, 2002 at 06:00:26PM -0400, Jakub Jelinek wrote:
>> Shouldn't be __thread const int i = 7; either forbidden, or __thread
>> ignored for it (in order of preference)?
>
> It is questionable, sure, but illegal? I'll think about it.
> Perhaps a warning only...
I don't see any reason for it to be illegal. It may be wasteful, but
that's all.
Sometimes you don't even know what type you've got; especially in
templates:
template <class T>
struct S {
__thread static T t;
};
f(S<const int>::t);
That one happens to be "const", but only because the template got
instantiated that way.
I don't think I'd even warn.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-22 15:42 ` Mark Mitchell
@ 2002-05-22 15:56 ` Richard Henderson
0 siblings, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-05-22 15:56 UTC (permalink / raw)
To: Mark Mitchell; +Cc: Jakub Jelinek, gcc-patches, Joseph S. Myers
On Wed, May 22, 2002 at 03:35:15PM -0700, Mark Mitchell wrote:
> f(S<const int>::t);
>
> I don't think I'd even warn.
Right. New test case added.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-22 15:39 ` Mark Mitchell
@ 2002-05-22 16:30 ` Richard Henderson
0 siblings, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-05-22 16:30 UTC (permalink / raw)
To: Mark Mitchell; +Cc: gcc-patches, Joseph S. Myers
On Wed, May 22, 2002 at 03:32:49PM -0700, Mark Mitchell wrote:
> > *shrug* So long as the compiler does the constant propagation,
> > then sure this should be ok.
>
> It should...
Test case added. It does work as expected.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-22 14:22 ` Richard Henderson
2002-05-22 14:44 ` Gabriel Dos Reis
2002-05-22 14:52 ` Mark Mitchell
@ 2002-05-22 16:46 ` Alexandre Oliva
2002-05-22 16:53 ` Richard Henderson
2 siblings, 1 reply; 875+ messages in thread
From: Alexandre Oliva @ 2002-05-22 16:46 UTC (permalink / raw)
To: Richard Henderson; +Cc: Mark Mitchell, gcc-patches, Joseph S. Myers
On May 22, 2002, Richard Henderson <rth@redhat.com> wrote:
> The run-time mechanism here is that TLS data is initialized via
> block-copy from a PT_TLS ELF program segment. So we can't have
> constructors of any form.
Sounds like you're describing POD types.
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist Professional serial bug killer
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-22 16:46 ` Alexandre Oliva
@ 2002-05-22 16:53 ` Richard Henderson
0 siblings, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-05-22 16:53 UTC (permalink / raw)
To: Alexandre Oliva; +Cc: Mark Mitchell, gcc-patches, Joseph S. Myers
On Wed, May 22, 2002 at 08:44:11PM -0300, Alexandre Oliva wrote:
> > The run-time mechanism here is that TLS data is initialized via
> > block-copy from a PT_TLS ELF program segment. So we can't have
> > constructors of any form.
>
> Sounds like you're describing POD types.
Well, more than that, as Jason noted with "int i = f();".
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* rs6000.c:output_toc
@ 2002-05-23 7:02 ` Alan Modra
2002-05-23 9:21 ` rs6000.c:output_toc David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-05-23 7:02 UTC (permalink / raw)
To: gcc-patches; +Cc: David Edelsohn
Fixes assembly output like
.tc ID_ffffffffcccccccc_cccccccd[TC],0xffffffffcccccccccccccccd
and the resultant assembler complaint
Warning: bignum truncated to 8 bytes
when compiling on a host with 64 bit longs.
gcc/ChangeLog
* config/rs6000/rs6000.c (output_toc): Mask longs to 32 bits.
OK for mainline and branch?
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.324
diff -u -p -r1.324 rs6000.c
--- gcc/config/rs6000/rs6000.c 23 May 2002 02:26:45 -0000 1.324
+++ gcc/config/rs6000/rs6000.c 23 May 2002 13:19:30 -0000
@@ -10256,8 +10256,10 @@ output_toc (file, x, labelno, mode)
if (TARGET_MINIMAL_TOC)
fputs (DOUBLE_INT_ASM_OP, file);
else
- fprintf (file, "\t.tc FD_%lx_%lx[TC],", k[0], k[1]);
- fprintf (file, "0x%lx%08lx\n", k[0], k[1]);
+ fprintf (file, "\t.tc FD_%lx_%lx[TC],",
+ k[0] & 0xffffffff, k[1] & 0xffffffff);
+ fprintf (file, "0x%lx%08lx\n",
+ k[0] & 0xffffffff, k[1] & 0xffffffff);
return;
}
else
@@ -10265,8 +10267,10 @@ output_toc (file, x, labelno, mode)
if (TARGET_MINIMAL_TOC)
fputs ("\t.long ", file);
else
- fprintf (file, "\t.tc FD_%lx_%lx[TC],", k[0], k[1]);
- fprintf (file, "0x%lx,0x%lx\n", k[0], k[1]);
+ fprintf (file, "\t.tc FD_%lx_%lx[TC],",
+ k[0] & 0xffffffff, k[1] & 0xffffffff);
+ fprintf (file, "0x%lx,0x%lx\n",
+ k[0] & 0xffffffff, k[1] & 0xffffffff);
return;
}
}
@@ -10283,8 +10287,8 @@ output_toc (file, x, labelno, mode)
if (TARGET_MINIMAL_TOC)
fputs (DOUBLE_INT_ASM_OP, file);
else
- fprintf (file, "\t.tc FS_%lx[TC],", l);
- fprintf (file, "0x%lx00000000\n", l);
+ fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
+ fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
return;
}
else
@@ -10292,8 +10296,8 @@ output_toc (file, x, labelno, mode)
if (TARGET_MINIMAL_TOC)
fputs ("\t.long ", file);
else
- fprintf (file, "\t.tc FS_%lx[TC],", l);
- fprintf (file, "0x%lx\n", l);
+ fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
+ fprintf (file, "0x%lx\n", l & 0xffffffff);
return;
}
}
@@ -10343,8 +10347,10 @@ output_toc (file, x, labelno, mode)
if (TARGET_MINIMAL_TOC)
fputs (DOUBLE_INT_ASM_OP, file);
else
- fprintf (file, "\t.tc ID_%lx_%lx[TC],", (long) high, (long) low);
- fprintf (file, "0x%lx%08lx\n", (long) high, (long) low);
+ fprintf (file, "\t.tc ID_%lx_%lx[TC],",
+ (long) high & 0xffffffff, (long) low & 0xffffffff);
+ fprintf (file, "0x%lx%08lx\n",
+ (long) high & 0xffffffff, (long) low & 0xffffffff);
return;
}
else
@@ -10355,16 +10361,17 @@ output_toc (file, x, labelno, mode)
fputs ("\t.long ", file);
else
fprintf (file, "\t.tc ID_%lx_%lx[TC],",
- (long) high, (long) low);
- fprintf (file, "0x%lx,0x%lx\n", (long) high, (long) low);
+ (long) high & 0xffffffff, (long) low & 0xffffffff);
+ fprintf (file, "0x%lx,0x%lx\n",
+ (long) high & 0xffffffff, (long) low & 0xffffffff);
}
else
{
if (TARGET_MINIMAL_TOC)
fputs ("\t.long ", file);
else
- fprintf (file, "\t.tc IS_%lx[TC],", (long) low);
- fprintf (file, "0x%lx\n", (long) low);
+ fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
+ fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
}
return;
}
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: rs6000.c:output_toc
2002-05-23 7:02 ` rs6000.c:output_toc Alan Modra
@ 2002-05-23 9:21 ` David Edelsohn
0 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-05-23 9:21 UTC (permalink / raw)
To: gcc-patches
* config/rs6000/rs6000.c (output_toc): Mask longs to 32 bits.
Yes, this is fine.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-22 15:13 ` Jakub Jelinek
2002-05-22 15:36 ` Richard Henderson
@ 2002-05-29 23:48 ` Fergus Henderson
1 sibling, 0 replies; 875+ messages in thread
From: Fergus Henderson @ 2002-05-29 23:48 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: gcc-patches
On 22-May-2002, Jakub Jelinek <jakub@redhat.com> wrote:
> Shouldn't be __thread const int i = 7; either forbidden, or __thread
> ignored for it (in order of preference)?
Ignoring __thread here would give the wrong semantics --
the constant should have different addresses for different threads.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
^ permalink raw reply [flat|nested] 875+ messages in thread
* PowerPC cleanup and Power4
@ 2002-06-09 8:10 David Edelsohn
2002-06-09 8:24 ` Neil Booth
2002-06-09 10:05 ` Geoff Keating
0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2002-06-09 8:10 UTC (permalink / raw)
To: gcc-patches
The following patch cleans up some cruft and formatting in the
rs6000 port and adds preliminary, basic Power4 support.
While exploring the scheduling, I noticed that cr_logical
attribute had not been applied to mfcr/mtcrf instructions. This bumps
performance on processors with multiple SCIUs where cr_logical was being
scheduled inefficiently.
David
* config/rs6000/{aix43.h,aix5.1} (ASM_CPU_SPEC): Add power3
synonym for 630. Add power4. Remove embedded processors. Use -m604
assembler option.
(CPP_CPU_SPEC): Add power3 and power4.
(PROCESSOR_DEFAULT): Change to 604e.
* config/rs6000/rs6000.h (ASM_CPU_SPEC): Similar additions.
(CPP_CPU_SPEC): Similar additions.
(enum process_type): Add POWER4.
(RTX_COSTS): Add POWER4.
(CPP_CPU_SPEC): Similar additions.
* config/rs6000/linux64.h (PROCESSOR_DEFAULT): Define.
* config/rs6000/rs6000.c (rs6000_override_options): Add power4.
(rs6000_adjust_cost): Add 603, 604, 604e, 620, 630, Power4 to
branch adjustment.
(rs6000_issue_rate): Add Power4.
* config/rs6000/rs6000.md (cpu attr): Add power4.
(iu compare): Remove 604, 604e, 620, 630.
Add basic Power4 scheduling information.
(mfcr/mtcrf): Change type attribute to cr_logical.
Index: aix43.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/aix43.h,v
retrieving revision 1.23
diff -c -p -r1.23 aix43.h
*** aix43.h 23 May 2002 02:26:45 -0000 1.23
--- aix43.h 9 Jun 2002 14:40:29 -0000
*************** do { \
*** 75,80 ****
--- 75,82 ----
%{mcpu=common: -mcom} \
%{mcpu=power: -mpwr} \
%{mcpu=power2: -mpwr2} \
+ %{mcpu=power3: -m604} \
+ %{mcpu=power4: -m604} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rios: -mpwr} \
%{mcpu=rios1: -mpwr} \
*************** do { \
*** 82,89 ****
%{mcpu=rsc: -mpwr} \
%{mcpu=rsc1: -mpwr} \
%{mcpu=rs64a: -mppc} \
- %{mcpu=403: -mppc} \
- %{mcpu=505: -mppc} \
%{mcpu=601: -m601} \
%{mcpu=602: -mppc} \
%{mcpu=603: -m603} \
--- 84,89 ----
*************** do { \
*** 91,99 ****
%{mcpu=604: -m604} \
%{mcpu=604e: -m604} \
%{mcpu=620: -mppc} \
! %{mcpu=630: -mppc} \
! %{mcpu=821: -mppc} \
! %{mcpu=860: -mppc}"
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
--- 91,97 ----
%{mcpu=604: -m604} \
%{mcpu=604e: -m604} \
%{mcpu=620: -mppc} \
! %{mcpu=630: -m604}"
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
*************** do { \
*** 135,140 ****
--- 133,140 ----
%{mcpu=common: -D_ARCH_COM} \
%{mcpu=power: -D_ARCH_PWR} \
%{mcpu=power2: -D_ARCH_PWR2} \
+ %{mcpu=power3: -D_ARCH_PPC} \
+ %{mcpu=power4: -D_ARCH_PPC} \
%{mcpu=powerpc: -D_ARCH_PPC} \
%{mcpu=rios: -D_ARCH_PWR} \
%{mcpu=rios1: -D_ARCH_PWR} \
*************** do { \
*** 142,158 ****
%{mcpu=rsc: -D_ARCH_PWR} \
%{mcpu=rsc1: -D_ARCH_PWR} \
%{mcpu=rs64a: -D_ARCH_PPC} \
- %{mcpu=403: -D_ARCH_PPC} \
- %{mcpu=505: -D_ARCH_PPC} \
%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
%{mcpu=602: -D_ARCH_PPC} \
%{mcpu=603: -D_ARCH_PPC} \
%{mcpu=603e: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC} \
%{mcpu=620: -D_ARCH_PPC} \
! %{mcpu=630: -D_ARCH_PPC} \
! %{mcpu=821: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC}"
#undef CPP_DEFAULT_SPEC
#define CPP_DEFAULT_SPEC "-D_ARCH_COM"
--- 142,154 ----
%{mcpu=rsc: -D_ARCH_PWR} \
%{mcpu=rsc1: -D_ARCH_PWR} \
%{mcpu=rs64a: -D_ARCH_PPC} \
%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
%{mcpu=602: -D_ARCH_PPC} \
%{mcpu=603: -D_ARCH_PPC} \
%{mcpu=603e: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC} \
%{mcpu=620: -D_ARCH_PPC} \
! %{mcpu=630: -D_ARCH_PPC}"
#undef CPP_DEFAULT_SPEC
#define CPP_DEFAULT_SPEC "-D_ARCH_COM"
*************** do { \
*** 161,167 ****
#define TARGET_DEFAULT MASK_NEW_MNEMONICS
#undef PROCESSOR_DEFAULT
! #define PROCESSOR_DEFAULT PROCESSOR_PPC604
/* Define this macro as a C expression for the initializer of an
array of string to tell the driver program which options are
--- 157,163 ----
#define TARGET_DEFAULT MASK_NEW_MNEMONICS
#undef PROCESSOR_DEFAULT
! #define PROCESSOR_DEFAULT PROCESSOR_PPC604e
/* Define this macro as a C expression for the initializer of an
array of string to tell the driver program which options are
Index: aix51.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/aix51.h,v
retrieving revision 1.12
diff -c -p -r1.12 aix51.h
*** aix51.h 23 May 2002 02:26:45 -0000 1.12
--- aix51.h 9 Jun 2002 14:40:29 -0000
*************** do { \
*** 75,80 ****
--- 75,82 ----
%{mcpu=common: -mcom} \
%{mcpu=power: -mpwr} \
%{mcpu=power2: -mpwr2} \
+ %{mcpu=power3: -m604} \
+ %{mcpu=power4: -m604} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rios: -mpwr} \
%{mcpu=rios1: -mpwr} \
*************** do { \
*** 82,89 ****
%{mcpu=rsc: -mpwr} \
%{mcpu=rsc1: -mpwr} \
%{mcpu=rs64a: -mppc} \
- %{mcpu=403: -mppc} \
- %{mcpu=505: -mppc} \
%{mcpu=601: -m601} \
%{mcpu=602: -mppc} \
%{mcpu=603: -m603} \
--- 84,89 ----
*************** do { \
*** 91,99 ****
%{mcpu=604: -m604} \
%{mcpu=604e: -m604} \
%{mcpu=620: -mppc} \
! %{mcpu=630: -mppc} \
! %{mcpu=821: -mppc} \
! %{mcpu=860: -mppc}"
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
--- 91,97 ----
%{mcpu=604: -m604} \
%{mcpu=604e: -m604} \
%{mcpu=620: -mppc} \
! %{mcpu=630: -m604}"
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
*************** do { \
*** 135,140 ****
--- 133,140 ----
%{mcpu=common: -D_ARCH_COM} \
%{mcpu=power: -D_ARCH_PWR} \
%{mcpu=power2: -D_ARCH_PWR2} \
+ %{mcpu=power3: -D_ARCH_PPC} \
+ %{mcpu=power4: -D_ARCH_PPC} \
%{mcpu=powerpc: -D_ARCH_PPC} \
%{mcpu=rios: -D_ARCH_PWR} \
%{mcpu=rios1: -D_ARCH_PWR} \
*************** do { \
*** 142,158 ****
%{mcpu=rsc: -D_ARCH_PWR} \
%{mcpu=rsc1: -D_ARCH_PWR} \
%{mcpu=rs64a: -D_ARCH_PPC} \
- %{mcpu=403: -D_ARCH_PPC} \
- %{mcpu=505: -D_ARCH_PPC} \
%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
%{mcpu=602: -D_ARCH_PPC} \
%{mcpu=603: -D_ARCH_PPC} \
%{mcpu=603e: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC} \
%{mcpu=620: -D_ARCH_PPC} \
! %{mcpu=630: -D_ARCH_PPC} \
! %{mcpu=821: -D_ARCH_PPC} \
! %{mcpu=860: -D_ARCH_PPC}"
#undef CPP_DEFAULT_SPEC
#define CPP_DEFAULT_SPEC "-D_ARCH_COM"
--- 142,154 ----
%{mcpu=rsc: -D_ARCH_PWR} \
%{mcpu=rsc1: -D_ARCH_PWR} \
%{mcpu=rs64a: -D_ARCH_PPC} \
%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
%{mcpu=602: -D_ARCH_PPC} \
%{mcpu=603: -D_ARCH_PPC} \
%{mcpu=603e: -D_ARCH_PPC} \
%{mcpu=604: -D_ARCH_PPC} \
%{mcpu=620: -D_ARCH_PPC} \
! %{mcpu=630: -D_ARCH_PPC}"
#undef CPP_DEFAULT_SPEC
#define CPP_DEFAULT_SPEC "-D_ARCH_COM"
*************** do { \
*** 161,167 ****
#define TARGET_DEFAULT MASK_NEW_MNEMONICS
#undef PROCESSOR_DEFAULT
! #define PROCESSOR_DEFAULT PROCESSOR_PPC604
/* Define this macro as a C expression for the initializer of an
array of string to tell the driver program which options are
--- 157,163 ----
#define TARGET_DEFAULT MASK_NEW_MNEMONICS
#undef PROCESSOR_DEFAULT
! #define PROCESSOR_DEFAULT PROCESSOR_PPC604e
/* Define this macro as a C expression for the initializer of an
array of string to tell the driver program which options are
Index: linux64.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/linux64.h,v
retrieving revision 1.15
diff -c -p -r1.15 linux64.h
*** linux64.h 5 Jun 2002 03:56:27 -0000 1.15
--- linux64.h 9 Jun 2002 14:40:29 -0000
*************** Boston, MA 02111-1307, USA. */
*** 31,36 ****
--- 31,39 ----
#define TARGET_DEFAULT \
(MASK_POWERPC | MASK_POWERPC64 | MASK_64BIT | MASK_NEW_MNEMONICS)
+ #undef PROCESSOR_DEFAULT
+ #define PROCESSOR_DEFAULT PROCESSOR_PPC630
+
#undef CPP_DEFAULT_SPEC
#define CPP_DEFAULT_SPEC "-D_ARCH_PPC64"
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.329
diff -c -p -r1.329 rs6000.c
*** rs6000.c 4 Jun 2002 07:09:27 -0000 1.329
--- rs6000.c 9 Jun 2002 14:40:30 -0000
*************** rs6000_override_options (default_cpu)
*** 353,358 ****
--- 353,361 ----
{"power3", PROCESSOR_PPC630,
MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
POWER_MASKS | MASK_PPC_GPOPT},
+ {"power4", PROCESSOR_POWER4,
+ MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
+ POWER_MASKS | MASK_PPC_GPOPT},
{"powerpc", PROCESSOR_POWERPC,
MASK_POWERPC | MASK_NEW_MNEMONICS,
POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
*************** rs6000_adjust_cost (insn, link, dep_insn
*** 10696,10713 ****
switch (get_attr_type (insn))
{
case TYPE_JMPREG:
! /* Tell the first scheduling pass about the latency between
a mtctr and bctr (and mtlr and br/blr). The first
scheduling pass will not know about this latency since
the mtctr instruction, which has the latency associated
to it, will be generated by reload. */
! return TARGET_POWER ? 5 : 4;
case TYPE_BRANCH:
/* Leave some extra cycles between a compare and its
dependent branch, to inhibit expensive mispredicts. */
! if ((rs6000_cpu_attr == CPU_PPC750
! || rs6000_cpu_attr == CPU_PPC7400
! || rs6000_cpu_attr == CPU_PPC7450)
&& recog_memoized (dep_insn)
&& (INSN_CODE (dep_insn) >= 0)
&& (get_attr_type (dep_insn) == TYPE_COMPARE
--- 10699,10722 ----
switch (get_attr_type (insn))
{
case TYPE_JMPREG:
! /* Tell the first scheduling pass about the latency between
a mtctr and bctr (and mtlr and br/blr). The first
scheduling pass will not know about this latency since
the mtctr instruction, which has the latency associated
to it, will be generated by reload. */
! return TARGET_POWER ? 5 : 4;
case TYPE_BRANCH:
/* Leave some extra cycles between a compare and its
dependent branch, to inhibit expensive mispredicts. */
! if ((rs6000_cpu_attr == CPU_PPC603
! || rs6000_cpu_attr == CPU_PPC604
! || rs6000_cpu_attr == CPU_PPC604E
! || rs6000_cpu_attr == CPU_PPC620
! || rs6000_cpu_attr == CPU_PPC630
! || rs6000_cpu_attr == CPU_PPC750
! || rs6000_cpu_attr == CPU_PPC7400
! || rs6000_cpu_attr == CPU_PPC7450
! || rs6000_cpu_attr == CPU_POWER4)
&& recog_memoized (dep_insn)
&& (INSN_CODE (dep_insn) >= 0)
&& (get_attr_type (dep_insn) == TYPE_COMPARE
*************** rs6000_issue_rate ()
*** 10788,10793 ****
--- 10797,10803 ----
case CPU_PPC604E:
case CPU_PPC620:
case CPU_PPC630:
+ case CPU_POWER4:
return 4;
default:
return 1;
Index: rs6000.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.206
diff -c -p -r1.206 rs6000.h
*** rs6000.h 4 Jun 2002 07:09:32 -0000 1.206
--- rs6000.h 9 Jun 2002 14:40:30 -0000
*************** Boston, MA 02111-1307, USA. */
*** 58,63 ****
--- 58,65 ----
%{mcpu=common: -D_ARCH_COM} \
%{mcpu=power: -D_ARCH_PWR} \
%{mcpu=power2: -D_ARCH_PWR2} \
+ %{mcpu=power3: -D_ARCH_PPC} \
+ %{mcpu=power4: -D_ARCH_PPC} \
%{mcpu=powerpc: -D_ARCH_PPC} \
%{mcpu=rios: -D_ARCH_PWR} \
%{mcpu=rios1: -D_ARCH_PWR} \
*************** Boston, MA 02111-1307, USA. */
*** 98,103 ****
--- 100,107 ----
%{mcpu=common: -mcom} \
%{mcpu=power: -mpwr} \
%{mcpu=power2: -mpwrx} \
+ %{mcpu=power3: -m604} \
+ %{mcpu=power4: -m604} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rios: -mpwr} \
%{mcpu=rios1: -mpwr} \
*************** Boston, MA 02111-1307, USA. */
*** 116,121 ****
--- 120,126 ----
%{mcpu=604: -mppc} \
%{mcpu=604e: -mppc} \
%{mcpu=620: -mppc} \
+ %{mcpu=630: -m604} \
%{mcpu=740: -mppc} \
%{mcpu=7400: -mppc} \
%{mcpu=7450: -mppc} \
*************** enum processor_type
*** 395,401 ****
PROCESSOR_PPC630,
PROCESSOR_PPC750,
PROCESSOR_PPC7400,
! PROCESSOR_PPC7450
};
extern enum processor_type rs6000_cpu;
--- 400,407 ----
PROCESSOR_PPC630,
PROCESSOR_PPC750,
PROCESSOR_PPC7400,
! PROCESSOR_PPC7450,
! PROCESSOR_POWER4
};
extern enum processor_type rs6000_cpu;
*************** do { \
*** 2298,2303 ****
--- 2304,2310 ----
return COSTS_N_INSNS (4); \
case PROCESSOR_PPC620: \
case PROCESSOR_PPC630: \
+ case PROCESSOR_POWER4: \
return (GET_CODE (XEXP (X, 1)) != CONST_INT \
? GET_MODE (XEXP (X, 1)) != DImode \
? COSTS_N_INSNS (5) : COSTS_N_INSNS (7) \
*************** do { \
*** 2337,2342 ****
--- 2344,2350 ----
return COSTS_N_INSNS (20); \
case PROCESSOR_PPC620: \
case PROCESSOR_PPC630: \
+ case PROCESSOR_POWER4: \
return (GET_MODE (XEXP (X, 1)) != DImode \
? COSTS_N_INSNS (21) \
: COSTS_N_INSNS (37)); \
Index: rs6000.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.189
diff -c -p -r1.189 rs6000.md
*** rs6000.md 19 May 2002 17:10:47 -0000 1.189
--- rs6000.md 9 Jun 2002 14:40:30 -0000
***************
*** 56,62 ****
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in rs6000.h.
! (define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450"
(const (symbol_ref "rs6000_cpu_attr")))
; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
--- 56,62 ----
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in rs6000.h.
! (define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,power4"
(const (symbol_ref "rs6000_cpu_attr")))
; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
***************
*** 375,416 ****
--- 375,426 ----
(and (eq_attr "type" "cr_logical")
(eq_attr "cpu" "ppc7450"))
1 1)
+
(define_function_unit "vec_alu2" 2 0
(and (eq_attr "type" "vecsimple")
(eq_attr "cpu" "ppc7450"))
1 2 [(eq_attr "type" "vecsimple")])
+
(define_function_unit "vec_alu2" 2 0
(and (eq_attr "type" "vecsimple")
(eq_attr "cpu" "ppc7450"))
1 1 [(eq_attr "type" "!vecsimple")])
+
(define_function_unit "vec_alu2" 2 0
(and (eq_attr "type" "veccomplex")
(eq_attr "cpu" "ppc7450"))
4 2 [(eq_attr "type" "veccomplex")])
+
(define_function_unit "vec_alu2" 2 0
(and (eq_attr "type" "veccomplex")
(eq_attr "cpu" "ppc7450"))
4 1 [(eq_attr "type" "!veccomplex")])
+
(define_function_unit "vec_alu2" 2 0
(and (eq_attr "type" "veccmp")
(eq_attr "cpu" "ppc7450"))
2 2 [(eq_attr "type" "veccmp")])
+
(define_function_unit "vec_alu2" 2 0
(and (eq_attr "type" "veccmp")
(eq_attr "cpu" "ppc7450"))
2 1 [(eq_attr "type" "!veccmp")])
+
(define_function_unit "vec_alu2" 2 0
(and (eq_attr "type" "vecfloat")
(eq_attr "cpu" "ppc7450"))
4 2 [(eq_attr "type" "vecfloat")])
+
(define_function_unit "vec_alu2" 2 0
(and (eq_attr "type" "vecfloat")
(eq_attr "cpu" "ppc7450"))
4 1 [(eq_attr "type" "!vecfloat")])
+
(define_function_unit "vec_alu2" 2 0
(and (eq_attr "type" "vecperm")
(eq_attr "cpu" "ppc7450"))
2 2 [(eq_attr "type" "vecperm")])
+
(define_function_unit "vec_alu2" 2 0
(and (eq_attr "type" "vecperm")
(eq_attr "cpu" "ppc7450"))
***************
*** 489,495 ****
(define_function_unit "iu" 1 0
(and (eq_attr "type" "compare,delayed_compare")
! (eq_attr "cpu" "rs64a,mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630"))
3 1)
; some extra cycles added by TARGET_SCHED_ADJUST_COST between compare
--- 499,505 ----
(define_function_unit "iu" 1 0
(and (eq_attr "type" "compare,delayed_compare")
! (eq_attr "cpu" "rs64a,mpccore,ppc403,ppc405,ppc601,ppc603"))
3 1)
; some extra cycles added by TARGET_SCHED_ADJUST_COST between compare
***************
*** 699,720 ****
; RIOS2 has two symmetric FPUs.
(define_function_unit "fpu2" 2 0
! (and (eq_attr "type" "fp")
! (eq_attr "cpu" "rios2"))
! 2 1)
!
! (define_function_unit "fpu2" 2 0
! (and (eq_attr "type" "fp")
! (eq_attr "cpu" "ppc630"))
! 3 1)
!
! (define_function_unit "fpu2" 2 0
! (and (eq_attr "type" "dmul")
(eq_attr "cpu" "rios2"))
2 1)
(define_function_unit "fpu2" 2 0
! (and (eq_attr "type" "dmul")
(eq_attr "cpu" "ppc630"))
3 1)
--- 709,720 ----
; RIOS2 has two symmetric FPUs.
(define_function_unit "fpu2" 2 0
! (and (eq_attr "type" "fp,dmul")
(eq_attr "cpu" "rios2"))
2 1)
(define_function_unit "fpu2" 2 0
! (and (eq_attr "type" "fp,dmul")
(eq_attr "cpu" "ppc630"))
3 1)
***************
*** 748,753 ****
--- 748,854 ----
(eq_attr "cpu" "ppc630"))
26 26)
+ ;; Power4
+ (define_function_unit "lsu2" 2 0
+ (and (eq_attr "type" "load")
+ (eq_attr "cpu" "power4"))
+ 3 1)
+
+ (define_function_unit "lsu2" 2 0
+ (and (eq_attr "type" "fpload")
+ (eq_attr "cpu" "power4"))
+ 5 1)
+
+ (define_function_unit "lsu2" 2 0
+ (and (eq_attr "type" "store,fpstore")
+ (eq_attr "cpu" "power4"))
+ 1 1)
+
+ (define_function_unit "iu2" 2 0
+ (and (eq_attr "type" "integer")
+ (eq_attr "cpu" "power4"))
+ 2 1)
+
+ (define_function_unit "iu2" 2 0
+ (and (eq_attr "type" "imul,lmul")
+ (eq_attr "cpu" "power4"))
+ 7 6)
+
+ (define_function_unit "iu2" 2 0
+ (and (eq_attr "type" "imul2")
+ (eq_attr "cpu" "power4"))
+ 5 4)
+
+ (define_function_unit "iu2" 2 0
+ (and (eq_attr "type" "imul3")
+ (eq_attr "cpu" "power4"))
+ 4 3)
+
+ (define_function_unit "iu2" 2 0
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "power4"))
+ 36 35)
+
+ (define_function_unit "iu2" 2 0
+ (and (eq_attr "type" "ldiv")
+ (eq_attr "cpu" "power4"))
+ 68 67)
+
+ (define_function_unit "imuldiv" 1 0
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "power4"))
+ 36 35)
+
+ (define_function_unit "imuldiv" 1 0
+ (and (eq_attr "type" "ldiv")
+ (eq_attr "cpu" "power4"))
+ 68 67)
+
+ (define_function_unit "iu2" 2 0
+ (and (eq_attr "type" "compare,delayed_compare")
+ (eq_attr "cpu" "power4"))
+ 2 1)
+
+ (define_function_unit "iu2" 2 0
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "power4"))
+ 3 1)
+
+ (define_function_unit "bpu" 1 0
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "power4"))
+ 3 1)
+
+ (define_function_unit "bpu" 1 0
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "power4"))
+ 2 1)
+
+ (define_function_unit "cru" 1 0
+ (and (eq_attr "type" "cr_logical")
+ (eq_attr "cpu" "power4"))
+ 4 1)
+
+ (define_function_unit "fpu2" 2 0
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "power4"))
+ 6 1)
+
+ (define_function_unit "fpu2" 2 0
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "power4"))
+ 8 2)
+
+ (define_function_unit "fpu2" 2 0
+ (and (eq_attr "type" "sdiv,ddiv")
+ (eq_attr "cpu" "power4"))
+ 33 28)
+
+ (define_function_unit "fpu2" 2 0
+ (and (eq_attr "type" "ssqrt,dsqrt")
+ (eq_attr "cpu" "power4"))
+ 40 35)
+
\f
;; Start with fixed-point load and store insns. Here we put only the more
;; complex forms. Basic data transfer is done later.
***************
*** 7778,7784 ****
mr %0,%1
{l%U1%X1|lwz%U1%X1} %0,%1
{st%U0%U1|stw%U0%U1} %1,%0"
! [(set_attr "type" "*,*,*,compare,*,*,load,store")
(set_attr "length" "*,*,12,*,8,*,*,*")])
\f
;; For floating-point, we normally deal with the floating-point registers
--- 7879,7885 ----
mr %0,%1
{l%U1%X1|lwz%U1%X1} %0,%1
{st%U0%U1|stw%U0%U1} %1,%0"
! [(set_attr "type" "cr_logical,cr_logical,cr_logical,cr_logical,cr_logical,*,load,store")
(set_attr "length" "*,*,12,*,8,*,*,*")])
\f
;; For floating-point, we normally deal with the floating-point registers
***************
*** 10585,10591 ****
(const_int 0)]))]
""
"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
! [(set_attr "length" "12")])
(define_insn ""
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
--- 10686,10693 ----
(const_int 0)]))]
""
"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
! [(set_attr "type" "cr_logical")
! (set_attr "length" "12")])
(define_insn ""
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
***************
*** 10594,10600 ****
(const_int 0)]))]
"TARGET_POWERPC64"
"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
! [(set_attr "length" "12")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
--- 10696,10703 ----
(const_int 0)]))]
"TARGET_POWERPC64"
"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
! [(set_attr "type" "cr_logical")
! (set_attr "length" "12")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
***************
*** 10650,10656 ****
return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
}"
! [(set_attr "length" "12")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
--- 10753,10760 ----
return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
}"
! [(set_attr "type" "cr_logical")
! (set_attr "length" "12")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
***************
*** 10719,10727 ****
(match_operator:SI 4 "scc_comparison_operator"
[(match_operand 5 "cc_reg_operand" "y")
(const_int 0)]))]
! "REGNO (operands[2]) != REGNO (operands[5])"
! "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
! [(set_attr "length" "20")])
(define_peephole
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
--- 10823,10832 ----
(match_operator:SI 4 "scc_comparison_operator"
[(match_operand 5 "cc_reg_operand" "y")
(const_int 0)]))]
! "REGNO (operands[2]) != REGNO (operands[5])"
! "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
! [(set_attr "type" "cr_logical")
! (set_attr "length" "20")])
(define_peephole
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
***************
*** 10732,10740 ****
(match_operator:DI 4 "scc_comparison_operator"
[(match_operand 5 "cc_reg_operand" "y")
(const_int 0)]))]
! "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
! "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
! [(set_attr "length" "20")])
;; There are some scc insns that can be done directly, without a compare.
;; These are faster because they don't involve the communications between
--- 10837,10846 ----
(match_operator:DI 4 "scc_comparison_operator"
[(match_operand 5 "cc_reg_operand" "y")
(const_int 0)]))]
! "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
! "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
! [(set_attr "type" "cr_logical")
! (set_attr "length" "20")])
;; There are some scc insns that can be done directly, without a compare.
;; These are faster because they don't involve the communications between
***************
*** 13727,13733 ****
(unspec:SI [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71)
(reg:CC 72) (reg:CC 73) (reg:CC 74) (reg:CC 75)] 19))]
""
! "mfcr %0")
(define_insn "*stmw"
[(match_parallel 0 "stmw_operation"
--- 13833,13840 ----
(unspec:SI [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71)
(reg:CC 72) (reg:CC 73) (reg:CC 74) (reg:CC 75)] 19))]
""
! "mfcr %0"
! [(set_attr "type" "cr_logical")])
(define_insn "*stmw"
[(match_parallel 0 "stmw_operation"
***************
*** 13799,13815 ****
mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
operands[4] = GEN_INT (mask);
return \"mtcrf %4,%2\";
! }")
(define_insn ""
! [(set (match_operand:CC 0 "cc_reg_operand" "=y")
! (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
! (match_operand 2 "immediate_operand" "n")] 20))]
! "GET_CODE (operands[0]) == REG
! && CR_REGNO_P (REGNO (operands[0]))
! && GET_CODE (operands[2]) == CONST_INT
! && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
! "mtcrf %R0,%1")
; The load-multiple instructions have similar properties.
; Note that "load_multiple" is a name known to the machine-independent
--- 13906,13924 ----
mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
operands[4] = GEN_INT (mask);
return \"mtcrf %4,%2\";
! }"
! [(set_attr "type" "cr_logical")])
(define_insn ""
! [(set (match_operand:CC 0 "cc_reg_operand" "=y")
! (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
! (match_operand 2 "immediate_operand" "n")] 20))]
! "GET_CODE (operands[0]) == REG
! && CR_REGNO_P (REGNO (operands[0]))
! && GET_CODE (operands[2]) == CONST_INT
! && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
! "mtcrf %R0,%1"
! [(set_attr "type" "cr_logical")])
; The load-multiple instructions have similar properties.
; Note that "load_multiple" is a name known to the machine-independent
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PowerPC cleanup and Power4
2002-06-09 8:10 PowerPC cleanup and Power4 David Edelsohn
@ 2002-06-09 8:24 ` Neil Booth
2002-06-09 8:31 ` David Edelsohn
2002-06-09 10:05 ` Geoff Keating
1 sibling, 1 reply; 875+ messages in thread
From: Neil Booth @ 2002-06-09 8:24 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
David Edelsohn wrote:-
> *************** do { \
> *** 135,140 ****
> --- 133,140 ----
> %{mcpu=common: -D_ARCH_COM} \
> %{mcpu=power: -D_ARCH_PWR} \
> %{mcpu=power2: -D_ARCH_PWR2} \
> + %{mcpu=power3: -D_ARCH_PPC} \
> + %{mcpu=power4: -D_ARCH_PPC} \
> %{mcpu=powerpc: -D_ARCH_PPC} \
> %{mcpu=rios: -D_ARCH_PWR} \
> %{mcpu=rios1: -D_ARCH_PWR} \
> *************** do { \
> *** 142,158 ****
> %{mcpu=rsc: -D_ARCH_PWR} \
> %{mcpu=rsc1: -D_ARCH_PWR} \
> %{mcpu=rs64a: -D_ARCH_PPC} \
> - %{mcpu=403: -D_ARCH_PPC} \
> - %{mcpu=505: -D_ARCH_PPC} \
> %{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
> %{mcpu=602: -D_ARCH_PPC} \
> %{mcpu=603: -D_ARCH_PPC} \
> %{mcpu=603e: -D_ARCH_PPC} \
> %{mcpu=604: -D_ARCH_PPC} \
> %{mcpu=620: -D_ARCH_PPC} \
> ! %{mcpu=630: -D_ARCH_PPC} \
> ! %{mcpu=821: -D_ARCH_PPC} \
> ! %{mcpu=860: -D_ARCH_PPC}"
Is there any chance of persuading you to get rid of all this spec
hackery for CPP macros, and to use TARGET_OS_CPP_BUILTINS and
TARGET_CPU_CPP_BUILTINS instead, as is done in the alpha/ port
and others? It has many advantages.
Neil.
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PowerPC cleanup and Power4
2002-06-09 8:24 ` Neil Booth
@ 2002-06-09 8:31 ` David Edelsohn
0 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-06-09 8:31 UTC (permalink / raw)
To: Neil Booth; +Cc: gcc-patches
>>>>> Neil Booth writes:
Neil> Is there any chance of persuading you to get rid of all this spec
Neil> hackery for CPP macros, and to use TARGET_OS_CPP_BUILTINS and
Neil> TARGET_CPU_CPP_BUILTINS instead, as is done in the alpha/ port
Neil> and others? It has many advantages.
I believe that Red Hat is planning to do this.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PowerPC cleanup and Power4
2002-06-09 8:10 PowerPC cleanup and Power4 David Edelsohn
2002-06-09 8:24 ` Neil Booth
@ 2002-06-09 10:05 ` Geoff Keating
2002-06-09 10:33 ` David Edelsohn
1 sibling, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-06-09 10:05 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
Hi David,
David Edelsohn <dje@watson.ibm.com> writes:
> The following patch cleans up some cruft and formatting in the
> rs6000 port and adds preliminary, basic Power4 support.
>
> While exploring the scheduling, I noticed that cr_logical
> attribute had not been applied to mfcr/mtcrf instructions. This bumps
> performance on processors with multiple SCIUs where cr_logical was being
> scheduled inefficiently.
How does this interact with processors where mfcr/mtcrf instructions
aren't done in the same function unit as other CR logical instructions
(like the 750)?
> *** linux64.h 5 Jun 2002 03:56:27 -0000 1.15
> --- linux64.h 9 Jun 2002 14:40:29 -0000
> *************** Boston, MA 02111-1307, USA. */
> *** 31,36 ****
> --- 31,39 ----
> #define TARGET_DEFAULT \
> (MASK_POWERPC | MASK_POWERPC64 | MASK_64BIT | MASK_NEW_MNEMONICS)
>
> + #undef PROCESSOR_DEFAULT
> + #define PROCESSOR_DEFAULT PROCESSOR_PPC630
> +
> #undef CPP_DEFAULT_SPEC
> #define CPP_DEFAULT_SPEC "-D_ARCH_PPC64"
This almost certainly doesn't do what you wanted. More likely, you
want to change PROCESSOR_DEFAULT64.
I would also suggest changing PROCESSOR_DEFAULT64 for AIX, since the
default is currently rios1.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PowerPC cleanup and Power4
2002-06-09 10:05 ` Geoff Keating
@ 2002-06-09 10:33 ` David Edelsohn
2002-06-09 12:08 ` Geoff Keating
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-06-09 10:33 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
>>>>> Geoff Keating writes:
Geoff> How does this interact with processors where mfcr/mtcrf instructions
Geoff> aren't done in the same function unit as other CR logical instructions
Geoff> (like the 750)?
Slight improvement because the 750 performs them in the complex
integer unit. Previously the instructions were considered integer and
assumed to dispatch on both simple integer pipelines, which was even
worse. It's not perfect, but it's a net improvement for the moment.
Geoff> This almost certainly doesn't do what you wanted. More likely, you
Geoff> want to change PROCESSOR_DEFAULT64.
Oops, right, fixed.
Geoff> I would also suggest changing PROCESSOR_DEFAULT64 for AIX, since the
Geoff> default is currently rios1.
PROCESSOR_DEFAULT64 never was defined as rios1. PROCESSOR_DEFAULT
is defined as rios1 in rs6000.h, but overridden in aix43.h and aix51.h.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PowerPC cleanup and Power4
2002-06-09 10:33 ` David Edelsohn
@ 2002-06-09 12:08 ` Geoff Keating
2002-06-09 12:15 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-06-09 12:08 UTC (permalink / raw)
To: dje; +Cc: gcc-patches
> Date: Sun, 09 Jun 2002 13:33:34 -0400
> From: David Edelsohn <dje@watson.ibm.com>
> Geoff> I would also suggest changing PROCESSOR_DEFAULT64 for AIX, since the
> Geoff> default is currently rios1.
>
> PROCESSOR_DEFAULT64 never was defined as rios1. PROCESSOR_DEFAULT
> is defined as rios1 in rs6000.h, but overridden in aix43.h and aix51.h.
Sorry, I meant "the default is currently rs64k". I expect that most
systems running aix 4.3 are not rs64k any more...
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: PowerPC cleanup and Power4
2002-06-09 12:08 ` Geoff Keating
@ 2002-06-09 12:15 ` David Edelsohn
0 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-06-09 12:15 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
>>>>> Geoff Keating writes:
Geoff> Sorry, I meant "the default is currently rs64k". I expect that most
Geoff> systems running aix 4.3 are not rs64k any more...
For AIX, most are business systems running on something from the
RS64 processor family. Scientific systems would be based Power3-based,
but those users probably don't use the default anyway. I doubt many AIX
users are compiling 64-bit apps with GCC anyway.
Scientific Power3 systems are probably a good assumption for
64-bit PowerPC Linux.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS
@ 2002-07-02 21:18 Matt Kraai
2002-07-03 8:10 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Matt Kraai @ 2002-07-02 21:18 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1695 bytes --]
Howdy,
The following patch converts 32-bit PowerPC GNU/Linux to use
TARGET_OS_CPP_BUILTINS. It was bootstrapped and regression
tested on powerpc-unknown-linux-gnu.
OK to commit?
If desired, I can also submit a patch which converts the other
targets which include rs6000/sysv4.h. I will only test on
powerpc-unknown-linux-gnu and powerpc-eabisim, however.
Matt
* config/rs6000/linux.h (CPP_PREDEFINES): Remove.
(TARGET_OS_CPP_BUILTINS): New.
Index: gcc/config/rs6000/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux.h,v
retrieving revision 1.31
diff -c -3 -p -r1.31 linux.h
*** gcc/config/rs6000/linux.h 3 Dec 2001 00:49:41 -0000 1.31
--- gcc/config/rs6000/linux.h 2 Jul 2002 17:27:45 -0000
*************** Boston, MA 02111-1307, USA. */
*** 28,35 ****
#undef MD_STARTFILE_PREFIX
#undef CPP_PREDEFINES
! #define CPP_PREDEFINES \
! "-DPPC -D__ELF__ -Dpowerpc -Acpu=powerpc -Amachine=powerpc"
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"
--- 28,43 ----
#undef MD_STARTFILE_PREFIX
#undef CPP_PREDEFINES
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("PPC"); \
! builtin_define_std ("__ELF__"); \
! builtin_define_std ("powerpc"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"
[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS
2002-07-02 21:18 convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS Matt Kraai
@ 2002-07-03 8:10 ` David Edelsohn
2002-07-03 9:15 ` Matt Kraai
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-07-03 8:10 UTC (permalink / raw)
To: kraai; +Cc: gcc-patches
I think it would be much better to convert the entire PowerPC port
at once instead of each target separately -- that means AIX and VxWorks,
etc.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS
2002-07-03 8:10 ` David Edelsohn
@ 2002-07-03 9:15 ` Matt Kraai
2002-07-03 9:25 ` Stan Shebs
` (3 more replies)
0 siblings, 4 replies; 875+ messages in thread
From: Matt Kraai @ 2002-07-03 9:15 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 24072 bytes --]
On Wed, Jul 03, 2002 at 10:51:19AM -0400, David Edelsohn wrote:
> I think it would be much better to convert the entire PowerPC port
> at once instead of each target separately -- that means AIX and VxWorks,
> etc.
OK. The following patch converts the entire port. I'm
currently bootstrapping it on powerpc-unknown-linux-gnu. I'd
appreciate other people testing it on some other PowerPC
platforms.
Matt
* config/rs6000/aix.h: Convert CPP_PREDEFINES to
TARGET_OS_CPP_BUILTINS.
* config/rs6000/aix31.h: Likewise.
* config/rs6000/aix41.h: Likewise.
* config/rs6000/aix43.h: Likewise.
* config/rs6000/aix51.h: Likewise.
* config/rs6000/beos.h: Likewise.
* config/rs6000/darwin.h: Likewise.
* config/rs6000/eabi.h: Likewise.
* config/rs6000/eabisim.h: Likewise.
* config/rs6000/linux.h: Likewise.
* config/rs6000/linux64.h: Likewise.
* config/rs6000/lynx.h: Likewise.
* config/rs6000/mach.h: Likewise.
* config/rs6000/rtems.h: Likewise.
* config/rs6000/sysv4.h: Likewise.
* config/rs6000/vxppc.h: Likewise.
Index: gcc/config/rs6000/aix.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/aix.h,v
retrieving revision 1.29
diff -c -3 -p -r1.29 aix.h
*** gcc/config/rs6000/aix.h 11 Jun 2002 23:14:47 -0000 1.29
--- gcc/config/rs6000/aix.h 3 Jul 2002 15:38:09 -0000
*************** Boston, MA 02111-1307, USA. */
*** 41,48 ****
#define LINK_LIBGCC_SPECIAL_1
/* Names to predefine in the preprocessor for this target machine. */
! #define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_LONG_LONG \
! -Asystem=unix -Asystem=aix -Acpu=rs6000 -Amachine=rs6000"
/* Define appropriate architecture macros for preprocessor depending on
target switches. */
--- 41,60 ----
#define LINK_LIBGCC_SPECIAL_1
/* Names to predefine in the preprocessor for this target machine. */
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("_IBMR2"); \
! builtin_define_std ("_POWER"); \
! builtin_define_std ("_AIX"); \
! builtin_define_std ("_AIX32"); \
! builtin_define_std ("_LONG_LONG"); \
! builtin_assert ("system=unix"); \
! builtin_assert ("system=aix"); \
! builtin_assert ("cpu=rs6000"); \
! builtin_assert ("machine=rs6000"); \
! } \
! while (0)
/* Define appropriate architecture macros for preprocessor depending on
target switches. */
Index: gcc/config/rs6000/aix31.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/aix31.h,v
retrieving revision 1.8
diff -c -3 -p -r1.8 aix31.h
*** gcc/config/rs6000/aix31.h 15 Nov 2001 05:21:06 -0000 1.8
--- gcc/config/rs6000/aix31.h 3 Jul 2002 15:38:09 -0000
*************** Boston, MA 02111-1307, USA. */
*** 60,67 ****
}
/* AIX 3.2 defined _AIX32, but older versions do not. */
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "-D_IBMR2 -D_AIX -Asystem=unix -Asystem=aix -Acpu=rs6000 -Amachine=rs6000"
/* AIX 3.1 uses bit 15 in CROR as the magic nop. */
#undef RS6000_CALL_GLUE
--- 60,77 ----
}
/* AIX 3.2 defined _AIX32, but older versions do not. */
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("_IBMR2"); \
! builtin_define_std ("_AIX"); \
! builtin_assert ("system=unix"); \
! builtin_assert ("system=aix"); \
! builtin_assert ("cpu=rs6000"); \
! builtin_assert ("machine=rs6000"); \
! } \
! while (0)
/* AIX 3.1 uses bit 15 in CROR as the magic nop. */
#undef RS6000_CALL_GLUE
Index: gcc/config/rs6000/aix41.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/aix41.h,v
retrieving revision 1.16
diff -c -3 -p -r1.16 aix41.h
*** gcc/config/rs6000/aix41.h 11 Jun 2002 23:14:47 -0000 1.16
--- gcc/config/rs6000/aix41.h 3 Jul 2002 15:38:09 -0000
*************** Boston, MA 02111-1307, USA. */
*** 33,41 ****
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_AIX41 \
! -D_LONG_LONG -Asystem=unix -Asystem=aix"
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
--- 33,52 ----
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("_IBMR2"); \
! builtin_define_std ("_POWER"); \
! builtin_define_std ("_AIX"); \
! builtin_define_std ("_AIX32"); \
! builtin_define_std ("_AIX41"); \
! builtin_define_std ("_LONG_LONG"); \
! builtin_assert ("system=unix"); \
! builtin_assert ("system=aix"); \
! } \
! while (0)
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
Index: gcc/config/rs6000/aix43.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/aix43.h,v
retrieving revision 1.26
diff -c -3 -p -r1.26 aix43.h
*** gcc/config/rs6000/aix43.h 12 Jun 2002 03:06:25 -0000 1.26
--- gcc/config/rs6000/aix43.h 3 Jul 2002 15:38:09 -0000
*************** do { \
*** 96,104 ****
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_AIX41 -D_AIX43 \
! -D_LONG_LONG -Asystem=unix -Asystem=aix"
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
--- 96,116 ----
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("_IBMR2"); \
! builtin_define_std ("_POWER"); \
! builtin_define_std ("_AIX"); \
! builtin_define_std ("_AIX32"); \
! builtin_define_std ("_AIX41"); \
! builtin_define_std ("_AIX43"); \
! builtin_define_std ("_LONG_LONG"); \
! builtin_assert ("system=unix"); \
! builtin_assert ("system=aix"); \
! } \
! while (0)
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
Index: gcc/config/rs6000/aix51.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/aix51.h,v
retrieving revision 1.15
diff -c -3 -p -r1.15 aix51.h
*** gcc/config/rs6000/aix51.h 12 Jun 2002 03:06:26 -0000 1.15
--- gcc/config/rs6000/aix51.h 3 Jul 2002 15:38:09 -0000
*************** do { \
*** 96,104 ****
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_LONG_LONG \
! -D_AIX -D_AIX32 -D_AIX41 -D_AIX43 -D_AIX51 -Asystem=unix -Asystem=aix"
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \
--- 96,117 ----
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("_IBMR2"); \
! builtin_define_std ("_POWER"); \
! builtin_define_std ("_LONG_LONG"); \
! builtin_define_std ("_AIX"); \
! builtin_define_std ("_AIX32"); \
! builtin_define_std ("_AIX41"); \
! builtin_define_std ("_AIX43"); \
! builtin_define_std ("_AIX51"); \
! builtin_assert ("system=unix"); \
! builtin_assert ("system=aix"); \
! } \
! while (0)
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \
Index: gcc/config/rs6000/beos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/beos.h,v
retrieving revision 1.10
diff -c -3 -p -r1.10 beos.h
*** gcc/config/rs6000/beos.h 11 Jun 2002 23:14:47 -0000 1.10
--- gcc/config/rs6000/beos.h 3 Jul 2002 15:38:09 -0000
*************** Boston, MA 02111-1307, USA. */
*** 38,46 ****
#undef ASM_SPEC
#define ASM_SPEC "-u %(asm_cpu)"
! #undef CPP_PREDEFINES
/* __POWERPC__ must be defined for some header files */
! #define CPP_PREDEFINES "-D__BEOS__ -D__POWERPC__ -Asystem=beos -Acpu=powerpc -Amachine=powerpc"
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}"
--- 38,55 ----
#undef ASM_SPEC
#define ASM_SPEC "-u %(asm_cpu)"
! #undef TARGET_OS_CPP_BUILTINS
/* __POWERPC__ must be defined for some header files */
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("__BEOS__"); \
! builtin_define_std ("__POWERPC__"); \
! builtin_assert ("system=beos"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}"
Index: gcc/config/rs6000/darwin.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/darwin.h,v
retrieving revision 1.21
diff -c -3 -p -r1.21 darwin.h
*** gcc/config/rs6000/darwin.h 11 Jun 2002 23:14:47 -0000 1.21
--- gcc/config/rs6000/darwin.h 3 Jul 2002 15:38:09 -0000
*************** Boston, MA 02111-1307, USA. */
*** 44,50 ****
#define SUBTARGET_OVERRIDE_OPTIONS \
rs6000_altivec_abi = 1;
! #define CPP_PREDEFINES "-D__ppc__ -D__POWERPC__ -D__NATURAL_ALIGNMENT__ -D__MACH__ -D__APPLE__"
/* We want -fPIC by default, unless we're using -static to compile for
the kernel or some such. */
--- 44,59 ----
#define SUBTARGET_OVERRIDE_OPTIONS \
rs6000_altivec_abi = 1;
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("__ppc__"); \
! builtin_define_std ("__POWERPC__"); \
! builtin_define_std ("__NATURAL_ALIGNMENT__"); \
! builtin_define_std ("__MACH__"); \
! builtin_define_std ("__APPLE__"); \
! } \
! while (0)
/* We want -fPIC by default, unless we're using -static to compile for
the kernel or some such. */
Index: gcc/config/rs6000/eabi.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/eabi.h,v
retrieving revision 1.5
diff -c -3 -p -r1.5 eabi.h
*** gcc/config/rs6000/eabi.h 2 Nov 2000 23:29:12 -0000 1.5
--- gcc/config/rs6000/eabi.h 3 Jul 2002 15:38:09 -0000
*************** Boston, MA 02111-1307, USA. */
*** 31,36 ****
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)");
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES \
! "-DPPC -D__embedded__ -Asystem=embedded -Acpu=powerpc -Amachine=powerpc"
--- 31,44 ----
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)");
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("PPC"); \
! builtin_define_std ("__embedded__"); \
! builtin_assert ("system=embedded"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
Index: gcc/config/rs6000/eabisim.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/eabisim.h,v
retrieving revision 1.4
diff -c -3 -p -r1.4 eabisim.h
*** gcc/config/rs6000/eabisim.h 2 Nov 2000 23:29:12 -0000 1.4
--- gcc/config/rs6000/eabisim.h 3 Jul 2002 15:38:09 -0000
*************** Boston, MA 02111-1307, USA. */
*** 23,31 ****
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Simulated)");
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES \
! "-DPPC -D__embedded__ -D__simulator__ -Asystem=embedded -Asystem=simulator -Acpu=powerpc -Amachine=powerpc"
/* Make the simulator the default */
#undef LIB_DEFAULT_SPEC
--- 23,41 ----
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Simulated)");
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("PPC"); \
! builtin_define_std ("__embedded__"); \
! builtin_define_std ("__simulator__"); \
! builtin_assert ("system=embedded"); \
! builtin_assert ("system=simulator"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
/* Make the simulator the default */
#undef LIB_DEFAULT_SPEC
Index: gcc/config/rs6000/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux.h,v
retrieving revision 1.31
diff -c -3 -p -r1.31 linux.h
*** gcc/config/rs6000/linux.h 3 Dec 2001 00:49:41 -0000 1.31
--- gcc/config/rs6000/linux.h 3 Jul 2002 15:38:09 -0000
*************** Boston, MA 02111-1307, USA. */
*** 27,35 ****
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES \
! "-DPPC -D__ELF__ -Dpowerpc -Acpu=powerpc -Amachine=powerpc"
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"
--- 27,43 ----
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("PPC"); \
! builtin_define_std ("__ELF__"); \
! builtin_define_std ("powerpc"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"
Index: gcc/config/rs6000/linux64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux64.h,v
retrieving revision 1.19
diff -c -3 -p -r1.19 linux64.h
*** gcc/config/rs6000/linux64.h 12 Jun 2002 03:06:26 -0000 1.19
--- gcc/config/rs6000/linux64.h 3 Jul 2002 15:38:09 -0000
*************** Boston, MA 02111-1307, USA. */
*** 106,116 ****
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES \
! "-D_PPC_ -D__PPC__ -D_PPC64_ -D__PPC64__ -D__powerpc__ -D__powerpc64__ \
! -D_PIC_ -D__PIC__ -D__ELF__ \
! -Acpu=powerpc64 -Amachine=powerpc64"
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"
--- 106,128 ----
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("_PPC_"); \
! builtin_define_std ("__PPC__"); \
! builtin_define_std ("_PPC64_"); \
! builtin_define_std ("__PPC64__"); \
! builtin_define_std ("__powerpc__"); \
! builtin_define_std ("__powerpc64__"); \
! builtin_define_std ("_PIC_"); \
! builtin_define_std ("__PIC__"); \
! builtin_define_std ("__ELF__"); \
! builtin_assert ("cpu=powerpc64"); \
! builtin_assert ("machine=powerpc64"); \
! } \
! while (0)
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"
Index: gcc/config/rs6000/lynx.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/lynx.h,v
retrieving revision 1.10
diff -c -3 -p -r1.10 lynx.h
*** gcc/config/rs6000/lynx.h 18 May 2002 23:47:17 -0000 1.10
--- gcc/config/rs6000/lynx.h 3 Jul 2002 15:38:09 -0000
*************** Boston, MA 02111-1307, USA. */
*** 53,60 ****
#undef DEFAULT_SIGNED_CHAR
#define DEFAULT_SIGNED_CHAR 1
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "-Acpu=rs6000 -Amachine=rs6000 -Asystem=lynx -Asystem=unix -DLynx -D_IBMR2 -Dunix -Drs6000 -Dlynx -DLYNX"
#undef LINK_SPEC
#define LINK_SPEC "-T0x10001000 -H0x1000 -D0x20000000 -btextro -bhalt:4 -bnodelcsect -bnso -bro -bnoglink %{v} %{b*}"
--- 53,74 ----
#undef DEFAULT_SIGNED_CHAR
#define DEFAULT_SIGNED_CHAR 1
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_assert ("cpu=rs6000"); \
! builtin_assert ("machine=rs6000"); \
! builtin_assert ("system=lynx"); \
! builtin_assert ("system=unix"); \
! builtin_define_std ("Lynx"); \
! builtin_define_std ("_IBMR2"); \
! builtin_define_std ("unix"); \
! builtin_define_std ("rs6000"); \
! builtin_define_std ("lynx"); \
! builtin_define_std ("LYNX"); \
! } \
! while (0)
#undef LINK_SPEC
#define LINK_SPEC "-T0x10001000 -H0x1000 -D0x20000000 -btextro -bhalt:4 -bnodelcsect -bnso -bro -bnoglink %{v} %{b*}"
Index: gcc/config/rs6000/mach.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/mach.h,v
retrieving revision 1.6
diff -c -3 -p -r1.6 mach.h
*** gcc/config/rs6000/mach.h 20 Nov 2001 19:43:28 -0000 1.6
--- gcc/config/rs6000/mach.h 3 Jul 2002 15:38:09 -0000
*************** Boston, MA 02111-1307, USA. */
*** 26,33 ****
#define TARGET_VERSION fprintf (stderr, " (Mach-RS/6000)");
/* We don't define AIX under MACH; instead we define `unix'. */
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "-Drios -D_IBMR2 -Dunix -Asystem=unix -Asystem=mach -Acpu=rs6000 -Amachine=rs6000"
/* Define different binder options for MACH. */
#undef LINK_SPEC
--- 26,44 ----
#define TARGET_VERSION fprintf (stderr, " (Mach-RS/6000)");
/* We don't define AIX under MACH; instead we define `unix'. */
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("rios"); \
! builtin_define_std ("_IBMR2"); \
! builtin_define_std ("unix"); \
! builtin_assert ("system=unix"); \
! builtin_assert ("system=mach"); \
! builtin_assert ("cpu=rs6000"); \
! builtin_assert ("machine=rs6000"); \
! } \
! while (0)
/* Define different binder options for MACH. */
#undef LINK_SPEC
Index: gcc/config/rs6000/rtems.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rtems.h,v
retrieving revision 1.14
diff -c -3 -p -r1.14 rtems.h
*** gcc/config/rs6000/rtems.h 12 Apr 2002 13:35:00 -0000 1.14
--- gcc/config/rs6000/rtems.h 3 Jul 2002 15:38:09 -0000
*************** Boston, MA 02111-1307, USA. */
*** 21,26 ****
/* Specify predefined symbols in preprocessor. */
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "-DPPC -D__rtems__ \
! -Asystem=rtems -Acpu=powerpc -Amachine=powerpc"
--- 21,34 ----
/* Specify predefined symbols in preprocessor. */
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("PPC"); \
! builtin_define_std ("__rtems__"); \
! builtin_assert ("system=rtems"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
Index: gcc/config/rs6000/sysv4.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.97
diff -c -3 -p -r1.97 sysv4.h
*** gcc/config/rs6000/sysv4.h 11 Jun 2002 23:14:47 -0000 1.97
--- gcc/config/rs6000/sysv4.h 3 Jul 2002 15:38:10 -0000
*************** do { \
*** 808,816 ****
#define TARGET_VERSION fprintf (stderr, " (PowerPC System V.4)");
#endif
\f
! #ifndef CPP_PREDEFINES
! #define CPP_PREDEFINES \
! "-DPPC -Dunix -D__svr4__ -Asystem=unix -Asystem=svr4 -Acpu=powerpc -Amachine=powerpc"
#endif
/* Pass various options to the assembler. */
--- 808,826 ----
#define TARGET_VERSION fprintf (stderr, " (PowerPC System V.4)");
#endif
\f
! #ifndef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("PPC"); \
! builtin_define_std ("unix"); \
! builtin_define_std ("__svr4__"); \
! builtin_assert ("system=unix"); \
! builtin_assert ("system=svr4"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
#endif
/* Pass various options to the assembler. */
Index: gcc/config/rs6000/vxppc.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/vxppc.h,v
retrieving revision 1.9
diff -c -3 -p -r1.9 vxppc.h
*** gcc/config/rs6000/vxppc.h 11 Jun 2002 23:14:47 -0000 1.9
--- gcc/config/rs6000/vxppc.h 3 Jul 2002 15:38:10 -0000
*************** Boston, MA 02111-1307, USA. */
*** 39,48 ****
#undef LINK_OS_DEFAULT_SPEC
#define LINK_OS_DEFAULT_SPEC "%(link_os_vxworks)"
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "\
! -D__vxworks -D__vxworks__ -Asystem=vxworks -Asystem=embedded \
! -Acpu=powerpc -Amachine=powerpc"
/* We use stabs-in-elf for debugging */
#undef PREFERRED_DEBUGGING_TYPE
--- 39,56 ----
#undef LINK_OS_DEFAULT_SPEC
#define LINK_OS_DEFAULT_SPEC "%(link_os_vxworks)"
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("__vxworks"); \
! builtin_define_std ("__vxworks__"); \
! builtin_assert ("system=vxworks"); \
! builtin_assert ("system=embedded"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
/* We use stabs-in-elf for debugging */
#undef PREFERRED_DEBUGGING_TYPE
[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS
2002-07-03 9:15 ` Matt Kraai
@ 2002-07-03 9:25 ` Stan Shebs
2002-07-03 9:32 ` David Edelsohn
` (2 subsequent siblings)
3 siblings, 0 replies; 875+ messages in thread
From: Stan Shebs @ 2002-07-03 9:25 UTC (permalink / raw)
To: Matt Kraai; +Cc: David Edelsohn, gcc-patches
Matt Kraai wrote:
>
> On Wed, Jul 03, 2002 at 10:51:19AM -0400, David Edelsohn wrote:
> > I think it would be much better to convert the entire PowerPC port
> > at once instead of each target separately -- that means AIX and VxWorks,
> > etc.
>
> OK. The following patch converts the entire port. I'm
> currently bootstrapping it on powerpc-unknown-linux-gnu. I'd
> appreciate other people testing it on some other PowerPC
> platforms.
The Darwin part looks good, I'm happy with you just checking it in.
Stan
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS
2002-07-03 9:15 ` Matt Kraai
2002-07-03 9:25 ` Stan Shebs
@ 2002-07-03 9:32 ` David Edelsohn
2002-07-03 9:36 ` Jason R Thorpe
2002-07-03 23:50 ` Alan Modra
3 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-07-03 9:32 UTC (permalink / raw)
To: Matt Kraai; +Cc: gcc-patches
* config/rs6000/aix.h: Convert CPP_PREDEFINES to
TARGET_OS_CPP_BUILTINS.
* config/rs6000/aix31.h: Likewise.
* config/rs6000/aix41.h: Likewise.
* config/rs6000/aix43.h: Likewise.
* config/rs6000/aix51.h: Likewise.
* config/rs6000/beos.h: Likewise.
* config/rs6000/darwin.h: Likewise.
* config/rs6000/eabi.h: Likewise.
* config/rs6000/eabisim.h: Likewise.
* config/rs6000/linux.h: Likewise.
* config/rs6000/linux64.h: Likewise.
* config/rs6000/lynx.h: Likewise.
* config/rs6000/mach.h: Likewise.
* config/rs6000/rtems.h: Likewise.
* config/rs6000/sysv4.h: Likewise.
* config/rs6000/vxppc.h: Likewise.
This looks fine to check in.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS
2002-07-03 9:15 ` Matt Kraai
2002-07-03 9:25 ` Stan Shebs
2002-07-03 9:32 ` David Edelsohn
@ 2002-07-03 9:36 ` Jason R Thorpe
2002-07-03 10:29 ` Matt Kraai
2002-07-03 23:50 ` Alan Modra
3 siblings, 1 reply; 875+ messages in thread
From: Jason R Thorpe @ 2002-07-03 9:36 UTC (permalink / raw)
To: kraai; +Cc: gcc-patches
On Wed, Jul 03, 2002 at 08:52:47AM -0700, Matt Kraai wrote:
> /* Names to predefine in the preprocessor for this target machine. */
> ! #define TARGET_OS_CPP_BUILTINS() \
> ! do \
> ! { \
> ! builtin_define_std ("_IBMR2"); \
> ! builtin_define_std ("_POWER"); \
> ! builtin_define_std ("_AIX"); \
> ! builtin_define_std ("_AIX32"); \
> ! builtin_define_std ("_LONG_LONG"); \
All these which already have _ at the beginning of their names don't
need builtin_define_std, only builtin_define.
> --- 38,55 ----
> #undef ASM_SPEC
> #define ASM_SPEC "-u %(asm_cpu)"
>
> ! #undef TARGET_OS_CPP_BUILTINS
> /* __POWERPC__ must be defined for some header files */
> ! #define TARGET_OS_CPP_BUILTINS() \
> ! do \
> ! { \
> ! builtin_define_std ("__BEOS__"); \
> ! builtin_define_std ("__POWERPC__"); \
...ditto for these.
> --- 31,44 ----
> #undef TARGET_VERSION
> #define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)");
>
> ! #undef TARGET_OS_CPP_BUILTINS
> ! #define TARGET_OS_CPP_BUILTINS() \
> ! do \
> ! { \
> ! builtin_define_std ("PPC"); \
This one, however, is a correct use of builtin_define_std.
--
-- Jason R. Thorpe <thorpej@wasabisystems.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS
2002-07-03 9:36 ` Jason R Thorpe
@ 2002-07-03 10:29 ` Matt Kraai
0 siblings, 0 replies; 875+ messages in thread
From: Matt Kraai @ 2002-07-03 10:29 UTC (permalink / raw)
To: Jason R Thorpe, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 26124 bytes --]
On Wed, Jul 03, 2002 at 09:35:26AM -0700, Jason R Thorpe wrote:
> On Wed, Jul 03, 2002 at 08:52:47AM -0700, Matt Kraai wrote:
>
> > /* Names to predefine in the preprocessor for this target machine. */
> > ! #define TARGET_OS_CPP_BUILTINS() \
> > ! do \
> > ! { \
> > ! builtin_define_std ("_IBMR2"); \
> > ! builtin_define_std ("_POWER"); \
> > ! builtin_define_std ("_AIX"); \
> > ! builtin_define_std ("_AIX32"); \
> > ! builtin_define_std ("_LONG_LONG"); \
>
> All these which already have _ at the beginning of their names don't
> need builtin_define_std, only builtin_define.
The following patch documents this in tm.texi and passes `make
info' and `make dvi'. OK to commit?
* doc/tm.texi (TARGET_CPU_CPP_BUILTINS): Document when
builtin_define is preferred over builtin_define_std.
Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.143
diff -c -3 -r1.143 tm.texi
*** gcc/doc/tm.texi 27 Jun 2002 17:19:04 -0000 1.143
--- gcc/doc/tm.texi 3 Jul 2002 17:07:42 -0000
***************
*** 609,614 ****
--- 609,617 ----
@code{__mips__} and possibly @code{_mips}, and passing @code{_ABI64}
defines only @code{_ABI64}.
+ For object-like macros which do not lie in the user's namespace, use
+ @code{builtin_define}.
+
You can also test for the C dialect being compiled. The variable
@code{c_language} is set to one of @code{clk_c}, @code{clk_cplusplus}
or @code{clk_objective_c}. Note that if we are preprocessing
> > #undef ASM_SPEC
> > #define ASM_SPEC "-u %(asm_cpu)"
> >
> > ! #undef TARGET_OS_CPP_BUILTINS
> > /* __POWERPC__ must be defined for some header files */
> > ! #define TARGET_OS_CPP_BUILTINS() \
> > ! do \
> > ! { \
> > ! builtin_define_std ("__BEOS__"); \
> > ! builtin_define_std ("__POWERPC__"); \
>
> ...ditto for these.
>
> > #undef TARGET_VERSION
> > #define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)");
> >
> > ! #undef TARGET_OS_CPP_BUILTINS
> > ! #define TARGET_OS_CPP_BUILTINS() \
> > ! do \
> > ! { \
> > ! builtin_define_std ("PPC"); \
>
> This one, however, is a correct use of builtin_define_std.
I've converted the definitions of all macros which lie in the
user's namespace to use builtin_define instead of
builtin_define_std. If the bootstrap and regression testing on
powerpc-unknown-linux-gnu are successful, OK to commit?
Matt
* aix.h: Convert from CPP_PREDEFINES to TARGET_OS_CPP_BUILTINS.
* aix31.h: Likewise.
* aix41.h: Likewise.
* aix43.h: Likewise.
* aix51.h: Likewise.
* beos.h: Likewise.
* darwin.h: Likewise.
* eabi.h: Likewise.
* eabisim.h: Likewise.
* linux.h: Likewise.
* linux64.h: Likewise.
* lynx.h: Likewise.
* mach.h: Likewise.
* rtems.h: Likewise.
* sysv4.h: Likewise.
* vxppc.h: Likewise.
Index: gcc/config/rs6000/aix.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/aix.h,v
retrieving revision 1.29
diff -c -3 -p -r1.29 aix.h
*** gcc/config/rs6000/aix.h 11 Jun 2002 23:14:47 -0000 1.29
--- gcc/config/rs6000/aix.h 3 Jul 2002 17:08:49 -0000
*************** Boston, MA 02111-1307, USA. */
*** 41,48 ****
#define LINK_LIBGCC_SPECIAL_1
/* Names to predefine in the preprocessor for this target machine. */
! #define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_LONG_LONG \
! -Asystem=unix -Asystem=aix -Acpu=rs6000 -Amachine=rs6000"
/* Define appropriate architecture macros for preprocessor depending on
target switches. */
--- 41,60 ----
#define LINK_LIBGCC_SPECIAL_1
/* Names to predefine in the preprocessor for this target machine. */
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define ("_IBMR2"); \
! builtin_define ("_POWER"); \
! builtin_define ("_AIX"); \
! builtin_define ("_AIX32"); \
! builtin_define ("_LONG_LONG"); \
! builtin_assert ("system=unix"); \
! builtin_assert ("system=aix"); \
! builtin_assert ("cpu=rs6000"); \
! builtin_assert ("machine=rs6000"); \
! } \
! while (0)
/* Define appropriate architecture macros for preprocessor depending on
target switches. */
Index: gcc/config/rs6000/aix31.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/aix31.h,v
retrieving revision 1.8
diff -c -3 -p -r1.8 aix31.h
*** gcc/config/rs6000/aix31.h 15 Nov 2001 05:21:06 -0000 1.8
--- gcc/config/rs6000/aix31.h 3 Jul 2002 17:08:50 -0000
*************** Boston, MA 02111-1307, USA. */
*** 60,67 ****
}
/* AIX 3.2 defined _AIX32, but older versions do not. */
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "-D_IBMR2 -D_AIX -Asystem=unix -Asystem=aix -Acpu=rs6000 -Amachine=rs6000"
/* AIX 3.1 uses bit 15 in CROR as the magic nop. */
#undef RS6000_CALL_GLUE
--- 60,77 ----
}
/* AIX 3.2 defined _AIX32, but older versions do not. */
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define ("_IBMR2"); \
! builtin_define ("_AIX"); \
! builtin_assert ("system=unix"); \
! builtin_assert ("system=aix"); \
! builtin_assert ("cpu=rs6000"); \
! builtin_assert ("machine=rs6000"); \
! } \
! while (0)
/* AIX 3.1 uses bit 15 in CROR as the magic nop. */
#undef RS6000_CALL_GLUE
Index: gcc/config/rs6000/aix41.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/aix41.h,v
retrieving revision 1.16
diff -c -3 -p -r1.16 aix41.h
*** gcc/config/rs6000/aix41.h 11 Jun 2002 23:14:47 -0000 1.16
--- gcc/config/rs6000/aix41.h 3 Jul 2002 17:08:50 -0000
*************** Boston, MA 02111-1307, USA. */
*** 33,41 ****
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_AIX41 \
! -D_LONG_LONG -Asystem=unix -Asystem=aix"
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
--- 33,52 ----
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define ("_IBMR2"); \
! builtin_define ("_POWER"); \
! builtin_define ("_AIX"); \
! builtin_define ("_AIX32"); \
! builtin_define ("_AIX41"); \
! builtin_define ("_LONG_LONG"); \
! builtin_assert ("system=unix"); \
! builtin_assert ("system=aix"); \
! } \
! while (0)
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
Index: gcc/config/rs6000/aix43.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/aix43.h,v
retrieving revision 1.26
diff -c -3 -p -r1.26 aix43.h
*** gcc/config/rs6000/aix43.h 12 Jun 2002 03:06:25 -0000 1.26
--- gcc/config/rs6000/aix43.h 3 Jul 2002 17:08:50 -0000
*************** do { \
*** 96,104 ****
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_AIX41 -D_AIX43 \
! -D_LONG_LONG -Asystem=unix -Asystem=aix"
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
--- 96,116 ----
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define ("_IBMR2"); \
! builtin_define ("_POWER"); \
! builtin_define ("_AIX"); \
! builtin_define ("_AIX32"); \
! builtin_define ("_AIX41"); \
! builtin_define ("_AIX43"); \
! builtin_define ("_LONG_LONG"); \
! builtin_assert ("system=unix"); \
! builtin_assert ("system=aix"); \
! } \
! while (0)
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
Index: gcc/config/rs6000/aix51.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/aix51.h,v
retrieving revision 1.15
diff -c -3 -p -r1.15 aix51.h
*** gcc/config/rs6000/aix51.h 12 Jun 2002 03:06:26 -0000 1.15
--- gcc/config/rs6000/aix51.h 3 Jul 2002 17:08:50 -0000
*************** do { \
*** 96,104 ****
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_LONG_LONG \
! -D_AIX -D_AIX32 -D_AIX41 -D_AIX43 -D_AIX51 -Asystem=unix -Asystem=aix"
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \
--- 96,117 ----
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define ("_IBMR2"); \
! builtin_define ("_POWER"); \
! builtin_define ("_LONG_LONG"); \
! builtin_define ("_AIX"); \
! builtin_define ("_AIX32"); \
! builtin_define ("_AIX41"); \
! builtin_define ("_AIX43"); \
! builtin_define ("_AIX51"); \
! builtin_assert ("system=unix"); \
! builtin_assert ("system=aix"); \
! } \
! while (0)
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \
Index: gcc/config/rs6000/beos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/beos.h,v
retrieving revision 1.10
diff -c -3 -p -r1.10 beos.h
*** gcc/config/rs6000/beos.h 11 Jun 2002 23:14:47 -0000 1.10
--- gcc/config/rs6000/beos.h 3 Jul 2002 17:08:50 -0000
*************** Boston, MA 02111-1307, USA. */
*** 38,46 ****
#undef ASM_SPEC
#define ASM_SPEC "-u %(asm_cpu)"
! #undef CPP_PREDEFINES
/* __POWERPC__ must be defined for some header files */
! #define CPP_PREDEFINES "-D__BEOS__ -D__POWERPC__ -Asystem=beos -Acpu=powerpc -Amachine=powerpc"
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}"
--- 38,55 ----
#undef ASM_SPEC
#define ASM_SPEC "-u %(asm_cpu)"
! #undef TARGET_OS_CPP_BUILTINS
/* __POWERPC__ must be defined for some header files */
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define ("__BEOS__"); \
! builtin_define ("__POWERPC__"); \
! builtin_assert ("system=beos"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}"
Index: gcc/config/rs6000/darwin.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/darwin.h,v
retrieving revision 1.21
diff -c -3 -p -r1.21 darwin.h
*** gcc/config/rs6000/darwin.h 11 Jun 2002 23:14:47 -0000 1.21
--- gcc/config/rs6000/darwin.h 3 Jul 2002 17:08:50 -0000
*************** Boston, MA 02111-1307, USA. */
*** 44,50 ****
#define SUBTARGET_OVERRIDE_OPTIONS \
rs6000_altivec_abi = 1;
! #define CPP_PREDEFINES "-D__ppc__ -D__POWERPC__ -D__NATURAL_ALIGNMENT__ -D__MACH__ -D__APPLE__"
/* We want -fPIC by default, unless we're using -static to compile for
the kernel or some such. */
--- 44,59 ----
#define SUBTARGET_OVERRIDE_OPTIONS \
rs6000_altivec_abi = 1;
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define ("__ppc__"); \
! builtin_define ("__POWERPC__"); \
! builtin_define ("__NATURAL_ALIGNMENT__"); \
! builtin_define ("__MACH__"); \
! builtin_define ("__APPLE__"); \
! } \
! while (0)
/* We want -fPIC by default, unless we're using -static to compile for
the kernel or some such. */
Index: gcc/config/rs6000/eabi.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/eabi.h,v
retrieving revision 1.5
diff -c -3 -p -r1.5 eabi.h
*** gcc/config/rs6000/eabi.h 2 Nov 2000 23:29:12 -0000 1.5
--- gcc/config/rs6000/eabi.h 3 Jul 2002 17:08:50 -0000
*************** Boston, MA 02111-1307, USA. */
*** 31,36 ****
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)");
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES \
! "-DPPC -D__embedded__ -Asystem=embedded -Acpu=powerpc -Amachine=powerpc"
--- 31,44 ----
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded)");
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("PPC"); \
! builtin_define ("__embedded__"); \
! builtin_assert ("system=embedded"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
Index: gcc/config/rs6000/eabisim.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/eabisim.h,v
retrieving revision 1.4
diff -c -3 -p -r1.4 eabisim.h
*** gcc/config/rs6000/eabisim.h 2 Nov 2000 23:29:12 -0000 1.4
--- gcc/config/rs6000/eabisim.h 3 Jul 2002 17:08:50 -0000
*************** Boston, MA 02111-1307, USA. */
*** 23,31 ****
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Simulated)");
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES \
! "-DPPC -D__embedded__ -D__simulator__ -Asystem=embedded -Asystem=simulator -Acpu=powerpc -Amachine=powerpc"
/* Make the simulator the default */
#undef LIB_DEFAULT_SPEC
--- 23,41 ----
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Simulated)");
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("PPC"); \
! builtin_define ("__embedded__"); \
! builtin_define ("__simulator__"); \
! builtin_assert ("system=embedded"); \
! builtin_assert ("system=simulator"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
/* Make the simulator the default */
#undef LIB_DEFAULT_SPEC
Index: gcc/config/rs6000/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux.h,v
retrieving revision 1.31
diff -c -3 -p -r1.31 linux.h
*** gcc/config/rs6000/linux.h 3 Dec 2001 00:49:41 -0000 1.31
--- gcc/config/rs6000/linux.h 3 Jul 2002 17:08:50 -0000
*************** Boston, MA 02111-1307, USA. */
*** 27,35 ****
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES \
! "-DPPC -D__ELF__ -Dpowerpc -Acpu=powerpc -Amachine=powerpc"
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"
--- 27,43 ----
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("PPC"); \
! builtin_define ("__ELF__"); \
! builtin_define_std ("powerpc"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"
Index: gcc/config/rs6000/linux64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux64.h,v
retrieving revision 1.19
diff -c -3 -p -r1.19 linux64.h
*** gcc/config/rs6000/linux64.h 12 Jun 2002 03:06:26 -0000 1.19
--- gcc/config/rs6000/linux64.h 3 Jul 2002 17:08:50 -0000
*************** Boston, MA 02111-1307, USA. */
*** 106,116 ****
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES \
! "-D_PPC_ -D__PPC__ -D_PPC64_ -D__PPC64__ -D__powerpc__ -D__powerpc64__ \
! -D_PIC_ -D__PIC__ -D__ELF__ \
! -Acpu=powerpc64 -Amachine=powerpc64"
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"
--- 106,128 ----
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define ("_PPC_"); \
! builtin_define ("__PPC__"); \
! builtin_define ("_PPC64_"); \
! builtin_define ("__PPC64__"); \
! builtin_define ("__powerpc__"); \
! builtin_define ("__powerpc64__"); \
! builtin_define ("_PIC_"); \
! builtin_define ("__PIC__"); \
! builtin_define ("__ELF__"); \
! builtin_assert ("cpu=powerpc64"); \
! builtin_assert ("machine=powerpc64"); \
! } \
! while (0)
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"
Index: gcc/config/rs6000/lynx.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/lynx.h,v
retrieving revision 1.10
diff -c -3 -p -r1.10 lynx.h
*** gcc/config/rs6000/lynx.h 18 May 2002 23:47:17 -0000 1.10
--- gcc/config/rs6000/lynx.h 3 Jul 2002 17:08:50 -0000
*************** Boston, MA 02111-1307, USA. */
*** 53,60 ****
#undef DEFAULT_SIGNED_CHAR
#define DEFAULT_SIGNED_CHAR 1
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "-Acpu=rs6000 -Amachine=rs6000 -Asystem=lynx -Asystem=unix -DLynx -D_IBMR2 -Dunix -Drs6000 -Dlynx -DLYNX"
#undef LINK_SPEC
#define LINK_SPEC "-T0x10001000 -H0x1000 -D0x20000000 -btextro -bhalt:4 -bnodelcsect -bnso -bro -bnoglink %{v} %{b*}"
--- 53,74 ----
#undef DEFAULT_SIGNED_CHAR
#define DEFAULT_SIGNED_CHAR 1
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_assert ("cpu=rs6000"); \
! builtin_assert ("machine=rs6000"); \
! builtin_assert ("system=lynx"); \
! builtin_assert ("system=unix"); \
! builtin_define_std ("Lynx"); \
! builtin_define ("_IBMR2"); \
! builtin_define_std ("unix"); \
! builtin_define_std ("rs6000"); \
! builtin_define_std ("lynx"); \
! builtin_define_std ("LYNX"); \
! } \
! while (0)
#undef LINK_SPEC
#define LINK_SPEC "-T0x10001000 -H0x1000 -D0x20000000 -btextro -bhalt:4 -bnodelcsect -bnso -bro -bnoglink %{v} %{b*}"
Index: gcc/config/rs6000/mach.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/mach.h,v
retrieving revision 1.6
diff -c -3 -p -r1.6 mach.h
*** gcc/config/rs6000/mach.h 20 Nov 2001 19:43:28 -0000 1.6
--- gcc/config/rs6000/mach.h 3 Jul 2002 17:08:50 -0000
*************** Boston, MA 02111-1307, USA. */
*** 26,33 ****
#define TARGET_VERSION fprintf (stderr, " (Mach-RS/6000)");
/* We don't define AIX under MACH; instead we define `unix'. */
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "-Drios -D_IBMR2 -Dunix -Asystem=unix -Asystem=mach -Acpu=rs6000 -Amachine=rs6000"
/* Define different binder options for MACH. */
#undef LINK_SPEC
--- 26,44 ----
#define TARGET_VERSION fprintf (stderr, " (Mach-RS/6000)");
/* We don't define AIX under MACH; instead we define `unix'. */
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("rios"); \
! builtin_define ("_IBMR2"); \
! builtin_define_std ("unix"); \
! builtin_assert ("system=unix"); \
! builtin_assert ("system=mach"); \
! builtin_assert ("cpu=rs6000"); \
! builtin_assert ("machine=rs6000"); \
! } \
! while (0)
/* Define different binder options for MACH. */
#undef LINK_SPEC
Index: gcc/config/rs6000/rtems.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rtems.h,v
retrieving revision 1.14
diff -c -3 -p -r1.14 rtems.h
*** gcc/config/rs6000/rtems.h 12 Apr 2002 13:35:00 -0000 1.14
--- gcc/config/rs6000/rtems.h 3 Jul 2002 17:08:50 -0000
*************** Boston, MA 02111-1307, USA. */
*** 21,26 ****
/* Specify predefined symbols in preprocessor. */
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "-DPPC -D__rtems__ \
! -Asystem=rtems -Acpu=powerpc -Amachine=powerpc"
--- 21,34 ----
/* Specify predefined symbols in preprocessor. */
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("PPC"); \
! builtin_define ("__rtems__"); \
! builtin_assert ("system=rtems"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
Index: gcc/config/rs6000/sysv4.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.97
diff -c -3 -p -r1.97 sysv4.h
*** gcc/config/rs6000/sysv4.h 11 Jun 2002 23:14:47 -0000 1.97
--- gcc/config/rs6000/sysv4.h 3 Jul 2002 17:08:50 -0000
*************** do { \
*** 808,816 ****
#define TARGET_VERSION fprintf (stderr, " (PowerPC System V.4)");
#endif
\f
! #ifndef CPP_PREDEFINES
! #define CPP_PREDEFINES \
! "-DPPC -Dunix -D__svr4__ -Asystem=unix -Asystem=svr4 -Acpu=powerpc -Amachine=powerpc"
#endif
/* Pass various options to the assembler. */
--- 808,826 ----
#define TARGET_VERSION fprintf (stderr, " (PowerPC System V.4)");
#endif
\f
! #ifndef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define_std ("PPC"); \
! builtin_define_std ("unix"); \
! builtin_define ("__svr4__"); \
! builtin_assert ("system=unix"); \
! builtin_assert ("system=svr4"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
#endif
/* Pass various options to the assembler. */
Index: gcc/config/rs6000/vxppc.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/vxppc.h,v
retrieving revision 1.9
diff -c -3 -p -r1.9 vxppc.h
*** gcc/config/rs6000/vxppc.h 11 Jun 2002 23:14:47 -0000 1.9
--- gcc/config/rs6000/vxppc.h 3 Jul 2002 17:08:50 -0000
*************** Boston, MA 02111-1307, USA. */
*** 39,48 ****
#undef LINK_OS_DEFAULT_SPEC
#define LINK_OS_DEFAULT_SPEC "%(link_os_vxworks)"
! #undef CPP_PREDEFINES
! #define CPP_PREDEFINES "\
! -D__vxworks -D__vxworks__ -Asystem=vxworks -Asystem=embedded \
! -Acpu=powerpc -Amachine=powerpc"
/* We use stabs-in-elf for debugging */
#undef PREFERRED_DEBUGGING_TYPE
--- 39,56 ----
#undef LINK_OS_DEFAULT_SPEC
#define LINK_OS_DEFAULT_SPEC "%(link_os_vxworks)"
! #undef TARGET_OS_CPP_BUILTINS
! #define TARGET_OS_CPP_BUILTINS() \
! do \
! { \
! builtin_define ("__vxworks"); \
! builtin_define ("__vxworks__"); \
! builtin_assert ("system=vxworks"); \
! builtin_assert ("system=embedded"); \
! builtin_assert ("cpu=powerpc"); \
! builtin_assert ("machine=powerpc"); \
! } \
! while (0)
/* We use stabs-in-elf for debugging */
#undef PREFERRED_DEBUGGING_TYPE
[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS
2002-07-03 9:15 ` Matt Kraai
` (2 preceding siblings ...)
2002-07-03 9:36 ` Jason R Thorpe
@ 2002-07-03 23:50 ` Alan Modra
2002-07-04 9:22 ` David Edelsohn
3 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-07-03 23:50 UTC (permalink / raw)
To: David Edelsohn, gcc-patches
On Wed, Jul 03, 2002 at 08:52:47AM -0700, Matt Kraai wrote:
> Index: gcc/config/rs6000/linux64.h
[snip]
> --- 106,128 ----
> #undef MD_EXEC_PREFIX
> #undef MD_STARTFILE_PREFIX
>
> ! #undef TARGET_OS_CPP_BUILTINS
> ! #define TARGET_OS_CPP_BUILTINS() \
> ! do \
> ! { \
> ! builtin_define_std ("_PPC_"); \
> ! builtin_define_std ("__PPC__"); \
> ! builtin_define_std ("_PPC64_"); \
> ! builtin_define_std ("__PPC64__"); \
> ! builtin_define_std ("__powerpc__"); \
> ! builtin_define_std ("__powerpc64__"); \
> ! builtin_define_std ("_PIC_"); \
> ! builtin_define_std ("__PIC__"); \
> ! builtin_define_std ("__ELF__"); \
> ! builtin_assert ("cpu=powerpc64"); \
> ! builtin_assert ("machine=powerpc64"); \
> ! } \
> ! while (0)
Since powerpc64-linux is a relatively new target, is there good reason
to define _PPC_, _PPC64_ and _PIC_?
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS
2002-07-03 23:50 ` Alan Modra
@ 2002-07-04 9:22 ` David Edelsohn
2002-07-08 18:27 ` Matt Kraai
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-07-04 9:22 UTC (permalink / raw)
To: gcc-patches
> Since powerpc64-linux is a relatively new target, is there good reason
> to define _PPC_, _PPC64_ and _PIC_?
I guess we can remove those macros. I guess GNU likes double
underscores, even when it is unecessary for upper case names.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS
2002-07-04 9:22 ` David Edelsohn
@ 2002-07-08 18:27 ` Matt Kraai
2002-07-08 19:05 ` Geoff Keating
2002-07-08 19:16 ` David Edelsohn
0 siblings, 2 replies; 875+ messages in thread
From: Matt Kraai @ 2002-07-08 18:27 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1437 bytes --]
On Thu, Jul 04, 2002 at 12:19:19PM -0400, David Edelsohn wrote:
> > Since powerpc64-linux is a relatively new target, is there good reason
> > to define _PPC_, _PPC64_ and _PIC_?
>
> I guess we can remove those macros. I guess GNU likes double
> underscores, even when it is unecessary for upper case names.
The following patch removes the aforementioned macros. Is it
possible to test it on powerpc-unknown-linux-gnu, and if so,
how?
Matt
* config/rs6000/linux64.h (CPP_PREDEFINES): Do not
define _PPC_, _PPC64_, or _PIC_.
Index: gcc/config/rs6000/linux64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux64.h,v
retrieving revision 1.19
diff -c -3 -p -r1.19 linux64.h
*** gcc/config/rs6000/linux64.h 12 Jun 2002 03:06:26 -0000 1.19
--- gcc/config/rs6000/linux64.h 8 Jul 2002 22:55:55 -0000
*************** Boston, MA 02111-1307, USA. */
*** 108,115 ****
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
! "-D_PPC_ -D__PPC__ -D_PPC64_ -D__PPC64__ -D__powerpc__ -D__powerpc64__ \
! -D_PIC_ -D__PIC__ -D__ELF__ \
-Acpu=powerpc64 -Amachine=powerpc64"
#undef CPP_OS_DEFAULT_SPEC
--- 108,114 ----
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
! "-D__PPC__ -D__PPC64__ -D__powerpc__ -D__powerpc64__ -D__PIC__ -D__ELF__ \
-Acpu=powerpc64 -Amachine=powerpc64"
#undef CPP_OS_DEFAULT_SPEC
[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS
2002-07-08 18:27 ` Matt Kraai
@ 2002-07-08 19:05 ` Geoff Keating
2002-07-08 19:16 ` David Edelsohn
1 sibling, 0 replies; 875+ messages in thread
From: Geoff Keating @ 2002-07-08 19:05 UTC (permalink / raw)
To: Matt Kraai; +Cc: gcc-patches
Matt Kraai <kraai@alumni.cmu.edu> writes:
> On Thu, Jul 04, 2002 at 12:19:19PM -0400, David Edelsohn wrote:
> > > Since powerpc64-linux is a relatively new target, is there good reason
> > > to define _PPC_, _PPC64_ and _PIC_?
> >
> > I guess we can remove those macros. I guess GNU likes double
> > underscores, even when it is unecessary for upper case names.
>
> The following patch removes the aforementioned macros. Is it
> possible to test it on powerpc-unknown-linux-gnu, and if so,
> how?
Um, bootstrap on a powerpc-linux machine?
The patch clearly can't affect powerpc-linux, because that header file
isn't used there.
> * config/rs6000/linux64.h (CPP_PREDEFINES): Do not
> define _PPC_, _PPC64_, or _PIC_.
>
> Index: gcc/config/rs6000/linux64.h
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux64.h,v
> retrieving revision 1.19
> diff -c -3 -p -r1.19 linux64.h
> *** gcc/config/rs6000/linux64.h 12 Jun 2002 03:06:26 -0000 1.19
> --- gcc/config/rs6000/linux64.h 8 Jul 2002 22:55:55 -0000
> *************** Boston, MA 02111-1307, USA. */
> *** 108,115 ****
>
> #undef CPP_PREDEFINES
> #define CPP_PREDEFINES \
> ! "-D_PPC_ -D__PPC__ -D_PPC64_ -D__PPC64__ -D__powerpc__ -D__powerpc64__ \
> ! -D_PIC_ -D__PIC__ -D__ELF__ \
> -Acpu=powerpc64 -Amachine=powerpc64"
>
> #undef CPP_OS_DEFAULT_SPEC
> --- 108,114 ----
>
> #undef CPP_PREDEFINES
> #define CPP_PREDEFINES \
> ! "-D__PPC__ -D__PPC64__ -D__powerpc__ -D__powerpc64__ -D__PIC__ -D__ELF__ \
> -Acpu=powerpc64 -Amachine=powerpc64"
>
> #undef CPP_OS_DEFAULT_SPEC
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS
2002-07-08 18:27 ` Matt Kraai
2002-07-08 19:05 ` Geoff Keating
@ 2002-07-08 19:16 ` David Edelsohn
2002-07-09 0:37 ` Matt Kraai
1 sibling, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-07-08 19:16 UTC (permalink / raw)
To: Matt Kraai; +Cc: gcc-patches
Just removes those macros with single underscores from your patch
converting to the new infrastructure.
Are you going to apply your patch or do you need someone to do it
for you?
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: convert 32-bit PowerPC GNU/Linux to TARGET_OS_CPP_BUILTINS
2002-07-08 19:16 ` David Edelsohn
@ 2002-07-09 0:37 ` Matt Kraai
0 siblings, 0 replies; 875+ messages in thread
From: Matt Kraai @ 2002-07-09 0:37 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 495 bytes --]
On Mon, Jul 08, 2002 at 10:05:13PM -0400, David Edelsohn wrote:
> Just removes those macros with single underscores from your patch
> converting to the new infrastructure.
>
> Are you going to apply your patch or do you need someone to do it
> for you?
I wasn't sure whether I should commit it. Neil Booth's reply
indicated that he didn't think I should. Thus, I was planning
to cleanup the CPP_PREDEFINES handling first, and then
transition to TARGET_OS_CPP_BUILTINS.
Matt
[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-05-21 18:54 thread-local storage: c front end and generic backend patch Richard Henderson
2002-05-22 4:25 ` Joseph S. Myers
2002-05-22 13:53 ` Mark Mitchell
@ 2002-07-11 9:00 ` David Edelsohn
2002-07-11 11:02 ` Richard Henderson
2 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-07-11 9:00 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches
The tls patch has changed GCC's behavior so that it no longer
emits uninitialize data in the common section, as the GCC Internals
documentation has stated would occur if BSS macros were not defined.
* c-decl.c (start_decl): Do not set DECL_COMMON for tls variables.
- if (!initialized && (! flag_no_common || ! TREE_PUBLIC (decl)))
+ if (TREE_CODE (decl) == VAR_DECL
+ && !initialized
+ && TREE_PUBLIC (decl)
+ && !DECL_THREAD_LOCAL (decl)
+ && !flag_no_common)
DECL_COMMON (decl) = 1;
This part of your patch from May did more than just change the
behavior for tls variables, it limited DECL_COMMON to variables marked
TREE_PUBLIC. Prior to your patch, variables without TREE_PUBLIC flag were
marked DECL_COMMON.
At the point where varasm.c:assemble_variable() considers unitialized
data, it tests DECL_COMMON if no BSS macro is defined:
#ifndef ASM_EMIT_BSS
/* If the target can't output uninitialized but not common global data
in .bss, then we have to use .data. */
/* ??? We should handle .bss via select_section mechanisms rather than
via special target hooks. That would eliminate this special case. */
else if (!DECL_COMMON (decl))
;
#endif
else if (DECL_INITIAL (decl) == 0
|| DECL_INITIAL (decl) == error_mark_node
|| (flag_zero_initialized_in_bss
&& initializer_zerop (DECL_INITIAL (decl))))
{
...
asm_emit_uninitialised (decl, name, size, rounded);
}
The tm.texi section for ASM_OUTPUT_BSS states:
If this macro and @code{ASM_OUTPUT_ALIGNED_BSS} are not defined then
@code{ASM_OUTPUT_COMMON} or @code{ASM_OUTPUT_ALIGNED_COMMON} or
@code{ASM_OUTPUT_ALIGNED_DECL_COMMON} is used.
and BSS_SECTION_ASM_OP:
If not defined, and neither @code{ASM_OUTPUT_BSS} nor
@code{ASM_OUTPUT_ALIGNED_BSS} are defined, uninitialized global data will
be output in the data section if @option{-fno-common} is passed, otherwise
@code{ASM_OUTPUT_COMMON} will be used.
ASM_OUTPUT_COMMON no longer is used in the absence of -fno-common as
documented. All systems without BSS definitions now are using initialized
data instead of common. If that is intentional, all targets without BSS
definitions need to be updated.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: thread-local storage: c front end and generic backend patch
2002-07-11 9:00 ` David Edelsohn
@ 2002-07-11 11:02 ` Richard Henderson
2002-07-26 11:08 ` [PATCH] " David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-07-11 11:02 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
On Thu, Jul 11, 2002 at 11:28:57AM -0400, David Edelsohn wrote:
> This part of your patch from May did more than just change the
> behavior for tls variables, it limited DECL_COMMON to variables marked
> TREE_PUBLIC. Prior to your patch, variables without TREE_PUBLIC flag were
> marked DECL_COMMON.
Hmm. Ok. I can see why I made the change -- COMMON does not
make sense without PUBLIC. I'll adjust assemble_variable and
its subroutines to compensate.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: target/7282: powerpc64 SImode in FPR
[not found] <20020712071414.GR30362@bubble.sa.bigpond.net.au>
@ 2002-07-13 4:58 ` Alan Modra
2002-07-13 7:25 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-07-13 4:58 UTC (permalink / raw)
To: gcc-gnats; +Cc: gcc-patches, David Edelsohn
This cures the ICE. Thanks to dje for putting me on the right track.
gcc/ChangeLog
PR 7282
* config/rs6000/rs6000.md (floatsidf2): Enable for POWERPC64.
(floatsidf_ppc64): New insn_and_split.
Checked with gcc-3.1 i686-linux -> powerpc64-linux cross-compiler.
Bootstrapping and regresssion testing powerpc-linux mainline just to
be sure.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
diff -up gcc-ppc64-31.orig/gcc/config/rs6000/rs6000.md gcc-ppc64-31/gcc/config/rs6000/rs6000.md
--- gcc-ppc64-31.orig/gcc/config/rs6000/rs6000.md 2002-07-04 19:40:32.000000000 +0930
+++ gcc-ppc64-31/gcc/config/rs6000/rs6000.md 2002-07-13 20:26:05.000000000 +0930
@@ -5271,9 +5428,18 @@
(clobber (match_dup 4))
(clobber (match_dup 5))
(clobber (match_dup 6))])]
- "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
+ "TARGET_HARD_FLOAT"
"
{
+ if (TARGET_POWERPC64)
+ {
+ rtx mem = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
+ rtx t1 = gen_reg_rtx (DImode);
+ rtx t2 = gen_reg_rtx (DImode);
+ emit_insn (gen_floatsidf_ppc64 (operands[0], operands[1], mem, t1, t2));
+ DONE;
+ }
+
operands[2] = force_reg (SImode, GEN_INT (0x43300000));
operands[3] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode));
operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
@@ -5456,6 +5622,22 @@
"fcfid %0,%1"
[(set_attr "type" "fp")])
+(define_insn_and_split "floatsidf_ppc64"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (float:DF (match_operand:SI 1 "gpc_reg_operand" "*f")))
+ (clobber (match_operand:DI 2 "memory_operand" "=o"))
+ (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))
+ (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
+ "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
+ "#"
+ ""
+ [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
+ (set (match_dup 2) (match_dup 3))
+ (set (match_dup 4) (match_dup 2))
+ (set (match_dup 0) (float:DF (match_dup 4)))]
+ ""
+ [(set_attr "type" "fp")])
+
(define_insn "fix_truncdfdi2"
[(set (match_operand:DI 0 "gpc_reg_operand" "=*f")
(fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: target/7282: powerpc64 SImode in FPR
2002-07-13 4:58 ` target/7282: powerpc64 SImode in FPR Alan Modra
@ 2002-07-13 7:25 ` David Edelsohn
2002-07-13 23:36 ` Alan Modra
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-07-13 7:25 UTC (permalink / raw)
To: gcc-gnats, gcc-patches
This looks okay except for
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (float:DF (match_operand:SI 1 "gpc_reg_operand" "*f")))
+ (clobber (match_operand:DI 2 "memory_operand" "=o"))
+ (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))
+ (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
The input SImode operand should have constraint "r", not "*f". The whole
point of this pattern is to move the SImode operand from the GPR to the
FPR because GCC sometimes gets confused when asked to do this itself.
SImode is not allowed in FPRs, so the "*f" constraint is contradictory.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: target/7282: powerpc64 SImode in FPR
2002-07-13 7:25 ` David Edelsohn
@ 2002-07-13 23:36 ` Alan Modra
2002-07-14 7:59 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-07-13 23:36 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-gnats, gcc-patches
On Sat, Jul 13, 2002 at 10:18:54AM -0400, David Edelsohn wrote:
> This looks okay except for
>
> + [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
> + (float:DF (match_operand:SI 1 "gpc_reg_operand" "*f")))
> + (clobber (match_operand:DI 2 "memory_operand" "=o"))
> + (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))
> + (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
>
> The input SImode operand should have constraint "r", not "*f". The whole
> point of this pattern is to move the SImode operand from the GPR to the
> FPR because GCC sometimes gets confused when asked to do this itself.
> SImode is not allowed in FPRs, so the "*f" constraint is contradictory.
Revised patch follows, incorporating your floatunssidf2 suggestion too.
PR target/7282
* config/rs6000/rs6000.md (floatsidf2): Enable for POWERPC64.
(floatunssidf2): Likewise.
(floatsidf_ppc64): New insn_and_split.
(floatunssidf_ppc64): Likewise.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
Index: gcc/config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.192
diff -u -p -r1.192 rs6000.md
--- gcc/config/rs6000/rs6000.md 3 Jul 2002 14:41:22 -0000 1.192
+++ gcc/config/rs6000/rs6000.md 14 Jul 2002 05:38:17 -0000
@@ -5350,9 +5350,18 @@
(clobber (match_dup 4))
(clobber (match_dup 5))
(clobber (match_dup 6))])]
- "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
+ "TARGET_HARD_FLOAT"
"
{
+ if (TARGET_POWERPC64)
+ {
+ rtx mem = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
+ rtx t1 = gen_reg_rtx (DImode);
+ rtx t2 = gen_reg_rtx (DImode);
+ emit_insn (gen_floatsidf_ppc64 (operands[0], operands[1], mem, t1, t2));
+ DONE;
+ }
+
operands[2] = force_reg (SImode, GEN_INT (0x43300000));
operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
@@ -5417,9 +5426,19 @@
(use (match_dup 3))
(clobber (match_dup 4))
(clobber (match_dup 5))])]
- "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
+ "TARGET_HARD_FLOAT"
"
{
+ if (TARGET_POWERPC64)
+ {
+ rtx mem = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
+ rtx t1 = gen_reg_rtx (DImode);
+ rtx t2 = gen_reg_rtx (DImode);
+ emit_insn (gen_floatunssidf_ppc64 (operands[0], operands[1], mem,
+ t1, t2));
+ DONE;
+ }
+
operands[2] = force_reg (SImode, GEN_INT (0x43300000));
operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
@@ -5533,6 +5552,38 @@
(float:DF (match_operand:DI 1 "gpc_reg_operand" "*f")))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"fcfid %0,%1"
+ [(set_attr "type" "fp")])
+
+(define_insn_and_split "floatsidf_ppc64"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
+ (clobber (match_operand:DI 2 "memory_operand" "=o"))
+ (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))
+ (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
+ "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
+ "#"
+ ""
+ [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
+ (set (match_dup 2) (match_dup 3))
+ (set (match_dup 4) (match_dup 2))
+ (set (match_dup 0) (float:DF (match_dup 4)))]
+ ""
+ [(set_attr "type" "fp")])
+
+(define_insn_and_split "floatunssidf_ppc64"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
+ (clobber (match_operand:DI 2 "memory_operand" "=o"))
+ (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))
+ (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
+ "TARGET_POWERPC64 && TARGET_HARD_FLOAT"
+ "#"
+ ""
+ [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
+ (set (match_dup 2) (match_dup 3))
+ (set (match_dup 4) (match_dup 2))
+ (set (match_dup 0) (float:DF (match_dup 4)))]
+ ""
[(set_attr "type" "fp")])
(define_insn "fix_truncdfdi2"
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: target/7282: powerpc64 SImode in FPR
2002-07-13 23:36 ` Alan Modra
@ 2002-07-14 7:59 ` David Edelsohn
0 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-07-14 7:59 UTC (permalink / raw)
To: Alan Modra; +Cc: gcc-patches
This is fine to commit to the mainline, but please remove
[(set_attr "type" "fp")]
from the define_insn_and_split patterns.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
[not found] <20020625081846.10430.qmail@sources.redhat.com>
@ 2002-07-15 2:43 ` Alan Modra
2002-07-15 5:22 ` Alan Modra
2002-07-15 12:51 ` Geoff Keating
0 siblings, 2 replies; 875+ messages in thread
From: Alan Modra @ 2002-07-15 2:43 UTC (permalink / raw)
To: d.mueller; +Cc: gcc-gnats, gcc-patches, David Edelsohn, geoffk
This patch cures the testcase. The !using_store_multiple code tests
whether regs are live before saving. We need to do something similar
for using_store_multiple, in case all regs need not be saved.
* config/rs6000/rs6000.c (rs6000_emit_prologue): Trim saved regs
for -mmultiple case like -mno-multiple case.
(rs6000_emit_epilogue): Likewise.
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.291.2.13
diff -u -p -r1.291.2.13 rs6000.c
--- gcc/config/rs6000/rs6000.c 23 May 2002 23:22:44 -0000 1.291.2.13
+++ gcc/config/rs6000/rs6000.c 15 Jul 2002 09:06:31 -0000
@@ -8836,30 +8836,45 @@ rs6000_emit_prologue ()
the store-multiple instructions. */
if (using_store_multiple)
{
- rtvec p, dwarfp;
- int i;
- p = rtvec_alloc (32 - info->first_gp_reg_save);
- dwarfp = rtvec_alloc (32 - info->first_gp_reg_save);
- for (i = 0; i < 32 - info->first_gp_reg_save; i++)
+ int n = info->first_gp_reg_save;
+
+ while (n < 32
+ && !((regs_ever_live[n]
+ && ! call_used_regs[n])
+ || (n == RS6000_PIC_OFFSET_TABLE_REGNUM
+ && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
+ || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
+ n++;
+
+ if (n < 32)
{
- rtx addr, reg, mem;
- reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
- addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
- GEN_INT (info->gp_save_offset
- + sp_offset
- + reg_size * i));
- mem = gen_rtx_MEM (reg_mode, addr);
- set_mem_alias_set (mem, rs6000_sr_alias_set);
+ rtvec p, dwarfp;
+ int i;
+
+ p = rtvec_alloc (32 - n);
+ dwarfp = rtvec_alloc (32 - n);
+ for (i = 0; i < 32 - n; i++)
+ {
+ rtx addr, reg, mem;
+ reg = gen_rtx_REG (reg_mode, n + i);
+ addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ GEN_INT (info->gp_save_offset
+ + sp_offset
+ + reg_size * i));
+ mem = gen_rtx_MEM (reg_mode, addr);
+ set_mem_alias_set (mem, rs6000_sr_alias_set);
- RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
+ RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
+ }
+ insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
+ rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+ NULL_RTX, NULL_RTX);
}
- insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
- rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
- NULL_RTX, NULL_RTX);
}
else
{
int i;
+
for (i = 0; i < 32 - info->first_gp_reg_save; i++)
if ((regs_ever_live[info->first_gp_reg_save+i]
&& ! call_used_regs[info->first_gp_reg_save+i])
@@ -9226,24 +9241,38 @@ rs6000_emit_epilogue (sibcall)
the load-multiple instructions. */
if (using_load_multiple)
{
- rtvec p;
- p = rtvec_alloc (32 - info->first_gp_reg_save);
- for (i = 0; i < 32 - info->first_gp_reg_save; i++)
- {
- rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
- GEN_INT (info->gp_save_offset
- + sp_offset
- + reg_size * i));
- rtx mem = gen_rtx_MEM (reg_mode, addr);
+ int n = info->first_gp_reg_save;
- set_mem_alias_set (mem, rs6000_sr_alias_set);
+ while (n < 32
+ && !((regs_ever_live[n]
+ && ! call_used_regs[n])
+ || (n == RS6000_PIC_OFFSET_TABLE_REGNUM
+ && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
+ || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
+ n++;
+
+ if (n < 32)
+ {
+ rtvec p;
- RTVEC_ELT (p, i) =
- gen_rtx_SET (VOIDmode,
- gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
- mem);
+ p = rtvec_alloc (32 - n);
+ for (i = 0; i < 32 - n; i++)
+ {
+ rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ GEN_INT (info->gp_save_offset
+ + sp_offset
+ + reg_size * i));
+ rtx mem = gen_rtx_MEM (reg_mode, addr);
+
+ set_mem_alias_set (mem, rs6000_sr_alias_set);
+
+ RTVEC_ELT (p, i) =
+ gen_rtx_SET (VOIDmode,
+ gen_rtx_REG (reg_mode, n + i),
+ mem);
+ }
+ emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
}
- emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
}
else
for (i = 0; i < 32 - info->first_gp_reg_save; i++)
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-15 2:43 ` other/7114: ICE building strcoll.op from glibc-2.2.5 Alan Modra
@ 2002-07-15 5:22 ` Alan Modra
2002-07-15 12:51 ` Geoff Keating
1 sibling, 0 replies; 875+ messages in thread
From: Alan Modra @ 2002-07-15 5:22 UTC (permalink / raw)
To: David Edelsohn, geoffk; +Cc: gcc-patches
On Mon, Jul 15, 2002 at 06:56:03PM +0930, Alan Modra wrote:
> This patch cures the testcase. The !using_store_multiple code tests
> whether regs are live before saving. We need to do something similar
> for using_store_multiple, in case all regs need not be saved.
>
> * config/rs6000/rs6000.c (rs6000_emit_prologue): Trim saved regs
> for -mmultiple case like -mno-multiple case.
> (rs6000_emit_epilogue): Likewise.
While this does cure the ICE, on further investigation, I'm not happy.
I think trimming off the saved regs in the -mno-multiple case is
wrong, and the above patch just copies wrong code. Why isn't
first_reg_to_save giving us the right number?
The answer to this is that r30 isn't being marked as used in the
current_function_needs_context case. PR 5967 is one result.
What's the right way to fix this? Using get_hard_reg_initial_val
for the static chain reg?
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-15 2:43 ` other/7114: ICE building strcoll.op from glibc-2.2.5 Alan Modra
2002-07-15 5:22 ` Alan Modra
@ 2002-07-15 12:51 ` Geoff Keating
2002-07-15 16:54 ` Alan Modra
1 sibling, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-07-15 12:51 UTC (permalink / raw)
To: amodra; +Cc: d.mueller, gcc-gnats, gcc-patches, dje
> Date: Mon, 15 Jul 2002 18:56:03 +0930
> From: Alan Modra <amodra@bigpond.net.au>
> This patch cures the testcase. The !using_store_multiple code tests
> whether regs are live before saving. We need to do something similar
> for using_store_multiple, in case all regs need not be saved.
Those registers are actually saved, whether they need to be or not,
correct?
So the RTL generated is an accurate representation of the instruction,
and the bug must be elsewhere.
> * config/rs6000/rs6000.c (rs6000_emit_prologue): Trim saved regs
> for -mmultiple case like -mno-multiple case.
> (rs6000_emit_epilogue): Likewise.
>
> Index: gcc/config/rs6000/rs6000.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
> retrieving revision 1.291.2.13
> diff -u -p -r1.291.2.13 rs6000.c
> --- gcc/config/rs6000/rs6000.c 23 May 2002 23:22:44 -0000 1.291.2.13
> +++ gcc/config/rs6000/rs6000.c 15 Jul 2002 09:06:31 -0000
> @@ -8836,30 +8836,45 @@ rs6000_emit_prologue ()
> the store-multiple instructions. */
> if (using_store_multiple)
> {
> - rtvec p, dwarfp;
> - int i;
> - p = rtvec_alloc (32 - info->first_gp_reg_save);
> - dwarfp = rtvec_alloc (32 - info->first_gp_reg_save);
> - for (i = 0; i < 32 - info->first_gp_reg_save; i++)
> + int n = info->first_gp_reg_save;
> +
> + while (n < 32
> + && !((regs_ever_live[n]
> + && ! call_used_regs[n])
> + || (n == RS6000_PIC_OFFSET_TABLE_REGNUM
> + && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
> + || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
> + n++;
> +
> + if (n < 32)
> {
> - rtx addr, reg, mem;
> - reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
> - addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
> - GEN_INT (info->gp_save_offset
> - + sp_offset
> - + reg_size * i));
> - mem = gen_rtx_MEM (reg_mode, addr);
> - set_mem_alias_set (mem, rs6000_sr_alias_set);
> + rtvec p, dwarfp;
> + int i;
> +
> + p = rtvec_alloc (32 - n);
> + dwarfp = rtvec_alloc (32 - n);
> + for (i = 0; i < 32 - n; i++)
> + {
> + rtx addr, reg, mem;
> + reg = gen_rtx_REG (reg_mode, n + i);
> + addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
> + GEN_INT (info->gp_save_offset
> + + sp_offset
> + + reg_size * i));
> + mem = gen_rtx_MEM (reg_mode, addr);
> + set_mem_alias_set (mem, rs6000_sr_alias_set);
>
> - RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
> + RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
> + }
> + insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
> + rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
> + NULL_RTX, NULL_RTX);
> }
> - insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
> - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
> - NULL_RTX, NULL_RTX);
> }
> else
> {
> int i;
> +
> for (i = 0; i < 32 - info->first_gp_reg_save; i++)
> if ((regs_ever_live[info->first_gp_reg_save+i]
> && ! call_used_regs[info->first_gp_reg_save+i])
> @@ -9226,24 +9241,38 @@ rs6000_emit_epilogue (sibcall)
> the load-multiple instructions. */
> if (using_load_multiple)
> {
> - rtvec p;
> - p = rtvec_alloc (32 - info->first_gp_reg_save);
> - for (i = 0; i < 32 - info->first_gp_reg_save; i++)
> - {
> - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
> - GEN_INT (info->gp_save_offset
> - + sp_offset
> - + reg_size * i));
> - rtx mem = gen_rtx_MEM (reg_mode, addr);
> + int n = info->first_gp_reg_save;
>
> - set_mem_alias_set (mem, rs6000_sr_alias_set);
> + while (n < 32
> + && !((regs_ever_live[n]
> + && ! call_used_regs[n])
> + || (n == RS6000_PIC_OFFSET_TABLE_REGNUM
> + && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
> + || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
> + n++;
> +
> + if (n < 32)
> + {
> + rtvec p;
>
> - RTVEC_ELT (p, i) =
> - gen_rtx_SET (VOIDmode,
> - gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
> - mem);
> + p = rtvec_alloc (32 - n);
> + for (i = 0; i < 32 - n; i++)
> + {
> + rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
> + GEN_INT (info->gp_save_offset
> + + sp_offset
> + + reg_size * i));
> + rtx mem = gen_rtx_MEM (reg_mode, addr);
> +
> + set_mem_alias_set (mem, rs6000_sr_alias_set);
> +
> + RTVEC_ELT (p, i) =
> + gen_rtx_SET (VOIDmode,
> + gen_rtx_REG (reg_mode, n + i),
> + mem);
> + }
> + emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
> }
> - emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
> }
> else
> for (i = 0; i < 32 - info->first_gp_reg_save; i++)
>
> --
> Alan Modra
> IBM OzLabs - Linux Technology Centre
>
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-15 12:51 ` Geoff Keating
@ 2002-07-15 16:54 ` Alan Modra
2002-07-15 18:38 ` Alan Modra
2002-07-16 10:46 ` Geoff Keating
0 siblings, 2 replies; 875+ messages in thread
From: Alan Modra @ 2002-07-15 16:54 UTC (permalink / raw)
To: Geoff Keating; +Cc: d.mueller, gcc-gnats, gcc-patches, dje
On Mon, Jul 15, 2002 at 12:43:02PM -0700, Geoff Keating wrote:
> > Date: Mon, 15 Jul 2002 18:56:03 +0930
> > From: Alan Modra <amodra@bigpond.net.au>
>
> > This patch cures the testcase. The !using_store_multiple code tests
> > whether regs are live before saving. We need to do something similar
> > for using_store_multiple, in case all regs need not be saved.
>
> Those registers are actually saved, whether they need to be or not,
> correct?
>
> So the RTL generated is an accurate representation of the instruction,
> and the bug must be elsewhere.
The testcase saves r30 and r31, but both are marked unused (don't
appear in regs_ever_live). Later rtl analysis decides that the
save instruction can be eliminated, thus the ICE. The real bug is
that r30 is not marked used when current_function_needs_context.
This is also the reason for PR5967.
The code that I copied from the !using_store_multiple case just
papers over this bug. So the above patch merely makes -mmultiple
and -mno-multiple consistently wrong.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-15 16:54 ` Alan Modra
@ 2002-07-15 18:38 ` Alan Modra
2002-07-15 22:08 ` Richard Henderson
2002-07-16 11:23 ` Geoff Keating
2002-07-16 10:46 ` Geoff Keating
1 sibling, 2 replies; 875+ messages in thread
From: Alan Modra @ 2002-07-15 18:38 UTC (permalink / raw)
To: Geoff Keating, d.mueller, gcc-gnats, gcc-patches, dje
On Tue, Jul 16, 2002 at 09:20:27AM +0930, Alan Modra wrote:
> The testcase saves r30 and r31, but both are marked unused (don't
> appear in regs_ever_live). Later rtl analysis decides that the
> save instruction can be eliminated, thus the ICE. The real bug is
> that r30 is not marked used when current_function_needs_context.
> This is also the reason for PR5967.
>
> The code that I copied from the !using_store_multiple case just
> papers over this bug. So the above patch merely makes -mmultiple
> and -mno-multiple consistently wrong.
It gets worse. rs6000/sysv4.h sets PROFILE_BEFORE_PROLOGUE. That
means it is completely wrong for first_reg_to_save to decide r30
needs saving when profiling and current_function_needs_context.
It's too late to think about saving r30. What really needs to
happen is one of
a) Don't use PROFILE_BEFORE_PROLOGUE.
or
b) Save the static chain reg on the stack somewhere before the mcount
call.
or
c) Clobber r30 in a call to a nested function when profiling is
enabled.
People would probably scream if we went with (a) as special purpose
implementations of mcount might make assumptions about the stack.
So, anyone want to speak up on the best way to solve this?
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-15 18:38 ` Alan Modra
@ 2002-07-15 22:08 ` Richard Henderson
2002-07-16 0:03 ` Alan Modra
2002-07-16 11:23 ` Geoff Keating
1 sibling, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-07-15 22:08 UTC (permalink / raw)
To: Geoff Keating, d.mueller, gcc-gnats, gcc-patches, dje
On Tue, Jul 16, 2002 at 11:08:16AM +0930, Alan Modra wrote:
> It gets worse. rs6000/sysv4.h sets PROFILE_BEFORE_PROLOGUE.
Make rs6000/sysv4.h can use PROFILE_HOOK instead.
I don't know what the ppc svr4 _mcount abi looks like, but I know that
you can emit any sort of rtl you want, which pretty much means that you
can avoid all of these register allocation problems by making an actual
register allocator take care of them.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-15 22:08 ` Richard Henderson
@ 2002-07-16 0:03 ` Alan Modra
0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2002-07-16 0:03 UTC (permalink / raw)
To: Richard Henderson, Geoff Keating, d.mueller, gcc-gnats, gcc-patches, dje
On Mon, Jul 15, 2002 at 09:31:24PM -0700, Richard Henderson wrote:
> On Tue, Jul 16, 2002 at 11:08:16AM +0930, Alan Modra wrote:
> > It gets worse. rs6000/sysv4.h sets PROFILE_BEFORE_PROLOGUE.
>
> Make rs6000/sysv4.h can use PROFILE_HOOK instead.
Aye, that's the nice way to do it. However, on powerpc64-linux,
I've had kernel people complaining that the profiling code isn't
what they want: All those register saves from the prologue
preceding the mcount call apparently are messing up accurate
count values, and it's hard for an mcount implementation to
adjust times, or so I'm told. I implemented a simple hack to
do PROFILE_BEFORE_PROLOGUE on powerpc64-linux for people who
want it.
I suspect we'll get the same sort of complaint if we change
powerpc mcount. There's also the issue that some special-purpose
mcount functions may expect to be called before the stack has
been adjusted.
I'm rapidly approaching the point where I either give up on this
problem, or simply remove support for profiling on nested
functions. The current code just doesn't work.
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-15 16:54 ` Alan Modra
2002-07-15 18:38 ` Alan Modra
@ 2002-07-16 10:46 ` Geoff Keating
1 sibling, 0 replies; 875+ messages in thread
From: Geoff Keating @ 2002-07-16 10:46 UTC (permalink / raw)
To: amodra; +Cc: d.mueller, gcc-gnats, gcc-patches, dje
> Date: Tue, 16 Jul 2002 09:20:27 +0930
> From: Alan Modra <amodra@bigpond.net.au>
> On Mon, Jul 15, 2002 at 12:43:02PM -0700, Geoff Keating wrote:
> > > Date: Mon, 15 Jul 2002 18:56:03 +0930
> > > From: Alan Modra <amodra@bigpond.net.au>
> >
> > > This patch cures the testcase. The !using_store_multiple code tests
> > > whether regs are live before saving. We need to do something similar
> > > for using_store_multiple, in case all regs need not be saved.
> >
> > Those registers are actually saved, whether they need to be or not,
> > correct?
> >
> > So the RTL generated is an accurate representation of the instruction,
> > and the bug must be elsewhere.
>
> The testcase saves r30 and r31, but both are marked unused (don't
> appear in regs_ever_live). Later rtl analysis decides that the
> save instruction can be eliminated, thus the ICE. The real bug is
> that r30 is not marked used when current_function_needs_context.
> This is also the reason for PR5967.
>
> The code that I copied from the !using_store_multiple case just
> papers over this bug. So the above patch merely makes -mmultiple
> and -mno-multiple consistently wrong.
No, the code below causes unused registers to actually not be saved,
which is correct (it does sometimes happen that all uses of a register
are eliminated after reload). This can be done when individual loads
and stores are being used, you just don't emit that store. It can't
be done when store-multiple is being used.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-15 18:38 ` Alan Modra
2002-07-15 22:08 ` Richard Henderson
@ 2002-07-16 11:23 ` Geoff Keating
2002-07-16 18:51 ` Alan Modra
1 sibling, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-07-16 11:23 UTC (permalink / raw)
To: amodra; +Cc: d.mueller, gcc-gnats, gcc-patches, dje
> Date: Tue, 16 Jul 2002 11:08:16 +0930
> From: Alan Modra <amodra@bigpond.net.au>
> Mail-Followup-To: Geoff Keating <geoffk@redhat.com>, d.mueller@elsoft.ch,
> gcc-gnats@gcc.gnu.org, gcc-patches@gcc.gnu.org, dje@watson.ibm.com
> Content-Disposition: inline
> User-Agent: Mutt/1.3.25i
>
> On Tue, Jul 16, 2002 at 09:20:27AM +0930, Alan Modra wrote:
> > The testcase saves r30 and r31, but both are marked unused (don't
> > appear in regs_ever_live). Later rtl analysis decides that the
> > save instruction can be eliminated, thus the ICE. The real bug is
> > that r30 is not marked used when current_function_needs_context.
> > This is also the reason for PR5967.
> >
> > The code that I copied from the !using_store_multiple case just
> > papers over this bug. So the above patch merely makes -mmultiple
> > and -mno-multiple consistently wrong.
>
> It gets worse. rs6000/sysv4.h sets PROFILE_BEFORE_PROLOGUE. That
> means it is completely wrong for first_reg_to_save to decide r30
> needs saving when profiling and current_function_needs_context.
> It's too late to think about saving r30. What really needs to
> happen is one of
>
> a) Don't use PROFILE_BEFORE_PROLOGUE.
> or
> b) Save the static chain reg on the stack somewhere before the mcount
> call.
> or
> c) Clobber r30 in a call to a nested function when profiling is
> enabled.
>
> People would probably scream if we went with (a) as special purpose
> implementations of mcount might make assumptions about the stack.
> So, anyone want to speak up on the best way to solve this?
The profiling function isn't allowed to clobber r30. It never has
been, so this should be no surprise.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-16 11:23 ` Geoff Keating
@ 2002-07-16 18:51 ` Alan Modra
2002-07-16 22:07 ` Alan Modra
2002-07-17 0:58 ` Geoff Keating
0 siblings, 2 replies; 875+ messages in thread
From: Alan Modra @ 2002-07-16 18:51 UTC (permalink / raw)
To: Geoff Keating; +Cc: d.mueller, gcc-gnats, gcc-patches, dje
On Tue, Jul 16, 2002 at 10:48:14AM -0700, Geoff Keating wrote:
> The profiling function isn't allowed to clobber r30. It never has
> been, so this should be no surprise.
I'm not quite sure what to make of this response. We're talking about
this code from rs6000.c:10479
if (current_function_needs_context)
asm_fprintf (file, "\tmr %s,%s\n",
reg_names[30], reg_names[STATIC_CHAIN_REGNUM]);
fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
if (current_function_needs_context)
asm_fprintf (file, "\tmr %s,%s\n",
reg_names[STATIC_CHAIN_REGNUM], reg_names[30]);
This is currently emitted _before_ the prologue in the nested function,
thus trashes r30. I was considering the idea of adding a clobber of
r30 to CALL_INSN_FUNCTION_USAGE when calling a nested function. That's
a workable solution, but means you need to zap r30 on all calls via
function pointers too.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-16 18:51 ` Alan Modra
@ 2002-07-16 22:07 ` Alan Modra
2002-07-17 0:58 ` Geoff Keating
1 sibling, 0 replies; 875+ messages in thread
From: Alan Modra @ 2002-07-16 22:07 UTC (permalink / raw)
To: Geoff Keating, d.mueller, gcc-gnats, gcc-patches, dje
PR target/5967, PR other/7114
* config/rs6000/r6000.c (first_reg_to_save): Remove bogus
adjustments to first_reg for profiling case.
(output_function_profiler): Correct lr save slot for ABI_AIX_NODESC.
Disable profiling for nested functions on ABI_V4, and for 64 bit
code on both ABI_V4 and ABI_AIX_NODESC. Save static chain reg
to sp + 12 on ABI_AIX_NODESC.
Rationale:
* config/rs6000/r6000.c (first_reg_to_save): Remove bogus
adjustments to first_reg for profiling case.
first_reg_to_save doesn't need to do anything special for any of these
registers as profiling is done via PROFILE_HOOK when ABI_AIX or
ABI_DARWIN. The normal register allocation code will set up
regs_ever_live for us. We're killing profiling on nested functions
when ABI_V4.
(output_function_profiler): Correct lr save slot for ABI_AIX_NODESC.
ABI_AIX_NODESC saves lr to sp + 8. This change is perhaps a little
contentious as existing mcount implementations may take into account
the current ABI breakage.
Disable profiling for nested functions on ABI_V4
See the comment below.
and for 64 bit code on both ABI_V4 and ABI_AIX_NODESC.
The instructions emitted here are 32 bit ones.
Save static chain reg to sp + 12 on ABI_AIX_NODESC.
We need to save it somewhere, or disable profiling of nested functions
for ABI_AIX_NODESC too.
bootstrapped (a slightly different patch) and regression tested
powerpc-linux. I'm re-running the bootstrap now. Built powerpc-linux
and powerpc64-linux glibc --enable-profile to test ABI_V4 and ABI_AIX
changes.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.343
diff -u -p -r1.343 rs6000.c
--- rs6000.c 16 Jul 2002 02:16:41 -0000 1.343
+++ rs6000.c 17 Jul 2002 03:43:03 -0000
@@ -7357,53 +7357,6 @@ first_reg_to_save ()
|| (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
break;
- if (current_function_profile)
- {
- /* AIX must save/restore every register that contains a parameter
- before/after the .__mcount call plus an additional register
- for the static chain, if needed; use registers from 30 down to 22
- to do this. */
- if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
- {
- int last_parm_reg, profile_first_reg;
-
- /* Figure out last used parameter register. The proper thing
- to do is to walk incoming args of the function. A function
- might have live parameter registers even if it has no
- incoming args. */
- for (last_parm_reg = 10;
- last_parm_reg > 2 && ! regs_ever_live [last_parm_reg];
- last_parm_reg--)
- ;
-
- /* Calculate first reg for saving parameter registers
- and static chain.
- Skip reg 31 which may contain the frame pointer. */
- profile_first_reg = (33 - last_parm_reg
- - (current_function_needs_context ? 1 : 0));
-#if TARGET_MACHO
- /* Need to skip another reg to account for R31 being PICBASE
- (when flag_pic is set) or R30 being used as the frame
- pointer (when flag_pic is not set). */
- --profile_first_reg;
-#endif
- /* Do not save frame pointer if no parameters needs to be saved. */
- if (profile_first_reg == 31)
- profile_first_reg = 32;
-
- if (first_reg > profile_first_reg)
- first_reg = profile_first_reg;
- }
-
- /* SVR4 may need one register to preserve the static chain. */
- else if (current_function_needs_context)
- {
- /* Skip reg 31 which may contain the frame pointer. */
- if (first_reg > 30)
- first_reg = 30;
- }
- }
-
#if TARGET_MACHO
if (flag_pic && current_function_uses_pic_offset_table &&
(first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM))
@@ -10430,6 +10383,8 @@ output_function_profiler (file, labelno)
int labelno;
{
char buf[100];
+ int save_lr = 8;
+ int save_chain = 12;
ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
switch (DEFAULT_ABI)
@@ -10438,13 +10393,35 @@ output_function_profiler (file, labelno)
abort ();
case ABI_V4:
+ if (current_function_needs_context)
+ {
+ /* There's no safe way to save STATIC_CHAIN_REGNUM around
+ the mcount call. The ABI_V4 stack has no slot available,
+ and since we are PROFILE_BEFORE_PROLOGUE, we can't use a
+ call-saved register. Adjusting the stack to give us some
+ space might confuse special purpose mcount functions.
+ And finally, clobbering a callee saved register for the
+ purpose of saving the static chain when calling a nested
+ function is difficult to get right; You might be calling
+ a nested function via a function pointer. */
+ warning ("no profiling on nested functions for this ABI");
+ return;
+ }
+ save_lr = 4;
+ /* Fall through. */
+
case ABI_AIX_NODESC:
+ if (!TARGET_32BIT)
+ {
+ warning ("no profiling of 64-bit code for this ABI");
+ return;
+ }
fprintf (file, "\tmflr %s\n", reg_names[0]);
if (flag_pic == 1)
{
fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
- asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
- reg_names[0], reg_names[1]);
+ asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
+ reg_names[0], save_lr, reg_names[1]);
asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
assemble_name (file, buf);
@@ -10452,8 +10429,8 @@ output_function_profiler (file, labelno)
}
else if (flag_pic > 1)
{
- asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
- reg_names[0], reg_names[1]);
+ asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
+ reg_names[0], save_lr, reg_names[1]);
/* Now, we need to get the address of the label. */
fputs ("\tbl 1f\n\t.long ", file);
assemble_name (file, buf);
@@ -10469,20 +10446,25 @@ output_function_profiler (file, labelno)
asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
assemble_name (file, buf);
fputs ("@ha\n", file);
- asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
- reg_names[0], reg_names[1]);
+ asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
+ reg_names[0], save_lr, reg_names[1]);
asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
assemble_name (file, buf);
asm_fprintf (file, "@l(%s)\n", reg_names[12]);
}
if (current_function_needs_context)
- asm_fprintf (file, "\tmr %s,%s\n",
- reg_names[30], reg_names[STATIC_CHAIN_REGNUM]);
- fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
- if (current_function_needs_context)
- asm_fprintf (file, "\tmr %s,%s\n",
- reg_names[STATIC_CHAIN_REGNUM], reg_names[30]);
+ {
+ asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
+ reg_names[STATIC_CHAIN_REGNUM],
+ save_chain, reg_names[1]);
+ fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
+ asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n",
+ reg_names[STATIC_CHAIN_REGNUM],
+ save_chain, reg_names[1]);
+ }
+ else
+ fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
break;
case ABI_AIX:
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-16 18:51 ` Alan Modra
2002-07-16 22:07 ` Alan Modra
@ 2002-07-17 0:58 ` Geoff Keating
2002-07-17 2:04 ` Alan Modra
2002-07-17 8:45 ` David Edelsohn
1 sibling, 2 replies; 875+ messages in thread
From: Geoff Keating @ 2002-07-17 0:58 UTC (permalink / raw)
To: amodra; +Cc: d.mueller, gcc-gnats, gcc-patches, dje
> Date: Wed, 17 Jul 2002 11:17:39 +0930
> From: Alan Modra <amodra@bigpond.net.au>
> On Tue, Jul 16, 2002 at 10:48:14AM -0700, Geoff Keating wrote:
> > The profiling function isn't allowed to clobber r30. It never has
> > been, so this should be no surprise.
>
> I'm not quite sure what to make of this response. We're talking about
> this code from rs6000.c:10479
>
> if (current_function_needs_context)
> asm_fprintf (file, "\tmr %s,%s\n",
> reg_names[30], reg_names[STATIC_CHAIN_REGNUM]);
> fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
> if (current_function_needs_context)
> asm_fprintf (file, "\tmr %s,%s\n",
> reg_names[STATIC_CHAIN_REGNUM], reg_names[30]);
I see, I was confused. I thought we were already using r30 for
STATIC_CHAIN_REGNUM. The ABI specifies r31, but I see we can't use
that if we want trampolines to be efficient.
> This is currently emitted _before_ the prologue in the nested function,
> thus trashes r30. I was considering the idea of adding a clobber of
> r30 to CALL_INSN_FUNCTION_USAGE when calling a nested function. That's
> a workable solution, but means you need to zap r30 on all calls via
> function pointers too.
From David's mail message when he put the code in:
I have ripped out all of the stack PUSH/POP stuff that was
causing ABI problems and replaced it with explicit moves to a
temporary register. This includes having the SVR4 ABI act more
like AIX using a register instead of the dangerous stack
save/restore game. I could not test the SVR4 changes, so I would
appreciate if the LinuxPPC testers would make sure that I have
not broken anything when profiling is enabled.
So, thanks for testing it! We now know this doesn't work. :-)
So, why don't we go back to the push/pop implementation, but this time
do it properly? We'd only need to push/pop in the (rare)
nested-function case.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-17 0:58 ` Geoff Keating
@ 2002-07-17 2:04 ` Alan Modra
2002-07-17 10:42 ` David Edelsohn
2002-07-17 12:10 ` Geoff Keating
2002-07-17 8:45 ` David Edelsohn
1 sibling, 2 replies; 875+ messages in thread
From: Alan Modra @ 2002-07-17 2:04 UTC (permalink / raw)
To: Geoff Keating; +Cc: d.mueller, gcc-gnats, gcc-patches, dje
On Wed, Jul 17, 2002 at 12:07:11AM -0700, Geoff Keating wrote:
> So, why don't we go back to the push/pop implementation, but this time
> do it properly? We'd only need to push/pop in the (rare)
> nested-function case.
I wasn't aware that powerpc used that scheme previously, and therefore
was worried that some mcount implementation might peek at the stack.
Here we go.
* config/rs6000/r6000.c (first_reg_to_save): Remove bogus
adjustments to first_reg for profiling case.
(output_function_profiler): Correct lr save slot for ABI_AIX_NODESC.
Disable profiling for 64 bit code on both ABI_V4 and ABI_AIX_NODESC.
Save static chain reg to sp + 12 on ABI_AIX_NODESC.
* config/rs6000/sysv4.h (ASM_OUTPUT_REG_PUSH): Define.
(ASM_OUTPUT_REG_POP): Define.
* config/rs6000/linux64.h (ASM_OUTPUT_REG_PUSH): Undef.
(ASM_OUTPUT_REG_POP): Undef.
Rationale:
* config/rs6000/r6000.c (first_reg_to_save): Remove bogus
adjustments to first_reg for profiling case.
first_reg_to_save doesn't need to do anything special for any of these
registers as profiling is done via PROFILE_HOOK when ABI_AIX or
ABI_DARWIN. The normal register allocation code will set up
regs_ever_live for us. We're also not trying to use a reg when ABI_V4.
(output_function_profiler): Correct lr save slot for ABI_AIX_NODESC.
ABI_AIX_NODESC saves lr to sp + 8. This change is perhaps a little
contentious as existing mcount implementations may take into account
the current ABI breakage.
Disable profiling for 64 bit code on both ABI_V4 and ABI_AIX_NODESC.
The instructions emitted here are 32 bit ones. Fix this with a later
patch.
Save static chain reg to sp + 12 on ABI_AIX_NODESC.
We need to save it somewhere. This seems a likely spot.
* config/rs6000/sysv4.h (ASM_OUTPUT_REG_PUSH): Define.
(ASM_OUTPUT_REG_POP): Define.
Code resurrected from prior to Mon Mar 15 22:45:25 1999 delta, but
with DEFAULT_ABI == ABI_V4 test added.
powerpc-linux bootstrap on mainline seems to be broken at the moment.
internal compiler error: Internal compiler error
in tree_low_cst, at tree.c:3312
so I'm in the process of bootstrapping this one on the 3.1 branch.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.344
diff -u -p -r1.344 rs6000.c
--- gcc/config/rs6000/rs6000.c 16 Jul 2002 20:59:03 -0000 1.344
+++ gcc/config/rs6000/rs6000.c 17 Jul 2002 08:19:35 -0000
@@ -7356,53 +7356,6 @@ first_reg_to_save ()
|| (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
break;
- if (current_function_profile)
- {
- /* AIX must save/restore every register that contains a parameter
- before/after the .__mcount call plus an additional register
- for the static chain, if needed; use registers from 30 down to 22
- to do this. */
- if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
- {
- int last_parm_reg, profile_first_reg;
-
- /* Figure out last used parameter register. The proper thing
- to do is to walk incoming args of the function. A function
- might have live parameter registers even if it has no
- incoming args. */
- for (last_parm_reg = 10;
- last_parm_reg > 2 && ! regs_ever_live [last_parm_reg];
- last_parm_reg--)
- ;
-
- /* Calculate first reg for saving parameter registers
- and static chain.
- Skip reg 31 which may contain the frame pointer. */
- profile_first_reg = (33 - last_parm_reg
- - (current_function_needs_context ? 1 : 0));
-#if TARGET_MACHO
- /* Need to skip another reg to account for R31 being PICBASE
- (when flag_pic is set) or R30 being used as the frame
- pointer (when flag_pic is not set). */
- --profile_first_reg;
-#endif
- /* Do not save frame pointer if no parameters needs to be saved. */
- if (profile_first_reg == 31)
- profile_first_reg = 32;
-
- if (first_reg > profile_first_reg)
- first_reg = profile_first_reg;
- }
-
- /* SVR4 may need one register to preserve the static chain. */
- else if (current_function_needs_context)
- {
- /* Skip reg 31 which may contain the frame pointer. */
- if (first_reg > 30)
- first_reg = 30;
- }
- }
-
#if TARGET_MACHO
if (flag_pic && current_function_uses_pic_offset_table &&
(first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM))
@@ -10429,6 +10382,7 @@ output_function_profiler (file, labelno)
int labelno;
{
char buf[100];
+ int save_lr = 8;
ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
switch (DEFAULT_ABI)
@@ -10437,13 +10391,21 @@ output_function_profiler (file, labelno)
abort ();
case ABI_V4:
+ save_lr = 4;
+ /* Fall through. */
+
case ABI_AIX_NODESC:
+ if (!TARGET_32BIT)
+ {
+ warning ("no profiling of 64-bit code for this ABI");
+ return;
+ }
fprintf (file, "\tmflr %s\n", reg_names[0]);
if (flag_pic == 1)
{
fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
- asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
- reg_names[0], reg_names[1]);
+ asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
+ reg_names[0], save_lr, reg_names[1]);
asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
assemble_name (file, buf);
@@ -10451,8 +10413,8 @@ output_function_profiler (file, labelno)
}
else if (flag_pic > 1)
{
- asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
- reg_names[0], reg_names[1]);
+ asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
+ reg_names[0], save_lr, reg_names[1]);
/* Now, we need to get the address of the label. */
fputs ("\tbl 1f\n\t.long ", file);
assemble_name (file, buf);
@@ -10468,27 +10430,32 @@ output_function_profiler (file, labelno)
asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
assemble_name (file, buf);
fputs ("@ha\n", file);
- asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
- reg_names[0], reg_names[1]);
+ asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
+ reg_names[0], save_lr, reg_names[1]);
asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
assemble_name (file, buf);
asm_fprintf (file, "@l(%s)\n", reg_names[12]);
}
- if (current_function_needs_context)
- asm_fprintf (file, "\tmr %s,%s\n",
- reg_names[30], reg_names[STATIC_CHAIN_REGNUM]);
- fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
- if (current_function_needs_context)
- asm_fprintf (file, "\tmr %s,%s\n",
- reg_names[STATIC_CHAIN_REGNUM], reg_names[30]);
+ if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC)
+ {
+ asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
+ reg_names[STATIC_CHAIN_REGNUM],
+ 12, reg_names[1]);
+ fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
+ asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n",
+ reg_names[STATIC_CHAIN_REGNUM],
+ 12, reg_names[1]);
+ }
+ else
+ /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
+ fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
break;
case ABI_AIX:
case ABI_DARWIN:
/* Don't do anything, done in output_profile_hook (). */
break;
-
}
}
Index: gcc/config/rs6000/sysv4.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.98
diff -u -p -r1.98 sysv4.h
--- gcc/config/rs6000/sysv4.h 10 Jul 2002 00:33:51 -0000 1.98
+++ gcc/config/rs6000/sysv4.h 17 Jul 2002 08:19:36 -0000
@@ -736,6 +736,38 @@ do { \
ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \
} while (0)
+/* This is how to output code to push a register on the stack.
+ It need not be very fast code.
+
+ On the rs6000, we must keep the backchain up to date. In order
+ to simplify things, always allocate 16 bytes for a push (System V
+ wants to keep stack aligned to a 16 byte boundary). */
+
+#define ASM_OUTPUT_REG_PUSH(FILE, REGNO) \
+do { \
+ if (DEFAULT_ABI == ABI_V4) \
+ asm_fprintf (FILE, \
+ (TARGET_32BIT \
+ ? "\t{stu|stwu} %s,-16(%s)\n\t{st|stw} %s,12(%s)\n" \
+ : "\tstdu %s,-32(%s)\n\tstd %s,24(%s)\n"), \
+ reg_names[1], reg_names[1], reg_names[REGNO], \
+ reg_names[1]); \
+} while (0)
+
+/* This is how to output an insn to pop a register from the stack.
+ It need not be very fast code. */
+
+#define ASM_OUTPUT_REG_POP(FILE, REGNO) \
+do { \
+ if (DEFAULT_ABI == ABI_V4) \
+ asm_fprintf (FILE, \
+ (TARGET_32BIT \
+ ? "\t{l|lwz} %s,12(%s)\n\t{ai|addic} %s,%s,16\n" \
+ : "\tld %s,24(%s)\n\t{ai|addic} %s,%s,32\n"), \
+ reg_names[REGNO], reg_names[1], reg_names[1], \
+ reg_names[1]); \
+} while (0)
+
/* Switch Recognition by gcc.c. Add -G xx support. */
/* Override svr4.h definition. */
Index: gcc/config/rs6000/linux64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux64.h,v
retrieving revision 1.21
diff -u -p -r1.21 linux64.h
--- gcc/config/rs6000/linux64.h 11 Jul 2002 00:23:16 -0000 1.21
+++ gcc/config/rs6000/linux64.h 17 Jul 2002 08:19:25 -0000
@@ -329,3 +329,7 @@ do \
sym_lineno += 1; \
} \
while (0)
+
+/* Override sysv4.h as these are ABI_V4 only. */
+#undef ASM_OUTPUT_REG_PUSH
+#undef ASM_OUTPUT_REG_POP
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-17 0:58 ` Geoff Keating
2002-07-17 2:04 ` Alan Modra
@ 2002-07-17 8:45 ` David Edelsohn
2002-07-17 12:26 ` Geoff Keating
1 sibling, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-07-17 8:45 UTC (permalink / raw)
To: Geoff Keating; +Cc: amodra, d.mueller, gcc-gnats, gcc-patches
>>>>> Geoff Keating writes:
Geoff> So, thanks for testing it! We now know this doesn't work. :-)
The patch was tested on SVR4 by Franz and showed no new failures:
http://gcc.gnu.org/ml/gcc-patches/1999-03n/msg00584.html
PUSH/POP cannot work on PowerPC. On AIX PUSH/POP were corrupting the
stack.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-17 2:04 ` Alan Modra
@ 2002-07-17 10:42 ` David Edelsohn
2002-07-17 12:10 ` Geoff Keating
1 sibling, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-07-17 10:42 UTC (permalink / raw)
To: Alan Modra; +Cc: Geoff Keating, d.mueller, gcc-gnats, gcc-patches
If you want to define PUSH/POP for sysv4.h, that's fine. I would
recommend removing the !TARGET_32BIT case for those macros and only using
the PowerPC mnemonics, to simplify things.
> * config/rs6000/r6000.c (first_reg_to_save): Remove bogus
> adjustments to first_reg for profiling case.
> first_reg_to_save doesn't need to do anything special for any of these
> registers as profiling is done via PROFILE_HOOK when ABI_AIX or
> ABI_DARWIN. The normal register allocation code will set up
> regs_ever_live for us. We're also not trying to use a reg when ABI_V4.
I guess this works now because of the scheduled prologue.
I think this is okay, once the trunk can bootstrap again and the
patch can be tested there. Joern has a patch which fixes the regrename.c
bug he introduced
http://gcc.gnu.org/ml/gcc-patches/2002-07/msg00840.html
but no one with global write privileges has approved it.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-17 2:04 ` Alan Modra
2002-07-17 10:42 ` David Edelsohn
@ 2002-07-17 12:10 ` Geoff Keating
1 sibling, 0 replies; 875+ messages in thread
From: Geoff Keating @ 2002-07-17 12:10 UTC (permalink / raw)
To: amodra; +Cc: d.mueller, gcc-gnats, gcc-patches, dje
> Date: Wed, 17 Jul 2002 18:30:49 +0930
> From: Alan Modra <amodra@bigpond.net.au>
> Cc: d.mueller@elsoft.ch, gcc-gnats@gcc.gnu.org, gcc-patches@gcc.gnu.org,
> dje@watson.ibm.com
> On Wed, Jul 17, 2002 at 12:07:11AM -0700, Geoff Keating wrote:
> > So, why don't we go back to the push/pop implementation, but this time
> > do it properly? We'd only need to push/pop in the (rare)
> > nested-function case.
>
> I wasn't aware that powerpc used that scheme previously, and therefore
> was worried that some mcount implementation might peek at the stack.
>
> Here we go.
>
> * config/rs6000/r6000.c (first_reg_to_save): Remove bogus
> adjustments to first_reg for profiling case.
> (output_function_profiler): Correct lr save slot for ABI_AIX_NODESC.
> Disable profiling for 64 bit code on both ABI_V4 and ABI_AIX_NODESC.
> Save static chain reg to sp + 12 on ABI_AIX_NODESC.
> * config/rs6000/sysv4.h (ASM_OUTPUT_REG_PUSH): Define.
> (ASM_OUTPUT_REG_POP): Define.
> * config/rs6000/linux64.h (ASM_OUTPUT_REG_PUSH): Undef.
> (ASM_OUTPUT_REG_POP): Undef.
This is OK. I'm pretty sure it's right, and completely sure it's no
worse than before. :-)
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-17 8:45 ` David Edelsohn
@ 2002-07-17 12:26 ` Geoff Keating
2002-07-17 14:05 ` David Edelsohn
2002-07-17 19:20 ` Alan Modra
0 siblings, 2 replies; 875+ messages in thread
From: Geoff Keating @ 2002-07-17 12:26 UTC (permalink / raw)
To: dje; +Cc: amodra, d.mueller, gcc-gnats, gcc-patches
> cc: amodra@bigpond.net.au, d.mueller@elsoft.ch, gcc-gnats@gcc.gnu.org,
> gcc-patches@gcc.gnu.org
> Date: Wed, 17 Jul 2002 11:42:02 -0400
> From: David Edelsohn <dje@watson.ibm.com>
>
> >>>>> Geoff Keating writes:
>
> Geoff> So, thanks for testing it! We now know this doesn't work. :-)
>
> The patch was tested on SVR4 by Franz and showed no new failures:
>
> http://gcc.gnu.org/ml/gcc-patches/1999-03n/msg00584.html
The testsuite probably doesn't check that r30 is not clobbered in a
nested function when profiling is switched on. Actually, Alan, could
you write a test for that? (That's something I missed while reviewing
your patch.)
> PUSH/POP cannot work on PowerPC. On AIX PUSH/POP were corrupting the
> stack.
Because they were implemented wrongly?
Clearly, push/pop can work, because procedures push and pop call
frames all the time. It's just necessary to do it the right way.
For AIX, of course, push/pop is unnecessary, and Alan's patch didn't
add it.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-17 12:26 ` Geoff Keating
@ 2002-07-17 14:05 ` David Edelsohn
2002-07-17 19:20 ` Alan Modra
1 sibling, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-07-17 14:05 UTC (permalink / raw)
To: Geoff Keating; +Cc: amodra, d.mueller, gcc-gnats, gcc-patches
>>>>> Geoff Keating writes:
>> PUSH/POP cannot work on PowerPC. On AIX PUSH/POP were corrupting the
>> stack.
Geoff> Because they were implemented wrongly?
Geoff> Clearly, push/pop can work, because procedures push and pop call
Geoff> frames all the time. It's just necessary to do it the right way.
We are discussing PUSH/POP in the context of the macros to save
and restore individual registers used when generating a profiler call in
final.c, so GCC's ability to correctly allocate call frames is irrelevant.
The discussion about the PUSH/POP macros in March 1999 provides
more background about the problem: the macros were not respecting the
ABI-defined location of dynamic allocation on the stack. PUSH/POP ideally
should work like alloca and open a hole in the stack frame at the alloca
location. The PUSH/POP macros modify the stack pointer without updating
the compiler's internal knowledge about the stack layout and assume that
the alloca area is adjacent to the top of the stack, so adjusting the
stack pointer will not have any bad consequences, e.g., if a function call
is invoked.
On AIX, things went haywire because the PUSH/POP macros only
copied the backchain pointer, not all of the ABI-specified area between
the backchain pointer and the alloca area. When GCC called the profiler
function, the call frame had random garbage in ABI-specified locations,
causing the application to run off the rails when an ABI stack location
was accessed in the called function. Copying the backchain *and* CR *and*
LR may be sufficient for the AIX case for this particular use.
Because SVR4 PowerPC invokes the profiler before the prologue and
has a slightly different stack layout, the simplistic definition of
PUSH/POP may work correctly.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-17 12:26 ` Geoff Keating
2002-07-17 14:05 ` David Edelsohn
@ 2002-07-17 19:20 ` Alan Modra
2002-07-17 19:45 ` David Edelsohn
2002-07-17 20:50 ` David Edelsohn
1 sibling, 2 replies; 875+ messages in thread
From: Alan Modra @ 2002-07-17 19:20 UTC (permalink / raw)
To: Geoff Keating; +Cc: dje, gcc-patches
On Wed, Jul 17, 2002 at 12:10:12PM -0700, Geoff Keating wrote:
> The testsuite probably doesn't check that r30 is not clobbered in a
> nested function when profiling is switched on. Actually, Alan, could
> you write a test for that?
Can we assume a profiling library is available?
Implements dje's suggestion re. !TARGET_32BIT
gcc/ChangeLog
* config/rs6000/sysv4.h (ASM_OUTPUT_REG_PUSH): Remove 64-bit support.
(ASM_OUTPUT_REG_POP): Likewise.
gcc/testsuite/ChangeLog
* gcc.dg/nest.c: New.
Rather embarrassingly, this new testcase fails with a segfault on
powerpc64-linux, both before and after my change to the profiling
code. So I have another bug to look into..
--
Alan Modra
IBM OzLabs - Linux Technology Centre
Index: gcc/config/rs6000/sysv4.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.99
diff -u -p -r1.99 sysv4.h
--- gcc/config/rs6000/sysv4.h 18 Jul 2002 00:15:31 -0000 1.99
+++ gcc/config/rs6000/sysv4.h 18 Jul 2002 00:45:01 -0000
@@ -747,9 +747,7 @@ do { \
do { \
if (DEFAULT_ABI == ABI_V4) \
asm_fprintf (FILE, \
- (TARGET_32BIT \
- ? "\t{stu|stwu} %s,-16(%s)\n\t{st|stw} %s,12(%s)\n" \
- : "\tstdu %s,-32(%s)\n\tstd %s,24(%s)\n"), \
+ "\t{stu|stwu} %s,-16(%s)\n\t{st|stw} %s,12(%s)\n", \
reg_names[1], reg_names[1], reg_names[REGNO], \
reg_names[1]); \
} while (0)
@@ -761,9 +759,7 @@ do { \
do { \
if (DEFAULT_ABI == ABI_V4) \
asm_fprintf (FILE, \
- (TARGET_32BIT \
- ? "\t{l|lwz} %s,12(%s)\n\t{ai|addic} %s,%s,16\n" \
- : "\tld %s,24(%s)\n\t{ai|addic} %s,%s,32\n"), \
+ "\t{l|lwz} %s,12(%s)\n\t{ai|addic} %s,%s,16\n", \
reg_names[REGNO], reg_names[1], reg_names[1], \
reg_names[1]); \
} while (0)
Index: gcc/testsuite/gcc.dg/nest.c
===================================================================
RCS file: gcc/testsuite/gcc.dg/nest.c
diff -N gcc/testsuite/gcc.dg/nest.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/nest.c 18 Jul 2002 00:45:10 -0000
@@ -0,0 +1,21 @@
+/* PR 5967, PR 7114 */
+/* { dg-do run } */
+/* { dg-options "-O2 -pg" } */
+
+long foo (long x)
+{
+ long i, sum = 0;
+ long bar (long z) { return z * 2; }
+
+ for (i = 0; i < x; i++)
+ sum += bar (i);
+
+ return sum;
+}
+
+int main (void)
+{
+ if (foo(10) != 90)
+ abort ();
+ return 0;
+}
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-17 19:20 ` Alan Modra
@ 2002-07-17 19:45 ` David Edelsohn
2002-07-17 20:50 ` David Edelsohn
1 sibling, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-07-17 19:45 UTC (permalink / raw)
To: Alan Modra; +Cc: Geoff Keating, gcc-patches
* config/rs6000/sysv4.h (ASM_OUTPUT_REG_PUSH): Remove 64-bit support.
(ASM_OUTPUT_REG_POP): Likewise.
This is fine. You probably should change the {l|lwz} to just lwz, etc.
because those macros only target PowerPC mnemonics.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-17 19:20 ` Alan Modra
2002-07-17 19:45 ` David Edelsohn
@ 2002-07-17 20:50 ` David Edelsohn
2002-07-17 20:52 ` Alan Modra
1 sibling, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-07-17 20:50 UTC (permalink / raw)
To: Alan Modra; +Cc: Geoff Keating, gcc-patches
The nest.c testcase does not fail on AIX -- neither 32-bit mode
nor 64-bit mode. I thought that user mode linux64 basically used the same
profiling definitions as AIX, so I am surprised that I do not see the same
failure. Note that I have not installed your patch changing
first_reg_to_save.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: other/7114: ICE building strcoll.op from glibc-2.2.5
2002-07-17 20:50 ` David Edelsohn
@ 2002-07-17 20:52 ` Alan Modra
0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2002-07-17 20:52 UTC (permalink / raw)
To: David Edelsohn; +Cc: Geoff Keating, gcc-patches
On Wed, Jul 17, 2002 at 10:45:17PM -0400, David Edelsohn wrote:
> I thought that user mode linux64 basically used the same
> profiling definitions as AIX, so I am surprised that I do not see the same
> failure.
It's bombing inside glibc. Not a gcc problem.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* [PATCH] Re: thread-local storage: c front end and generic backend patch
2002-07-11 11:02 ` Richard Henderson
@ 2002-07-26 11:08 ` David Edelsohn
2002-07-27 15:40 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-07-26 11:08 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches
>>>>> Richard Henderson writes:
> Hmm. Ok. I can see why I made the change -- COMMON does not
> make sense without PUBLIC. I'll adjust assemble_variable and
> its subroutines to compensate.
I think this actually stems from the question of what DECL_COMMON
means. tree.h says:
/* Nonzero for a given ..._DECL node means that this node should be
put in .common, if possible. If a DECL_INITIAL is given, and it
is not error_mark_node, then the decl cannot be put in .common. */
#define DECL_COMMON(NODE) (DECL_CHECK (NODE)->decl.common_flag)
Is ".common" all common or only global common?
The change to c-decl.c testing TREE_PUBLIC implies that
DECL_COMMON only means global common. This means that GCC has no way to
mark a decl as local common, other than uninitialized and not public.
And, currently, GCC only *emits* local common if the the target also
supports ASM_OUTPUT_BSS.
There is no connection between a target supporting local common
and supporting BSS, so the logic has been confused somewhere.
Two apparent solutions are:
1) Either DECL_COMMON should mean any common, in which case it should not
depend on TREE_PUBLIC(decl) and c-decl should be fixed.
2) Or, DECL_COMMON only means global common, in which case
varasm.c:assemble_variable() should test ASM_EMIT_BSS and, if not defined,
avoid invoking asm_emit_uninitialized() for the *one* case it is required:
uninitialized, public symbol that is not common.
I have implemented option 2 above and submit it for review. As I
say in the comment, it seems that it would be cleaner to localize the test
to asm_emit_uninitialized and return failure instead of spreading the test
across two functions and aborting if called the wrong way.
David
* varasm.c (assemble_variable): Narrow test for uninitialized
without BSS target support.
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.296
diff -c -p -r1.296 varasm.c
*** varasm.c 26 Jun 2002 15:16:01 -0000 1.296
--- varasm.c 26 Jul 2002 16:47:51 -0000
*************** assemble_variable (decl, top_level, at_e
*** 1598,1604 ****
in .bss, then we have to use .data. */
/* ??? We should handle .bss via select_section mechanisms rather than
via special target hooks. That would eliminate this special case. */
! else if (!DECL_COMMON (decl))
;
#endif
else if (DECL_INITIAL (decl) == 0
--- 1598,1606 ----
in .bss, then we have to use .data. */
/* ??? We should handle .bss via select_section mechanisms rather than
via special target hooks. That would eliminate this special case. */
! /* Duplicate BSS test in asm_emit_uninitialized instead of having it
! return success or failure for that case. Shrug. */
! else if (TREE_PUBLIC (decl) && !DECL_COMMON (decl))
;
#endif
else if (DECL_INITIAL (decl) == 0
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] Re: thread-local storage: c front end and generic backend patch
2002-07-26 11:08 ` [PATCH] " David Edelsohn
@ 2002-07-27 15:40 ` Richard Henderson
2002-07-27 16:18 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-07-27 15:40 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
On Fri, Jul 26, 2002 at 01:16:03PM -0400, David Edelsohn wrote:
> I think this actually stems from the question of what DECL_COMMON means.
I think of it in terms of the ELF STT_COMMON defintion, which is
the same as that which a.out used.
> Is ".common" all common or only global common?
Only global, I'd say. Local common doesn't make any sense when
you think of the linker semantics.
> There is no connection between a target supporting local common
> and supporting BSS, so the logic has been confused somewhere.
Local common _is_ BSS. Perhaps the target doesn't support changing
to a section via .bss and emitting symbols, but that's the effect
of e.g. the .lcomm directive.
> * varasm.c (assemble_variable): Narrow test for uninitialized
> without BSS target support.
This is about what I had in mind.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] Re: thread-local storage: c front end and generic backend patch
2002-07-27 15:40 ` Richard Henderson
@ 2002-07-27 16:18 ` David Edelsohn
2002-07-29 11:02 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-07-27 16:18 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches
I think of data, common, bss, weak, etc. mapping into the
following, basic characteristics:
1) Initialized Data (data section) versus Uninitialized Data (bss
section, blank static storage initialized with zeros).
2) Global scope versus Local scope.
3) Multiple symbol definitions merged (common) or error (no-common).
Common specifies global, uninitialized data which is merged with
other definitions of the same global symbol by the linker. Local common
specifies local, uninitialized data which is merged with other definitions
of the same local symbol by the *assembler*. If a data section global
symbol definition does not override a common symbol, the common symbol is
instantiated in the BSS section.
Explicitly defining a BSS symbol specifies global, uninitialized
data which *cannot* be merged and is an error if a duplicate definition of
the global symbol appears in another module. In other words, BSS but not
COMMON.
ASM_OUTPUT_COMMON generates an uninitialized, global, common-label
name. ASM_OUTPUT_LOCAL generates an uninitialized, local, common-label
name. ASM_OUTPUT_BSS generates an uninitialized, global name.
David> Is ".common" all common or only global common?
Richard> Only global, I'd say. Local common doesn't make any sense when
Richard> you think of the linker semantics.
Right, because it's assembler semantics, not linker semantics.
Richard> Local common _is_ BSS. Perhaps the target doesn't support changing
Richard> to a section via .bss and emitting symbols, but that's the effect
Richard> of e.g. the .lcomm directive.
Well, sort of. Local common is allocated in the BSS section, but
it's scope is local, while a BSS symbol can have global scope. And local
common symbols can be merged by the assembler, while pure BSS symbols
cannot have duplicates.
What I meant by no connection between local common and BSS is that
there is no connection between an assembler/linker allowing GCC to emit
unique BSS symbol definitions which cannot be merged (using
ASM_OUTPUT_BSS) and allowing uninitialized data through local common.
The current logic in varasm.c means that if the target does not
support directly emitting a BSS global symbol, then it does not support
local common either and no uninitialized local data is generated.
If you want GCC DECL_COMMON to mean linker-only common, fine.
David> * varasm.c (assemble_variable): Narrow test for uninitialized
David> without BSS target support.
Richard> This is about what I had in mind.
Any additional change you want me to make, such as localizing this
logic in asm_emit_uninitialized, or can I commit the patch as posted?
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] Re: thread-local storage: c front end and generic backend patch
2002-07-27 16:18 ` David Edelsohn
@ 2002-07-29 11:02 ` Richard Henderson
2002-07-29 11:36 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-07-29 11:02 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
On Sat, Jul 27, 2002 at 06:40:28PM -0400, David Edelsohn wrote:
> Local common specifies local, uninitialized data which is merged
> with other definitions of the same local symbol by the *assembler*.
I suppose, yes, but gcc has no need for such a feature. We will
never emit duplicates of the same local symbol for the assembler
to merge.
> Any additional change you want me to make, such as localizing this
> logic in asm_emit_uninitialized, or can I commit the patch as posted?
Well, you can't really localize the change any more since the
change to assemble_variable is require in order for
asm_emit_uninitialized to be called.
So, the patch is ok as-is.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] Re: thread-local storage: c front end and generic backend patch
2002-07-29 11:02 ` Richard Henderson
@ 2002-07-29 11:36 ` David Edelsohn
2002-07-29 15:30 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-07-29 11:36 UTC (permalink / raw)
To: gcc-patches
>>>>> Richard Henderson writes:
>> Any additional change you want me to make, such as localizing this
>> logic in asm_emit_uninitialized, or can I commit the patch as posted?
Richard> Well, you can't really localize the change any more since the
Richard> change to assemble_variable is require in order for
Richard> asm_emit_uninitialized to be called.
Richard> So, the patch is ok as-is.
Okay.
Just for clarity, what I suggested is for asm_emit_uninitialized()
to return success or failure instead of assemble_variable() avoiding the
function for cases it cannot handle. The code currently is
if ()
...
#ifndef ASM_EMIT_BSS
else if (! DECL_COMMON)
; /* skip next test */
#endif
else if (BSS)
{
asm_emit_uninitialized();
return;
}
/* initialized variables and no defined BSS */
It could be reworked as
if ()
...
else if (BSS)
{
if (asm_emit_uninitialized())
return;
}
where asm_emit_uninitialized() returns FALSE for decls requiring
ASM_EMIT_BSS if that macro is undefined.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] Re: thread-local storage: c front end and generic backend patch
2002-07-29 11:36 ` David Edelsohn
@ 2002-07-29 15:30 ` Richard Henderson
2002-07-29 22:10 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-07-29 15:30 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
On Mon, Jul 29, 2002 at 02:09:35PM -0400, David Edelsohn wrote:
> It could be reworked as
>
> if ()
> ...
> else if (BSS)
> {
> if (asm_emit_uninitialized())
> return;
> }
>
> where asm_emit_uninitialized() returns FALSE for decls requiring
> ASM_EMIT_BSS if that macro is undefined.
Oh, I see. Yes, that would be cleaner. If you'd like to
work on that, I'd be grateful.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] Re: thread-local storage: c front end and generic backend patch
2002-07-29 15:30 ` Richard Henderson
@ 2002-07-29 22:10 ` David Edelsohn
2002-07-30 9:41 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-07-29 22:10 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches
>>>>> Richard Henderson writes:
Richard> Oh, I see. Yes, that would be cleaner. If you'd like to
Richard> work on that, I'd be grateful.
* varasm.c (asm_emit_uninitialized): Return false if global BSS
and ASM_EMIT_BSS not supported by target.
(assemble_variable): Do not duplicate uninitialized logic.
Fall through if asm_emit_uninitialized failed.
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.297
diff -c -p -r1.297 varasm.c
*** varasm.c 29 Jul 2002 19:01:55 -0000 1.297
--- varasm.c 30 Jul 2002 04:54:39 -0000
*************** static void asm_output_aligned_bss PARAM
*** 172,178 ****
#endif /* BSS_SECTION_ASM_OP */
static hashval_t const_str_htab_hash PARAMS ((const void *x));
static int const_str_htab_eq PARAMS ((const void *x, const void *y));
! static void asm_emit_uninitialised PARAMS ((tree, const char*, int, int));
static void resolve_unique_section PARAMS ((tree, int, int));
static void mark_weak PARAMS ((tree));
\f
--- 172,178 ----
#endif /* BSS_SECTION_ASM_OP */
static hashval_t const_str_htab_hash PARAMS ((const void *x));
static int const_str_htab_eq PARAMS ((const void *x, const void *y));
! static bool asm_emit_uninitialised PARAMS ((tree, const char*, int, int));
static void resolve_unique_section PARAMS ((tree, int, int));
static void mark_weak PARAMS ((tree));
\f
*************** assemble_string (p, size)
*** 1350,1356 ****
#endif
#endif
! static void
asm_emit_uninitialised (decl, name, size, rounded)
tree decl;
const char *name;
--- 1350,1356 ----
#endif
#endif
! static bool
asm_emit_uninitialised (decl, name, size, rounded)
tree decl;
const char *name;
*************** asm_emit_uninitialised (decl, name, size
*** 1365,1377 ****
}
destination = asm_dest_local;
if (TREE_PUBLIC (decl))
{
! #if defined ASM_EMIT_BSS
! if (! DECL_COMMON (decl))
destination = asm_dest_bss;
! else
#endif
destination = asm_dest_common;
}
--- 1365,1381 ----
}
destination = asm_dest_local;
+ /* ??? We should handle .bss via select_section mechanisms rather than
+ via special target hooks. That would eliminate this special case. */
if (TREE_PUBLIC (decl))
{
! if (!DECL_COMMON (decl))
! #ifdef ASM_EMIT_BSS
destination = asm_dest_bss;
! #else
! return false;
#endif
+ else
destination = asm_dest_common;
}
*************** asm_emit_uninitialised (decl, name, size
*** 1420,1426 ****
abort ();
}
! return;
}
/* Assemble everything that is needed for a variable or function declaration.
--- 1424,1430 ----
abort ();
}
! return true;
}
/* Assemble everything that is needed for a variable or function declaration.
*************** assemble_variable (decl, top_level, at_e
*** 1593,1608 ****
if (DECL_COMMON (decl))
sorry ("thread-local COMMON data not implemented");
}
- #ifndef ASM_EMIT_BSS
- /* If the target can't output uninitialized but not common global data
- in .bss, then we have to use .data. */
- /* ??? We should handle .bss via select_section mechanisms rather than
- via special target hooks. That would eliminate this special case. */
- /* Duplicate BSS test in asm_emit_uninitialized instead of having it
- return success or failure for that case. Shrug. */
- else if (TREE_PUBLIC (decl) && !DECL_COMMON (decl))
- ;
- #endif
else if (DECL_INITIAL (decl) == 0
|| DECL_INITIAL (decl) == error_mark_node
|| (flag_zero_initialized_in_bss
--- 1597,1602 ----
*************** assemble_variable (decl, top_level, at_e
*** 1629,1637 ****
(decl, "requested alignment for %s is greater than implemented alignment of %d",rounded);
#endif
! asm_emit_uninitialised (decl, name, size, rounded);
!
! return;
}
/* Handle initialized definitions.
--- 1623,1632 ----
(decl, "requested alignment for %s is greater than implemented alignment of %d",rounded);
#endif
! /* If the target cannot output uninitialized but not common global data
! in .bss, then we have to use .data, so fall through. */
! if (asm_emit_uninitialised (decl, name, size, rounded))
! return;
}
/* Handle initialized definitions.
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] Re: thread-local storage: c front end and generic backend patch
2002-07-29 22:10 ` David Edelsohn
@ 2002-07-30 9:41 ` Richard Henderson
0 siblings, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-07-30 9:41 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
On Tue, Jul 30, 2002 at 01:04:06AM -0400, David Edelsohn wrote:
> * varasm.c (asm_emit_uninitialized): Return false if global BSS
> and ASM_EMIT_BSS not supported by target.
> (assemble_variable): Do not duplicate uninitialized logic.
> Fall through if asm_emit_uninitialized failed.
Ok.
Thanks for cleaning this up.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* power4 branch hints
@ 2002-08-01 18:39 Alan Modra
2002-08-01 18:47 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-08-01 18:39 UTC (permalink / raw)
To: gcc-patches; +Cc: David Edelsohn
See the comment below.
* config/rs6000/rs6000.c (output_cbranch): Hint differently for power4.
* config/rs6000/rs6000.h (enum processor_type): Comment on ordering.
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.355
diff -u -p -r1.355 rs6000.c
--- gcc/config/rs6000/rs6000.c 2 Aug 2002 01:08:01 -0000 1.355
+++ gcc/config/rs6000/rs6000.c 2 Aug 2002 01:21:55 -0000
@@ -8438,21 +8438,30 @@ output_cbranch (op, label, reversed, ins
/* Maybe we have a guess as to how likely the branch is.
The old mnemonics don't have a way to specify this information. */
+ pred = "";
note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
if (note != NULL_RTX)
{
/* PROB is the difference from 50%. */
int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
-
- /* For branches that are very close to 50%, assume not-taken. */
- if (abs (prob) > REG_BR_PROB_BASE / 20
- && ((prob > 0) ^ need_longbranch))
- pred = "+";
- else
- pred = "-";
+ int cpu_version1_arch = rs6000_cpu < PROCESSOR_POWER4;
+
+ /* Only hint for highly probable/improbable branches on newer
+ cpus as static prediction overrides processor dynamic
+ prediction. For older cpus we may as well always hint, but
+ assume not taken for branches that are very close to 50% as a
+ mispredicted taken branch is more expensive than a
+ mispredicted not-taken branch. */
+ if (cpu_version1_arch
+ || abs (prob) > REG_BR_PROB_BASE / 100 * 48)
+ {
+ if (abs (prob) > REG_BR_PROB_BASE / 20
+ && ((prob > 0) ^ need_longbranch))
+ pred = "+";
+ else
+ pred = "-";
+ }
}
- else
- pred = "";
if (label == NULL)
s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
Index: gcc/config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.217
diff -u -p -r1.217 rs6000.h
--- gcc/config/rs6000/rs6000.h 1 Aug 2002 21:18:34 -0000 1.217
+++ gcc/config/rs6000/rs6000.h 2 Aug 2002 01:22:00 -0000
@@ -341,7 +341,10 @@ extern int target_flags;
/* This is meant to be redefined in the host dependent files */
#define SUBTARGET_SWITCHES
-/* Processor type. Order must match cpu attribute in MD file. */
+/* Processor type. Order must match cpu attribute in MD file.
+ Please keep all Power4 type processors using "at" branch hints
+ after PROCESSOR_POWER4, and those using the "y" branch hints,
+ before. */
enum processor_type
{
PROCESSOR_RIOS1,
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: power4 branch hints
2002-08-01 18:39 power4 branch hints Alan Modra
@ 2002-08-01 18:47 ` David Edelsohn
2002-08-01 19:50 ` Alan Modra
2002-08-02 13:25 ` Geoff Keating
0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2002-08-01 18:47 UTC (permalink / raw)
To: Alan Modra, Geoff Keating; +Cc: gcc-patches
+ int cpu_version1_arch = rs6000_cpu < PROCESSOR_POWER4;
I am extremely conflicted about having a fragile test like the one
above versus
int at_hints = (rs6000_cpu == PROCESSOR_POWER4)
which adds yet another place potentially requiring tweaking for new
processors.
Geoff, do you have any preferences?
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: power4 branch hints
2002-08-01 18:47 ` David Edelsohn
@ 2002-08-01 19:50 ` Alan Modra
2002-08-01 20:25 ` David Edelsohn
2002-08-02 13:25 ` Geoff Keating
1 sibling, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-08-01 19:50 UTC (permalink / raw)
To: gcc-patches; +Cc: Geoff Keating, David Edelsohn
On Thu, Aug 01, 2002 at 09:47:01PM -0400, David Edelsohn wrote:
> + int cpu_version1_arch = rs6000_cpu < PROCESSOR_POWER4;
>
> I am extremely conflicted about having a fragile test like the one
> above versus
OK, we came to agreement in private email. For the record, this is
what I'm committing.
* config/rs6000/rs6000.c (output_cbranch): Hint differently for power4.
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.355
diff -u -p -r1.355 rs6000.c
--- config/rs6000/rs6000.c 2 Aug 2002 01:08:01 -0000 1.355
+++ config/rs6000/rs6000.c 2 Aug 2002 02:46:19 -0000
@@ -8438,21 +8438,30 @@ output_cbranch (op, label, reversed, ins
/* Maybe we have a guess as to how likely the branch is.
The old mnemonics don't have a way to specify this information. */
+ pred = "";
note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
if (note != NULL_RTX)
{
/* PROB is the difference from 50%. */
int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
-
- /* For branches that are very close to 50%, assume not-taken. */
- if (abs (prob) > REG_BR_PROB_BASE / 20
- && ((prob > 0) ^ need_longbranch))
- pred = "+";
- else
- pred = "-";
+ bool always_hint = rs6000_cpu != PROCESSOR_POWER4;
+
+ /* Only hint for highly probable/improbable branches on newer
+ cpus as static prediction overrides processor dynamic
+ prediction. For older cpus we may as well always hint, but
+ assume not taken for branches that are very close to 50% as a
+ mispredicted taken branch is more expensive than a
+ mispredicted not-taken branch. */
+ if (always_hint
+ || abs (prob) > REG_BR_PROB_BASE / 100 * 48)
+ {
+ if (abs (prob) > REG_BR_PROB_BASE / 20
+ && ((prob > 0) ^ need_longbranch))
+ pred = "+";
+ else
+ pred = "-";
+ }
}
- else
- pred = "";
if (label == NULL)
s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: power4 branch hints
2002-08-01 19:50 ` Alan Modra
@ 2002-08-01 20:25 ` David Edelsohn
0 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-08-01 20:25 UTC (permalink / raw)
To: gcc-patches
* config/rs6000/rs6000.c (output_cbranch): Hint differently for power4.
Yes, this is fine.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: power4 branch hints
2002-08-01 18:47 ` David Edelsohn
2002-08-01 19:50 ` Alan Modra
@ 2002-08-02 13:25 ` Geoff Keating
1 sibling, 0 replies; 875+ messages in thread
From: Geoff Keating @ 2002-08-02 13:25 UTC (permalink / raw)
To: dje; +Cc: amodra, gcc-patches
> cc: gcc-patches@gcc.gnu.org
> Date: Thu, 01 Aug 2002 21:47:01 -0400
> From: David Edelsohn <dje@watson.ibm.com>
>
> + int cpu_version1_arch = rs6000_cpu < PROCESSOR_POWER4;
>
> I am extremely conflicted about having a fragile test like the one
> above versus
>
> int at_hints = (rs6000_cpu == PROCESSOR_POWER4)
>
> which adds yet another place potentially requiring tweaking for new
> processors.
>
> Geoff, do you have any preferences?
I think I slightly prefer the second, because the first one depends on
ordering of an enum.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* [RFC] PowerPC select_section / unique_section
@ 2002-08-21 11:09 David Edelsohn
2002-08-21 11:21 ` Franz Sirl
2002-08-21 18:54 ` Alan Modra
0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2002-08-21 11:09 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
While investigating a problem with PowerPC ELF section decisions,
I realized that the functions need to treat PPC64 as if flag_pic were set.
I also noticed a discrepancy between the PowerPC definition and the
default definition in varasm.c: rs6000_elf_select_section should not
default to readonly when reloc is defined.
My remaining concern is that the readonly algorithm in
rs6000_elf_unique_section does not match the algorithm in
rs6000_elf_select_section: the handling of decl CONSTRUCTOR and the
handling of default readonly. Should the definitions match?
Thanks, David
* config/rs6000/rs6000.c (rs6000_elf_select_section): Treat
DEFAULT_ABI == ABI_AIX like PIC. Test PIC & reloc for readonly
default.
(rs6000_elf_unique_section): Treat DEFAULT_ABI == ABI_AIX like
PIC.
(rs6000_xcoff_select_section): Update to recent readonly
algorithm.
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.364
diff -c -p -r1.364 rs6000.c
*** rs6000.c 19 Aug 2002 16:32:53 -0000 1.364
--- rs6000.c 21 Aug 2002 16:42:25 -0000
*************** rs6000_elf_select_section (decl, reloc,
*** 12432,12439 ****
unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
{
int size = int_size_in_bytes (TREE_TYPE (decl));
! int needs_sdata;
! int readonly;
static void (* const sec_funcs[4]) PARAMS ((void)) = {
&readonly_data_section,
&sdata2_section,
--- 12462,12469 ----
unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
{
int size = int_size_in_bytes (TREE_TYPE (decl));
! bool needs_sdata;
! bool readonly;
static void (* const sec_funcs[4]) PARAMS ((void)) = {
&readonly_data_section,
&sdata2_section,
*************** rs6000_elf_select_section (decl, reloc,
*** 12447,12468 ****
&& (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
if (TREE_CODE (decl) == STRING_CST)
! readonly = ! flag_writable_strings;
else if (TREE_CODE (decl) == VAR_DECL)
! readonly = (! (flag_pic && reloc)
&& TREE_READONLY (decl)
! && ! TREE_SIDE_EFFECTS (decl)
&& DECL_INITIAL (decl)
&& DECL_INITIAL (decl) != error_mark_node
&& TREE_CONSTANT (DECL_INITIAL (decl)));
else if (TREE_CODE (decl) == CONSTRUCTOR)
! readonly = (! (flag_pic && reloc)
! && ! TREE_SIDE_EFFECTS (decl)
&& TREE_CONSTANT (decl));
else
! readonly = 1;
if (needs_sdata && rs6000_sdata != SDATA_EABI)
! readonly = 0;
(*sec_funcs[(readonly ? 0 : 2) + (needs_sdata ? 1 : 0)])();
}
--- 12477,12499 ----
&& (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
if (TREE_CODE (decl) == STRING_CST)
! readonly = !flag_writable_strings;
else if (TREE_CODE (decl) == VAR_DECL)
! readonly = (!((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
&& TREE_READONLY (decl)
! && !TREE_SIDE_EFFECTS (decl)
&& DECL_INITIAL (decl)
&& DECL_INITIAL (decl) != error_mark_node
&& TREE_CONSTANT (DECL_INITIAL (decl)));
else if (TREE_CODE (decl) == CONSTRUCTOR)
! readonly = (!((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
! && !TREE_SIDE_EFFECTS (decl)
&& TREE_CONSTANT (decl));
else
! readonly = !((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc);
!
if (needs_sdata && rs6000_sdata != SDATA_EABI)
! readonly = false;
(*sec_funcs[(readonly ? 0 : 2) + (needs_sdata ? 1 : 0)])();
}
*************** rs6000_elf_unique_section (decl, reloc)
*** 12501,12517 ****
sec = 6;
else
{
! int readonly;
! int needs_sdata;
int size;
- readonly = 1;
if (TREE_CODE (decl) == STRING_CST)
! readonly = ! flag_writable_strings;
else if (TREE_CODE (decl) == VAR_DECL)
! readonly = (! (flag_pic && reloc)
&& TREE_READONLY (decl)
! && ! TREE_SIDE_EFFECTS (decl)
&& TREE_CONSTANT (DECL_INITIAL (decl)));
size = int_size_in_bytes (TREE_TYPE (decl));
--- 12532,12547 ----
sec = 6;
else
{
! bool readonly = true;
! bool needs_sdata;
int size;
if (TREE_CODE (decl) == STRING_CST)
! readonly = !flag_writable_strings;
else if (TREE_CODE (decl) == VAR_DECL)
! readonly = (!((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
&& TREE_READONLY (decl)
! && !TREE_SIDE_EFFECTS (decl)
&& TREE_CONSTANT (DECL_INITIAL (decl)));
size = int_size_in_bytes (TREE_TYPE (decl));
*************** rs6000_elf_unique_section (decl, reloc)
*** 12523,12529 ****
if (DECL_INITIAL (decl) == 0
|| DECL_INITIAL (decl) == error_mark_node)
sec = 4;
! else if (! readonly)
sec = 2;
else
sec = 0;
--- 12553,12559 ----
if (DECL_INITIAL (decl) == 0
|| DECL_INITIAL (decl) == error_mark_node)
sec = 4;
! else if (!readonly)
sec = 2;
else
sec = 0;
*************** xcoff_asm_named_section (name, flags)
*** 13104,13131 ****
}
static void
! rs6000_xcoff_select_section (exp, reloc, align)
! tree exp;
int reloc;
unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
{
! if ((TREE_CODE (exp) == STRING_CST
! && ! flag_writable_strings)
! || (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
! && TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp)
! && DECL_INITIAL (exp)
! && (DECL_INITIAL (exp) == error_mark_node
! || TREE_CONSTANT (DECL_INITIAL (exp)))
! && ! (reloc)))
{
! if (TREE_PUBLIC (exp))
read_only_data_section ();
else
read_only_private_data_section ();
}
else
{
! if (TREE_PUBLIC (exp))
data_section ();
else
private_data_section ();
--- 13134,13172 ----
}
static void
! rs6000_xcoff_select_section (decl, reloc, align)
! tree decl;
int reloc;
unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
{
! bool readonly = false;
!
! if (TREE_CODE (decl) == STRING_CST)
! readonly = !flag_writable_strings;
! else if (TREE_CODE (decl) == VAR_DECL)
! readonly = (!reloc
! && TREE_READONLY (decl)
! && !TREE_SIDE_EFFECTS (decl)
! && DECL_INITIAL (decl)
! && DECL_INITIAL (decl) != error_mark_node
! && TREE_CONSTANT (DECL_INITIAL (decl)));
! else if (TREE_CODE (decl) == CONSTRUCTOR)
! readonly = (!reloc
! && !TREE_SIDE_EFFECTS (decl)
! && TREE_CONSTANT (decl));
! else
! readonly = !reloc;
!
! if (readonly)
{
! if (TREE_PUBLIC (decl))
read_only_data_section ();
else
read_only_private_data_section ();
}
else
{
! if (TREE_PUBLIC (decl))
data_section ();
else
private_data_section ();
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-21 11:09 [RFC] PowerPC select_section / unique_section David Edelsohn
@ 2002-08-21 11:21 ` Franz Sirl
2002-08-21 11:29 ` David Edelsohn
2002-08-21 18:54 ` Alan Modra
1 sibling, 1 reply; 875+ messages in thread
From: Franz Sirl @ 2002-08-21 11:21 UTC (permalink / raw)
To: David Edelsohn, Geoff Keating; +Cc: gcc-patches
On Mittwoch, 21. August 2002 19:20, David Edelsohn wrote:
> While investigating a problem with PowerPC ELF section decisions,
> I realized that the functions need to treat PPC64 as if flag_pic were set.
> I also noticed a discrepancy between the PowerPC definition and the
> default definition in varasm.c: rs6000_elf_select_section should not
> default to readonly when reloc is defined.
>
> My remaining concern is that the readonly algorithm in
> rs6000_elf_unique_section does not match the algorithm in
> rs6000_elf_select_section: the handling of decl CONSTRUCTOR and the
> handling of default readonly. Should the definitions match?
See
<http://gcc.gnu.org/ml/gcc-patches/2002-05/subjects.html#01551>
for a patch I suggested to unify the handling and the followup discussion on
how to better re-use the stuff in varasm.c. I haven't come around to
implement this yet unfortunately (and it doesn't look like I will be able to
tackle this anytime soon).
Franz.
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-21 11:21 ` Franz Sirl
@ 2002-08-21 11:29 ` David Edelsohn
2002-08-21 12:01 ` Franz Sirl
2002-08-21 19:02 ` Alan Modra
0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2002-08-21 11:29 UTC (permalink / raw)
To: Franz Sirl; +Cc: Geoff Keating, gcc-patches
>>>>> Franz Sirl writes:
Franz> I suggested to unify the handling and the followup discussion on
Franz> how to better re-use the stuff in varasm.c. I haven't come around to
Franz> implement this yet unfortunately (and it doesn't look like I will be able to
Franz> tackle this anytime soon).
PowerPC cannot use the default functions in varasm.c because of
its assumptions (e.g., flag_pic). I already investigated that and I do
remember the earlier discussion.
My patch is not a cleanup, it's a correctness issue.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-21 11:29 ` David Edelsohn
@ 2002-08-21 12:01 ` Franz Sirl
2002-08-21 12:15 ` David Edelsohn
2002-08-21 19:02 ` Alan Modra
1 sibling, 1 reply; 875+ messages in thread
From: Franz Sirl @ 2002-08-21 12:01 UTC (permalink / raw)
To: David Edelsohn; +Cc: Geoff Keating, gcc-patches
On Mittwoch, 21. August 2002 20:25, David Edelsohn wrote:
> >>>>> Franz Sirl writes:
>
> Franz> I suggested to unify the handling and the followup discussion on
> Franz> how to better re-use the stuff in varasm.c. I haven't come around to
> Franz> implement this yet unfortunately (and it doesn't look like I will be
> able to Franz> tackle this anytime soon).
>
> PowerPC cannot use the default functions in varasm.c because of
> its assumptions (e.g., flag_pic). I already investigated that and I do
> remember the earlier discussion.
Well, we could save flag_pic around calling these functions or change the
flag_pic checks in varasm.c to a target hook.
> My patch is not a cleanup, it's a correctness issue.
I understand that, but I consider reusing as much as possible of the varasm
functions a longterm correctness issue.
Franz.
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-21 12:01 ` Franz Sirl
@ 2002-08-21 12:15 ` David Edelsohn
2002-08-29 18:01 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-08-21 12:15 UTC (permalink / raw)
To: Franz Sirl; +Cc: Geoff Keating, gcc-patches
>>>>> Franz Sirl writes:
Franz> Well, we could save flag_pic around calling these functions or change the
Franz> flag_pic checks in varasm.c to a target hook.
Yes, I considered setting and unsetting flag_pic, but that's
ugly. The only way I see to use the default functions is to add a "pic"
parameter to the functions instead of using the GCC flag_pic global.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-21 11:09 [RFC] PowerPC select_section / unique_section David Edelsohn
2002-08-21 11:21 ` Franz Sirl
@ 2002-08-21 18:54 ` Alan Modra
2002-08-21 18:59 ` David Edelsohn
1 sibling, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-08-21 18:54 UTC (permalink / raw)
To: David Edelsohn; +Cc: Geoff Keating, gcc-patches
On Wed, Aug 21, 2002 at 01:20:18PM -0400, David Edelsohn wrote:
> * config/rs6000/rs6000.c (rs6000_elf_select_section): Treat
> DEFAULT_ABI == ABI_AIX like PIC. Test PIC & reloc for readonly
> default.
> (rs6000_elf_unique_section): Treat DEFAULT_ABI == ABI_AIX like
> PIC.
> (rs6000_xcoff_select_section): Update to recent readonly
> algorithm.
Why not use decl_readonly_section? rs6000_elf_select_section ends up
looking like:
needs_sdata = (size > 0
&& size <= g_switch_value
&& rs6000_sdata != SDATA_NONE
&& (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
readonly = 0;
if (!needs_sdata || rs6000_sdata == SDATA_EABI)
readonly = decl_readonly_section (decl, reloc);
(*sec_funcs[(readonly ? 0 : 2) + (needs_sdata ? 1 : 0)])();
Similarly for the other functions. I've used this on gcc-3.2 based
powerpc64-linux for a couple of weeks. Patch available on request.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-21 18:54 ` Alan Modra
@ 2002-08-21 18:59 ` David Edelsohn
0 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-08-21 18:59 UTC (permalink / raw)
To: Alan Modra; +Cc: Geoff Keating, gcc-patches
>>>>> Alan Modra writes:
Alan> Why not use decl_readonly_section?
Alan> Similarly for the other functions. I've used this on gcc-3.2 based
Alan> powerpc64-linux for a couple of weeks. Patch available on request.
As I replied to Franz, testing flag_pic is not sufficient for
PPC64. Any patch using the varasm.c default functions without further
changes is wrong.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-21 11:29 ` David Edelsohn
2002-08-21 12:01 ` Franz Sirl
@ 2002-08-21 19:02 ` Alan Modra
2002-08-21 19:19 ` David Edelsohn
2002-08-29 18:03 ` Richard Henderson
1 sibling, 2 replies; 875+ messages in thread
From: Alan Modra @ 2002-08-21 19:02 UTC (permalink / raw)
To: David Edelsohn; +Cc: Franz Sirl, Geoff Keating, gcc-patches
On Wed, Aug 21, 2002 at 02:25:06PM -0400, David Edelsohn wrote:
> PowerPC cannot use the default functions in varasm.c because of
> its assumptions (e.g., flag_pic).
Ouch. Forget my suggestion re decl_readonly_section. Hmm, would
you accept a patch that cleans up flag_pic in rs6000.c? ie. has
flag_pic always set for ABI_AIX?
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-21 19:02 ` Alan Modra
@ 2002-08-21 19:19 ` David Edelsohn
2002-08-21 19:25 ` Alan Modra
2002-08-29 18:03 ` Richard Henderson
1 sibling, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-08-21 19:19 UTC (permalink / raw)
To: Alan Modra; +Cc: Franz Sirl, Geoff Keating, gcc-patches
>>>>> Alan Modra writes:
Alan> Ouch. Forget my suggestion re decl_readonly_section. Hmm, would
Alan> you accept a patch that cleans up flag_pic in rs6000.c? ie. has
Alan> flag_pic always set for ABI_AIX?
Have you actually tried that? flag_pic interferes with ABI_AIX
TOC register usage. ABI_AIX does not use the flag_pic machinery.
Now that I have fixed the ASM_GLOBALIZE_LABEL breakage, I am going
to get back to testing the select_section patch for GCC 3.2 and GCC 3.3.
We can look at cleaning up select_section and unique_section for GCC 3.4,
but it's too late for GCC 3.2 and GCC 3.3. I only am modifying the
current form of those functions enough to fix bugs.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-21 19:19 ` David Edelsohn
@ 2002-08-21 19:25 ` Alan Modra
2002-08-21 21:28 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-08-21 19:25 UTC (permalink / raw)
To: David Edelsohn; +Cc: Franz Sirl, Geoff Keating, gcc-patches
On Wed, Aug 21, 2002 at 10:07:13PM -0400, David Edelsohn wrote:
> >>>>> Alan Modra writes:
>
> Alan> Ouch. Forget my suggestion re decl_readonly_section. Hmm, would
> Alan> you accept a patch that cleans up flag_pic in rs6000.c? ie. has
> Alan> flag_pic always set for ABI_AIX?
>
> Have you actually tried that?
Not yet, but I think it's worth doing. Setting flag_pic to zero when
we are PIC amounts to lying to the rest of the compiler.
> flag_pic interferes with ABI_AIX
> TOC register usage. ABI_AIX does not use the flag_pic machinery.
Yes, I know. I'm talking about adding a DEFAULT_ABI test with all
uses of flag_pic in rs6000/*. Many already do so.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-21 19:25 ` Alan Modra
@ 2002-08-21 21:28 ` David Edelsohn
2002-08-29 18:19 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-08-21 21:28 UTC (permalink / raw)
To: Alan Modra; +Cc: Franz Sirl, Geoff Keating, gcc-patches
>>>>> Alan Modra writes:
Alan> Setting flag_pic to zero when
Alan> we are PIC amounts to lying to the rest of the compiler.
Not really. GCC handled PIC just fine before flag_pic was
introduced. flag_pic really means flag_got. It really means enable a
particular way of implementing PIC support, not enable PIC codegen. It
would be nice if flag_pic meant PIC, but the meaning is confused with the
implementation.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-21 12:15 ` David Edelsohn
@ 2002-08-29 18:01 ` Richard Henderson
0 siblings, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-08-29 18:01 UTC (permalink / raw)
To: David Edelsohn; +Cc: Franz Sirl, Geoff Keating, gcc-patches
On Wed, Aug 21, 2002 at 03:01:20PM -0400, David Edelsohn wrote:
> Yes, I considered setting and unsetting flag_pic, but that's ugly.
Nevertheless, see ia64_aix_unique_section and ia64_aix_select_rtx_section
in which exactly this is done. Personally, I think this is the best
solution.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-21 19:02 ` Alan Modra
2002-08-21 19:19 ` David Edelsohn
@ 2002-08-29 18:03 ` Richard Henderson
2002-08-30 7:15 ` Alan Modra
1 sibling, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-08-29 18:03 UTC (permalink / raw)
To: David Edelsohn, Franz Sirl, Geoff Keating, gcc-patches
On Thu, Aug 22, 2002 at 11:29:31AM +0930, Alan Modra wrote:
> Ouch. Forget my suggestion re decl_readonly_section. Hmm, would
> you accept a patch that cleans up flag_pic in rs6000.c? ie. has
> flag_pic always set for ABI_AIX?
That will pessimize ppc64-elf name binding. (I.e. binds_local_p.)
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-21 21:28 ` David Edelsohn
@ 2002-08-29 18:19 ` Richard Henderson
0 siblings, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-08-29 18:19 UTC (permalink / raw)
To: David Edelsohn; +Cc: Alan Modra, Franz Sirl, Geoff Keating, gcc-patches
On Wed, Aug 21, 2002 at 10:25:26PM -0400, David Edelsohn wrote:
> Alan> Setting flag_pic to zero when
> Alan> we are PIC amounts to lying to the rest of the compiler.
>
> Not really. GCC handled PIC just fine before flag_pic was
> introduced. flag_pic really means flag_got. It really means enable a
> particular way of implementing PIC support, not enable PIC codegen. It
> would be nice if flag_pic meant PIC, but the meaning is confused with the
> implementation.
Indeed. For ELF what it actually means is "compiling for
inclusion in a shared library". Existing usage of the
command-line switch is way too entrenched to rename it.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-29 18:03 ` Richard Henderson
@ 2002-08-30 7:15 ` Alan Modra
2002-08-30 8:27 ` Alan Modra
2002-08-30 8:42 ` David Edelsohn
0 siblings, 2 replies; 875+ messages in thread
From: Alan Modra @ 2002-08-30 7:15 UTC (permalink / raw)
To: Richard Henderson, David Edelsohn, Franz Sirl, Geoff Keating; +Cc: gcc-patches
On Thu, Aug 29, 2002 at 06:01:18PM -0700, Richard Henderson wrote:
> On Thu, Aug 22, 2002 at 11:29:31AM +0930, Alan Modra wrote:
> > Ouch. Forget my suggestion re decl_readonly_section. Hmm, would
> > you accept a patch that cleans up flag_pic in rs6000.c? ie. has
> > flag_pic always set for ABI_AIX?
>
> That will pessimize ppc64-elf name binding. (I.e. binds_local_p.)
Uh, oh. If I understand binds_local_p and mark_constant_function
correctly, setting flag_pic is actually a bug-fix when compiling
powerpc64-linux shared libs. We have the standard ELF binding of
global syms. That is, global functions may be overridden by functions
in another shared library or by the main application.
So powerpc64-linux-gcc should allow -fpic/PIC to twiddle flag_pic for
binds_local_p, and users should set -fPIC when compiling shared libs
as is common on other ELF targets. We could use another flag, because
like that annoying rs6000.c warning says "all code is position
independent" on ppc64, but that would make powerpc64-linux just that
more odd. Lots of packages set -fPIC to mean "compile me code for a
shared library".
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-30 7:15 ` Alan Modra
@ 2002-08-30 8:27 ` Alan Modra
2002-08-30 8:42 ` David Edelsohn
1 sibling, 0 replies; 875+ messages in thread
From: Alan Modra @ 2002-08-30 8:27 UTC (permalink / raw)
To: Richard Henderson, David Edelsohn, Franz Sirl, Geoff Keating,
gcc-patches
On Fri, Aug 30, 2002 at 11:00:23PM +0930, Alan Modra wrote:
> So powerpc64-linux-gcc should allow -fpic/PIC to twiddle flag_pic for
> binds_local_p
Just a note to save any duplication of effort:
I have a patch that does this and makes rs6000/* effectively ignore
flag_pic as regarding code generation when ABI_AIX. I'll post it in
the morning if my overnight builds are successful.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-30 7:15 ` Alan Modra
2002-08-30 8:27 ` Alan Modra
@ 2002-08-30 8:42 ` David Edelsohn
2002-08-30 11:17 ` Franz Sirl
2002-08-30 17:32 ` Alan Modra
1 sibling, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2002-08-30 8:42 UTC (permalink / raw)
To: Alan Modra; +Cc: Richard Henderson, Franz Sirl, Geoff Keating, gcc-patches
>>>>> Alan Modra writes:
Alan> Uh, oh. If I understand binds_local_p and mark_constant_function
Alan> correctly, setting flag_pic is actually a bug-fix when compiling
Alan> powerpc64-linux shared libs. We have the standard ELF binding of
Alan> global syms. That is, global functions may be overridden by functions
Alan> in another shared library or by the main application.
Alan> So powerpc64-linux-gcc should allow -fpic/PIC to twiddle flag_pic for
Alan> binds_local_p, and users should set -fPIC when compiling shared libs
Alan> as is common on other ELF targets. We could use another flag, because
Alan> like that annoying rs6000.c warning says "all code is position
Alan> independent" on ppc64, but that would make powerpc64-linux just that
Alan> more odd. Lots of packages set -fPIC to mean "compile me code for a
Alan> shared library".
This is what the patch that I applied to both gcc-3.2 and the
trunk already does, without utilizing the generic infrastructure. The
PowerPC port currently does not use the targetm.binds_local_p. We can
discuss evolving to the generic infrastructure for GCC 3.4.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-30 8:42 ` David Edelsohn
@ 2002-08-30 11:17 ` Franz Sirl
2002-08-30 11:26 ` Franz Sirl
2002-08-30 11:29 ` David Edelsohn
2002-08-30 17:32 ` Alan Modra
1 sibling, 2 replies; 875+ messages in thread
From: Franz Sirl @ 2002-08-30 11:17 UTC (permalink / raw)
To: David Edelsohn; +Cc: Alan Modra, Richard Henderson, Geoff Keating, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1509 bytes --]
At 17:27 30.08.2002, David Edelsohn wrote:
> >>>>> Alan Modra writes:
>
>Alan> Uh, oh. If I understand binds_local_p and mark_constant_function
>Alan> correctly, setting flag_pic is actually a bug-fix when compiling
>Alan> powerpc64-linux shared libs. We have the standard ELF binding of
>Alan> global syms. That is, global functions may be overridden by functions
>Alan> in another shared library or by the main application.
>
>Alan> So powerpc64-linux-gcc should allow -fpic/PIC to twiddle flag_pic for
>Alan> binds_local_p, and users should set -fPIC when compiling shared libs
>Alan> as is common on other ELF targets. We could use another flag, because
>Alan> like that annoying rs6000.c warning says "all code is position
>Alan> independent" on ppc64, but that would make powerpc64-linux just that
>Alan> more odd. Lots of packages set -fPIC to mean "compile me code for a
>Alan> shared library".
>
> This is what the patch that I applied to both gcc-3.2 and the
>trunk already does, without utilizing the generic infrastructure. The
>PowerPC port currently does not use the targetm.binds_local_p. We can
>discuss evolving to the generic infrastructure for GCC 3.4.
What might be acceptable for 3.3 still is the appended patch which
basically just copies the varasm routines to rs6000.c and adds SDATA2 and
AIXELF PIC handling. Briefly tested on powerpc-linux-gnu without
regressions. Can the AIXELF people give it a try? Sorry, no changelog yet,
I'm in a hurry right now.
Franz.
[-- Attachment #2: gcc-ppcsections-1.patch --]
[-- Type: application/octet-stream, Size: 15128 bytes --]
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.368
diff -u -p -r1.368 rs6000.c
--- gcc/config/rs6000/rs6000.c 23 Aug 2002 18:02:22 -0000 1.368
+++ gcc/config/rs6000/rs6000.c 30 Aug 2002 18:08:39 -0000
@@ -196,9 +196,11 @@ static unsigned int rs6000_elf_section_t
int));
static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
-static void rs6000_elf_select_section PARAMS ((tree, int,
- unsigned HOST_WIDE_INT));
-static void rs6000_elf_unique_section PARAMS ((tree, int));
+static bool rs6000_in_small_data_p PARAMS ((tree));
+
+void rs6000_elf_select_section PARAMS ((tree, int,
+ unsigned HOST_WIDE_INT));
+void rs6000_elf_unique_section PARAMS ((tree, int));
static void rs6000_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
unsigned HOST_WIDE_INT));
static void rs6000_elf_encode_section_info PARAMS ((tree, int));
@@ -308,7 +310,8 @@ static const char alt_reg_names[][8] =
#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
-
+#undef TARGET_IN_SMALL_DATA_P
+#define TARGET_IN_SMALL_DATA_P rs6000_in_small_data_p
#undef TARGET_ASM_ALIGNED_DI_OP
#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
@@ -6503,7 +6506,7 @@ mtcrf_operation (op, mode)
maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
if (GET_CODE (unspec) != UNSPEC
- || XINT (unspec, 1) != 20
+ || XINT (unspec, 1) != UNSPEC_MOVESI_TO_CR
|| XVECLEN (unspec, 0) != 2
|| XVECEXP (unspec, 0, 0) != src_reg
|| GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
@@ -9633,7 +9636,7 @@ get_TOC_alias_set ()
}
/* This retuns nonzero if the current function uses the TOC. This is
- determined by the presence of (unspec ... 7), which is generated by
+ determined by the presence of (unspec ... UNSPEC_TOCADR), which is generated by
the various load_toc_* patterns. */
int
@@ -9650,7 +9653,7 @@ uses_TOC ()
if (GET_CODE (pat) == PARALLEL)
for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC
- && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7)
+ && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == UNSPEC_TOCADR)
return 1;
}
return 0;
@@ -10845,7 +10848,7 @@ rs6000_emit_epilogue (sibcall)
RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
RTVEC_ELT (p, ndx) =
gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
- gen_rtx_UNSPEC (CCmode, r, 20));
+ gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
ndx++;
}
emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
@@ -12416,137 +12419,293 @@ rs6000_elf_select_rtx_section (mode, x,
default_elf_select_rtx_section (mode, x, align);
}
-/* A C statement or statements to switch to the appropriate
- section for output of DECL. DECL is either a `VAR_DECL' node
- or a constant of some sort. RELOC indicates whether forming
- the initial value of DECL requires link-time relocations. */
-static void
-rs6000_elf_select_section (decl, reloc, align)
+static bool
+rs6000_in_small_data_p (decl)
tree decl;
- int reloc;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
{
- int size = int_size_in_bytes (TREE_TYPE (decl));
- bool needs_sdata;
- bool readonly;
- static void (* const sec_funcs[4]) PARAMS ((void)) = {
- &readonly_data_section,
- &sdata2_section,
- &data_section,
- &sdata_section
- };
+ /* We want to merge strings, so we never consider them small data. */
+ if (TREE_CODE (decl) == STRING_CST)
+ return false;
- needs_sdata = (size > 0
- && size <= g_switch_value
- && rs6000_sdata != SDATA_NONE
- && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
+ if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
+ {
+ const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+ if (strcmp (section, ".sdata") == 0
+ || strcmp (section, ".sdata2") == 0
+ || strcmp (section, ".sbss") == 0)
+ return true;
+ }
+ else
+ {
+ int size = int_size_in_bytes (TREE_TYPE (decl));
+ return (size > 0
+ && size <= g_switch_value
+ && rs6000_sdata != SDATA_NONE
+ && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
+ }
+}
- if (TREE_CODE (decl) == STRING_CST)
- readonly = !flag_writable_strings;
+/* A helper function for default_elf_select_section and
+ default_elf_unique_section. Categorizes the DECL. */
+
+enum rs6000_section_category
+{
+ SECCAT_TEXT,
+
+ SECCAT_RODATA,
+ SECCAT_RODATA_MERGE_STR,
+ SECCAT_RODATA_MERGE_STR_INIT,
+ SECCAT_RODATA_MERGE_CONST,
+
+ SECCAT_DATA,
+
+ /* To optimize loading of shared programs, define following subsections
+ of data section:
+ _REL Contains data that has relocations, so they get grouped
+ together and dynamic linker will visit fewer pages in memory.
+ _RO Contains data that is otherwise read-only. This is useful
+ with prelinking as most relocations won't be dynamically
+ linked and thus stay read only.
+ _LOCAL Marks data containing relocations only to local objects.
+ These relocations will get fully resolved by prelinking. */
+ SECCAT_DATA_REL,
+ SECCAT_DATA_REL_LOCAL,
+ SECCAT_DATA_REL_RO,
+ SECCAT_DATA_REL_RO_LOCAL,
+
+ SECCAT_SDATA,
+ SECCAT_SDATA2,
+ SECCAT_TDATA,
+
+ SECCAT_BSS,
+ SECCAT_SBSS,
+ SECCAT_TBSS
+};
+
+static enum rs6000_section_category rs6000_categorize_decl_for_section PARAMS ((tree, int, int));
+
+static enum rs6000_section_category
+rs6000_categorize_decl_for_section (decl, reloc, pic)
+ tree decl;
+ int reloc;
+ int pic;
+{
+ enum rs6000_section_category ret;
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ return SECCAT_TEXT;
+ else if (TREE_CODE (decl) == STRING_CST)
+ {
+ if (flag_writable_strings)
+ return SECCAT_DATA;
+ else
+ return SECCAT_RODATA_MERGE_STR;
+ }
else if (TREE_CODE (decl) == VAR_DECL)
- readonly = (!((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
- && TREE_READONLY (decl)
- && !TREE_SIDE_EFFECTS (decl)
- && DECL_INITIAL (decl)
- && DECL_INITIAL (decl) != error_mark_node
- && TREE_CONSTANT (DECL_INITIAL (decl)));
+ {
+ if (DECL_INITIAL (decl) == NULL
+ || DECL_INITIAL (decl) == error_mark_node)
+ ret = SECCAT_BSS;
+ else if (! TREE_READONLY (decl)
+ || TREE_SIDE_EFFECTS (decl)
+ || ! TREE_CONSTANT (DECL_INITIAL (decl)))
+ {
+ if (pic && (reloc & 2))
+ ret = SECCAT_DATA_REL;
+ else if (pic && reloc)
+ ret = SECCAT_DATA_REL_LOCAL;
+ else
+ ret = SECCAT_DATA;
+ }
+ else if (pic && (reloc & 2))
+ ret = SECCAT_DATA_REL_RO;
+ else if (pic && reloc)
+ ret = SECCAT_DATA_REL_RO_LOCAL;
+ else if (flag_merge_constants < 2)
+ /* C and C++ don't allow different variables to share the same
+ location. -fmerge-all-constants allows even that (at the
+ expense of not conforming). */
+ ret = SECCAT_RODATA;
+ else if (TREE_CODE (DECL_INITIAL (decl)) == STRING_CST)
+ ret = SECCAT_RODATA_MERGE_STR_INIT;
+ else
+ ret = SECCAT_RODATA_MERGE_CONST;
+ }
else if (TREE_CODE (decl) == CONSTRUCTOR)
- readonly = (!((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
- && !TREE_SIDE_EFFECTS (decl)
- && TREE_CONSTANT (decl));
+ {
+ if ((pic && reloc)
+ || TREE_SIDE_EFFECTS (decl)
+ || ! TREE_CONSTANT (decl))
+ ret = SECCAT_DATA;
+ else
+ ret = SECCAT_RODATA;
+ }
else
- readonly = !((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc);
+ ret = SECCAT_RODATA;
- if (needs_sdata && rs6000_sdata != SDATA_EABI)
- readonly = false;
-
- (*sec_funcs[(readonly ? 0 : 2) + (needs_sdata ? 1 : 0)])();
+ /* There are no read-only thread-local sections. */
+ if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
+ {
+ if (ret == SECCAT_BSS)
+ ret = SECCAT_TBSS;
+ else
+ ret = SECCAT_TDATA;
+ }
+
+ /* If the target uses small data sections, select it. */
+ else if ((*targetm.in_small_data_p) (decl))
+ {
+ if (ret == SECCAT_BSS)
+ ret = SECCAT_SBSS;
+ else
+ ret = SECCAT_SDATA;
+ }
+
+ /* With EABI we put small readonly data into .sdata2. */
+ if (ret == SECCAT_RODATA && rs6000_sdata == SDATA_EABI
+ && (*targetm.in_small_data_p) (decl))
+ ret = SECCAT_SDATA2;
+
+ return ret;
}
-/* A C statement to build up a unique section name, expressed as a
- STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
- RELOC indicates whether the initial value of EXP requires
- link-time relocations. If you do not define this macro, GCC will use
- the symbol name prefixed by `.' as the section name. Note - this
- macro can now be called for uninitialized data items as well as
- initialised data and functions. */
+/* Select a section based on the above categorization. */
-static void
+void
+rs6000_elf_select_section (decl, reloc, align)
+ tree decl;
+ int reloc;
+ unsigned HOST_WIDE_INT align;
+{
+ bool pic = flag_pic || DEFAULT_ABI == ABI_AIX;
+
+ switch (rs6000_categorize_decl_for_section (decl, reloc, pic))
+ {
+ case SECCAT_TEXT:
+ /* We're not supposed to be called on FUNCTION_DECLs. */
+ abort ();
+ case SECCAT_RODATA:
+ readonly_data_section ();
+ break;
+ case SECCAT_RODATA_MERGE_STR:
+ mergeable_string_section (decl, align, 0);
+ break;
+ case SECCAT_RODATA_MERGE_STR_INIT:
+ mergeable_string_section (DECL_INITIAL (decl), align, 0);
+ break;
+ case SECCAT_RODATA_MERGE_CONST:
+ mergeable_constant_section (DECL_MODE (decl), align, 0);
+ break;
+ case SECCAT_DATA:
+ data_section ();
+ break;
+ case SECCAT_DATA_REL:
+ named_section (NULL_TREE, ".data.rel", reloc);
+ break;
+ case SECCAT_DATA_REL_LOCAL:
+ named_section (NULL_TREE, ".data.rel.local", reloc);
+ break;
+ case SECCAT_DATA_REL_RO:
+ named_section (NULL_TREE, ".data.rel.ro", reloc);
+ break;
+ case SECCAT_DATA_REL_RO_LOCAL:
+ named_section (NULL_TREE, ".data.rel.ro.local", reloc);
+ break;
+ case SECCAT_SDATA:
+ named_section (NULL_TREE, ".sdata", reloc);
+ break;
+ case SECCAT_SDATA2:
+ named_section (NULL_TREE, ".sdata2", reloc);
+ break;
+ case SECCAT_TDATA:
+ named_section (NULL_TREE, ".tdata", reloc);
+ break;
+ case SECCAT_BSS:
+#ifdef BSS_SECTION_ASM_OP
+ bss_section ();
+#else
+ named_section (NULL_TREE, ".bss", reloc);
+#endif
+ break;
+ case SECCAT_SBSS:
+ named_section (NULL_TREE, ".sbss", reloc);
+ break;
+ case SECCAT_TBSS:
+ named_section (NULL_TREE, ".tbss", reloc);
+ break;
+ default:
+ abort ();
+ }
+}
+
+/* Construct a unique section name based on the decl name and the
+ categorization performed above. */
+
+void
rs6000_elf_unique_section (decl, reloc)
tree decl;
int reloc;
{
- int len;
- int sec;
- const char *name;
+ bool one_only = DECL_ONE_ONLY (decl);
+ bool pic = flag_pic || DEFAULT_ABI == ABI_AIX;
+ const char *prefix, *name;
+ size_t nlen, plen;
char *string;
- const char *prefix;
- static const char *const prefixes[7][2] =
- {
- { ".rodata.", ".gnu.linkonce.r." },
- { ".sdata2.", ".gnu.linkonce.s2." },
- { ".data.", ".gnu.linkonce.d." },
- { ".sdata.", ".gnu.linkonce.s." },
- { ".bss.", ".gnu.linkonce.b." },
- { ".sbss.", ".gnu.linkonce.sb." },
- { ".text.", ".gnu.linkonce.t." }
- };
-
- if (TREE_CODE (decl) == FUNCTION_DECL)
- sec = 6;
- else
+ switch (rs6000_categorize_decl_for_section (decl, reloc, pic))
{
- bool readonly;
- bool needs_sdata;
- int size;
-
- if (TREE_CODE (decl) == STRING_CST)
- readonly = !flag_writable_strings;
- else if (TREE_CODE (decl) == VAR_DECL)
- readonly = (!((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
- && TREE_READONLY (decl)
- && !TREE_SIDE_EFFECTS (decl)
- && TREE_CONSTANT (DECL_INITIAL (decl)));
- else
- readonly = !((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc);
-
- size = int_size_in_bytes (TREE_TYPE (decl));
- needs_sdata = (size > 0
- && size <= g_switch_value
- && rs6000_sdata != SDATA_NONE
- && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
-
- if (DECL_INITIAL (decl) == NULL
- || DECL_INITIAL (decl) == error_mark_node)
- sec = 4;
- else if (!readonly)
- sec = 2;
- else
- sec = 0;
-
- if (needs_sdata)
- {
- /* .sdata2 is only for EABI. */
- if (sec == 0 && rs6000_sdata != SDATA_EABI)
- sec = 2;
- sec += 1;
- }
+ case SECCAT_TEXT:
+ prefix = one_only ? ".gnu.linkonce.t." : ".text.";
+ break;
+ case SECCAT_RODATA:
+ case SECCAT_RODATA_MERGE_STR:
+ case SECCAT_RODATA_MERGE_STR_INIT:
+ case SECCAT_RODATA_MERGE_CONST:
+ prefix = one_only ? ".gnu.linkonce.r." : ".rodata.";
+ break;
+ case SECCAT_DATA:
+ case SECCAT_DATA_REL:
+ case SECCAT_DATA_REL_LOCAL:
+ case SECCAT_DATA_REL_RO:
+ case SECCAT_DATA_REL_RO_LOCAL:
+ prefix = one_only ? ".gnu.linkonce.d." : ".data.";
+ break;
+ case SECCAT_SDATA:
+ prefix = one_only ? ".gnu.linkonce.s." : ".sdata.";
+ break;
+ case SECCAT_SDATA2:
+ prefix = one_only ? ".gnu.linkonce.s2." : ".sdata2.";
+ break;
+ case SECCAT_BSS:
+ prefix = one_only ? ".gnu.linkonce.b." : ".bss.";
+ break;
+ case SECCAT_SBSS:
+ prefix = one_only ? ".gnu.linkonce.sb." : ".sbss.";
+ break;
+ case SECCAT_TDATA:
+ prefix = one_only ? ".gnu.linkonce.td." : ".tdata.";
+ break;
+ case SECCAT_TBSS:
+ prefix = one_only ? ".gnu.linkonce.tb." : ".tbss.";
+ break;
+ default:
+ abort ();
}
+ plen = strlen (prefix);
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
- name = (*targetm.strip_name_encoding) (name);
- prefix = prefixes[sec][DECL_ONE_ONLY (decl)];
- len = strlen (name) + strlen (prefix);
- string = alloca (len + 1);
-
- sprintf (string, "%s%s", prefix, name);
-
- DECL_SECTION_NAME (decl) = build_string (len, string);
+ name = (* targetm.strip_name_encoding) (name);
+ nlen = strlen (name);
+
+ string = alloca (nlen + plen + 1);
+ memcpy (string, prefix, plen);
+ memcpy (string + plen, name, nlen + 1);
+
+ DECL_SECTION_NAME (decl) = build_string (nlen + plen, string);
}
-\f
+
/* If we are referencing a function that is static or is known to be
in this file, make the SYMBOL_REF special. We can use this to indicate
that we can branch to this function without emitting a no-op after the
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-30 11:17 ` Franz Sirl
@ 2002-08-30 11:26 ` Franz Sirl
2002-08-30 11:29 ` David Edelsohn
1 sibling, 0 replies; 875+ messages in thread
From: Franz Sirl @ 2002-08-30 11:26 UTC (permalink / raw)
To: David Edelsohn; +Cc: Alan Modra, Richard Henderson, Geoff Keating, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1931 bytes --]
At 20:15 30.08.2002, David Edelsohn wrote:
>At 17:27 30.08.2002, David Edelsohn wrote:
>> >>>>> Alan Modra writes:
>>
>>Alan> Uh, oh. If I understand binds_local_p and mark_constant_function
>>Alan> correctly, setting flag_pic is actually a bug-fix when compiling
>>Alan> powerpc64-linux shared libs. We have the standard ELF binding of
>>Alan> global syms. That is, global functions may be overridden by functions
>>Alan> in another shared library or by the main application.
>>
>>Alan> So powerpc64-linux-gcc should allow -fpic/PIC to twiddle flag_pic for
>>Alan> binds_local_p, and users should set -fPIC when compiling shared libs
>>Alan> as is common on other ELF targets. We could use another flag, because
>>Alan> like that annoying rs6000.c warning says "all code is position
>>Alan> independent" on ppc64, but that would make powerpc64-linux just that
>>Alan> more odd. Lots of packages set -fPIC to mean "compile me code for a
>>Alan> shared library".
>>
>> This is what the patch that I applied to both gcc-3.2 and the
>>trunk already does, without utilizing the generic infrastructure. The
>>PowerPC port currently does not use the targetm.binds_local_p. We can
>>discuss evolving to the generic infrastructure for GCC 3.4.
>
>What might be acceptable for 3.3 still is the appended patch which
>basically just copies the varasm routines to rs6000.c and adds SDATA2 and
>AIXELF PIC handling. Briefly tested on powerpc-linux-gnu without
>regressions. Can the AIXELF people give it a try? Sorry, no changelog yet,
>I'm in a hurry right now.
Argh, forgot to remove the define_constant hunks, here the corrected patch.
And one comment, while working on this it occurred to me it's not that easy
to re-use the varasm code for 3.4 with the current structure, even if I add
a target hook for categorize_decl_for_section as suggested. The aborts in
the generic functions make re-use difficult...
Franz.
[-- Attachment #2: gcc-ppcsections-1a.patch --]
[-- Type: application/octet-stream, Size: 13732 bytes --]
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.368
diff -u -p -r1.368 rs6000.c
--- gcc/config/rs6000/rs6000.c 23 Aug 2002 18:02:22 -0000 1.368
+++ gcc/config/rs6000/rs6000.c 30 Aug 2002 18:08:39 -0000
@@ -196,9 +196,11 @@ static unsigned int rs6000_elf_section_t
int));
static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
-static void rs6000_elf_select_section PARAMS ((tree, int,
- unsigned HOST_WIDE_INT));
-static void rs6000_elf_unique_section PARAMS ((tree, int));
+static bool rs6000_in_small_data_p PARAMS ((tree));
+
+void rs6000_elf_select_section PARAMS ((tree, int,
+ unsigned HOST_WIDE_INT));
+void rs6000_elf_unique_section PARAMS ((tree, int));
static void rs6000_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
unsigned HOST_WIDE_INT));
static void rs6000_elf_encode_section_info PARAMS ((tree, int));
@@ -308,7 +310,8 @@ static const char alt_reg_names[][8] =
#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
-
+#undef TARGET_IN_SMALL_DATA_P
+#define TARGET_IN_SMALL_DATA_P rs6000_in_small_data_p
#undef TARGET_ASM_ALIGNED_DI_OP
#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
@@ -12416,137 +12419,293 @@ rs6000_elf_select_rtx_section (mode, x,
default_elf_select_rtx_section (mode, x, align);
}
-/* A C statement or statements to switch to the appropriate
- section for output of DECL. DECL is either a `VAR_DECL' node
- or a constant of some sort. RELOC indicates whether forming
- the initial value of DECL requires link-time relocations. */
-static void
-rs6000_elf_select_section (decl, reloc, align)
+static bool
+rs6000_in_small_data_p (decl)
tree decl;
- int reloc;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
{
- int size = int_size_in_bytes (TREE_TYPE (decl));
- bool needs_sdata;
- bool readonly;
- static void (* const sec_funcs[4]) PARAMS ((void)) = {
- &readonly_data_section,
- &sdata2_section,
- &data_section,
- &sdata_section
- };
+ /* We want to merge strings, so we never consider them small data. */
+ if (TREE_CODE (decl) == STRING_CST)
+ return false;
- needs_sdata = (size > 0
- && size <= g_switch_value
- && rs6000_sdata != SDATA_NONE
- && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
+ if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
+ {
+ const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+ if (strcmp (section, ".sdata") == 0
+ || strcmp (section, ".sdata2") == 0
+ || strcmp (section, ".sbss") == 0)
+ return true;
+ }
+ else
+ {
+ int size = int_size_in_bytes (TREE_TYPE (decl));
+ return (size > 0
+ && size <= g_switch_value
+ && rs6000_sdata != SDATA_NONE
+ && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
+ }
+}
- if (TREE_CODE (decl) == STRING_CST)
- readonly = !flag_writable_strings;
+/* A helper function for default_elf_select_section and
+ default_elf_unique_section. Categorizes the DECL. */
+
+enum rs6000_section_category
+{
+ SECCAT_TEXT,
+
+ SECCAT_RODATA,
+ SECCAT_RODATA_MERGE_STR,
+ SECCAT_RODATA_MERGE_STR_INIT,
+ SECCAT_RODATA_MERGE_CONST,
+
+ SECCAT_DATA,
+
+ /* To optimize loading of shared programs, define following subsections
+ of data section:
+ _REL Contains data that has relocations, so they get grouped
+ together and dynamic linker will visit fewer pages in memory.
+ _RO Contains data that is otherwise read-only. This is useful
+ with prelinking as most relocations won't be dynamically
+ linked and thus stay read only.
+ _LOCAL Marks data containing relocations only to local objects.
+ These relocations will get fully resolved by prelinking. */
+ SECCAT_DATA_REL,
+ SECCAT_DATA_REL_LOCAL,
+ SECCAT_DATA_REL_RO,
+ SECCAT_DATA_REL_RO_LOCAL,
+
+ SECCAT_SDATA,
+ SECCAT_SDATA2,
+ SECCAT_TDATA,
+
+ SECCAT_BSS,
+ SECCAT_SBSS,
+ SECCAT_TBSS
+};
+
+static enum rs6000_section_category rs6000_categorize_decl_for_section PARAMS ((tree, int, int));
+
+static enum rs6000_section_category
+rs6000_categorize_decl_for_section (decl, reloc, pic)
+ tree decl;
+ int reloc;
+ int pic;
+{
+ enum rs6000_section_category ret;
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ return SECCAT_TEXT;
+ else if (TREE_CODE (decl) == STRING_CST)
+ {
+ if (flag_writable_strings)
+ return SECCAT_DATA;
+ else
+ return SECCAT_RODATA_MERGE_STR;
+ }
else if (TREE_CODE (decl) == VAR_DECL)
- readonly = (!((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
- && TREE_READONLY (decl)
- && !TREE_SIDE_EFFECTS (decl)
- && DECL_INITIAL (decl)
- && DECL_INITIAL (decl) != error_mark_node
- && TREE_CONSTANT (DECL_INITIAL (decl)));
+ {
+ if (DECL_INITIAL (decl) == NULL
+ || DECL_INITIAL (decl) == error_mark_node)
+ ret = SECCAT_BSS;
+ else if (! TREE_READONLY (decl)
+ || TREE_SIDE_EFFECTS (decl)
+ || ! TREE_CONSTANT (DECL_INITIAL (decl)))
+ {
+ if (pic && (reloc & 2))
+ ret = SECCAT_DATA_REL;
+ else if (pic && reloc)
+ ret = SECCAT_DATA_REL_LOCAL;
+ else
+ ret = SECCAT_DATA;
+ }
+ else if (pic && (reloc & 2))
+ ret = SECCAT_DATA_REL_RO;
+ else if (pic && reloc)
+ ret = SECCAT_DATA_REL_RO_LOCAL;
+ else if (flag_merge_constants < 2)
+ /* C and C++ don't allow different variables to share the same
+ location. -fmerge-all-constants allows even that (at the
+ expense of not conforming). */
+ ret = SECCAT_RODATA;
+ else if (TREE_CODE (DECL_INITIAL (decl)) == STRING_CST)
+ ret = SECCAT_RODATA_MERGE_STR_INIT;
+ else
+ ret = SECCAT_RODATA_MERGE_CONST;
+ }
else if (TREE_CODE (decl) == CONSTRUCTOR)
- readonly = (!((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
- && !TREE_SIDE_EFFECTS (decl)
- && TREE_CONSTANT (decl));
+ {
+ if ((pic && reloc)
+ || TREE_SIDE_EFFECTS (decl)
+ || ! TREE_CONSTANT (decl))
+ ret = SECCAT_DATA;
+ else
+ ret = SECCAT_RODATA;
+ }
else
- readonly = !((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc);
+ ret = SECCAT_RODATA;
- if (needs_sdata && rs6000_sdata != SDATA_EABI)
- readonly = false;
-
- (*sec_funcs[(readonly ? 0 : 2) + (needs_sdata ? 1 : 0)])();
+ /* There are no read-only thread-local sections. */
+ if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
+ {
+ if (ret == SECCAT_BSS)
+ ret = SECCAT_TBSS;
+ else
+ ret = SECCAT_TDATA;
+ }
+
+ /* If the target uses small data sections, select it. */
+ else if ((*targetm.in_small_data_p) (decl))
+ {
+ if (ret == SECCAT_BSS)
+ ret = SECCAT_SBSS;
+ else
+ ret = SECCAT_SDATA;
+ }
+
+ /* With EABI we put small readonly data into .sdata2. */
+ if (ret == SECCAT_RODATA && rs6000_sdata == SDATA_EABI
+ && (*targetm.in_small_data_p) (decl))
+ ret = SECCAT_SDATA2;
+
+ return ret;
}
-/* A C statement to build up a unique section name, expressed as a
- STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
- RELOC indicates whether the initial value of EXP requires
- link-time relocations. If you do not define this macro, GCC will use
- the symbol name prefixed by `.' as the section name. Note - this
- macro can now be called for uninitialized data items as well as
- initialised data and functions. */
+/* Select a section based on the above categorization. */
-static void
+void
+rs6000_elf_select_section (decl, reloc, align)
+ tree decl;
+ int reloc;
+ unsigned HOST_WIDE_INT align;
+{
+ bool pic = flag_pic || DEFAULT_ABI == ABI_AIX;
+
+ switch (rs6000_categorize_decl_for_section (decl, reloc, pic))
+ {
+ case SECCAT_TEXT:
+ /* We're not supposed to be called on FUNCTION_DECLs. */
+ abort ();
+ case SECCAT_RODATA:
+ readonly_data_section ();
+ break;
+ case SECCAT_RODATA_MERGE_STR:
+ mergeable_string_section (decl, align, 0);
+ break;
+ case SECCAT_RODATA_MERGE_STR_INIT:
+ mergeable_string_section (DECL_INITIAL (decl), align, 0);
+ break;
+ case SECCAT_RODATA_MERGE_CONST:
+ mergeable_constant_section (DECL_MODE (decl), align, 0);
+ break;
+ case SECCAT_DATA:
+ data_section ();
+ break;
+ case SECCAT_DATA_REL:
+ named_section (NULL_TREE, ".data.rel", reloc);
+ break;
+ case SECCAT_DATA_REL_LOCAL:
+ named_section (NULL_TREE, ".data.rel.local", reloc);
+ break;
+ case SECCAT_DATA_REL_RO:
+ named_section (NULL_TREE, ".data.rel.ro", reloc);
+ break;
+ case SECCAT_DATA_REL_RO_LOCAL:
+ named_section (NULL_TREE, ".data.rel.ro.local", reloc);
+ break;
+ case SECCAT_SDATA:
+ named_section (NULL_TREE, ".sdata", reloc);
+ break;
+ case SECCAT_SDATA2:
+ named_section (NULL_TREE, ".sdata2", reloc);
+ break;
+ case SECCAT_TDATA:
+ named_section (NULL_TREE, ".tdata", reloc);
+ break;
+ case SECCAT_BSS:
+#ifdef BSS_SECTION_ASM_OP
+ bss_section ();
+#else
+ named_section (NULL_TREE, ".bss", reloc);
+#endif
+ break;
+ case SECCAT_SBSS:
+ named_section (NULL_TREE, ".sbss", reloc);
+ break;
+ case SECCAT_TBSS:
+ named_section (NULL_TREE, ".tbss", reloc);
+ break;
+ default:
+ abort ();
+ }
+}
+
+/* Construct a unique section name based on the decl name and the
+ categorization performed above. */
+
+void
rs6000_elf_unique_section (decl, reloc)
tree decl;
int reloc;
{
- int len;
- int sec;
- const char *name;
+ bool one_only = DECL_ONE_ONLY (decl);
+ bool pic = flag_pic || DEFAULT_ABI == ABI_AIX;
+ const char *prefix, *name;
+ size_t nlen, plen;
char *string;
- const char *prefix;
- static const char *const prefixes[7][2] =
- {
- { ".rodata.", ".gnu.linkonce.r." },
- { ".sdata2.", ".gnu.linkonce.s2." },
- { ".data.", ".gnu.linkonce.d." },
- { ".sdata.", ".gnu.linkonce.s." },
- { ".bss.", ".gnu.linkonce.b." },
- { ".sbss.", ".gnu.linkonce.sb." },
- { ".text.", ".gnu.linkonce.t." }
- };
-
- if (TREE_CODE (decl) == FUNCTION_DECL)
- sec = 6;
- else
+ switch (rs6000_categorize_decl_for_section (decl, reloc, pic))
{
- bool readonly;
- bool needs_sdata;
- int size;
-
- if (TREE_CODE (decl) == STRING_CST)
- readonly = !flag_writable_strings;
- else if (TREE_CODE (decl) == VAR_DECL)
- readonly = (!((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
- && TREE_READONLY (decl)
- && !TREE_SIDE_EFFECTS (decl)
- && TREE_CONSTANT (DECL_INITIAL (decl)));
- else
- readonly = !((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc);
-
- size = int_size_in_bytes (TREE_TYPE (decl));
- needs_sdata = (size > 0
- && size <= g_switch_value
- && rs6000_sdata != SDATA_NONE
- && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
-
- if (DECL_INITIAL (decl) == NULL
- || DECL_INITIAL (decl) == error_mark_node)
- sec = 4;
- else if (!readonly)
- sec = 2;
- else
- sec = 0;
-
- if (needs_sdata)
- {
- /* .sdata2 is only for EABI. */
- if (sec == 0 && rs6000_sdata != SDATA_EABI)
- sec = 2;
- sec += 1;
- }
+ case SECCAT_TEXT:
+ prefix = one_only ? ".gnu.linkonce.t." : ".text.";
+ break;
+ case SECCAT_RODATA:
+ case SECCAT_RODATA_MERGE_STR:
+ case SECCAT_RODATA_MERGE_STR_INIT:
+ case SECCAT_RODATA_MERGE_CONST:
+ prefix = one_only ? ".gnu.linkonce.r." : ".rodata.";
+ break;
+ case SECCAT_DATA:
+ case SECCAT_DATA_REL:
+ case SECCAT_DATA_REL_LOCAL:
+ case SECCAT_DATA_REL_RO:
+ case SECCAT_DATA_REL_RO_LOCAL:
+ prefix = one_only ? ".gnu.linkonce.d." : ".data.";
+ break;
+ case SECCAT_SDATA:
+ prefix = one_only ? ".gnu.linkonce.s." : ".sdata.";
+ break;
+ case SECCAT_SDATA2:
+ prefix = one_only ? ".gnu.linkonce.s2." : ".sdata2.";
+ break;
+ case SECCAT_BSS:
+ prefix = one_only ? ".gnu.linkonce.b." : ".bss.";
+ break;
+ case SECCAT_SBSS:
+ prefix = one_only ? ".gnu.linkonce.sb." : ".sbss.";
+ break;
+ case SECCAT_TDATA:
+ prefix = one_only ? ".gnu.linkonce.td." : ".tdata.";
+ break;
+ case SECCAT_TBSS:
+ prefix = one_only ? ".gnu.linkonce.tb." : ".tbss.";
+ break;
+ default:
+ abort ();
}
+ plen = strlen (prefix);
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
- name = (*targetm.strip_name_encoding) (name);
- prefix = prefixes[sec][DECL_ONE_ONLY (decl)];
- len = strlen (name) + strlen (prefix);
- string = alloca (len + 1);
-
- sprintf (string, "%s%s", prefix, name);
-
- DECL_SECTION_NAME (decl) = build_string (len, string);
+ name = (* targetm.strip_name_encoding) (name);
+ nlen = strlen (name);
+
+ string = alloca (nlen + plen + 1);
+ memcpy (string, prefix, plen);
+ memcpy (string + plen, name, nlen + 1);
+
+ DECL_SECTION_NAME (decl) = build_string (nlen + plen, string);
}
-\f
+
/* If we are referencing a function that is static or is known to be
in this file, make the SYMBOL_REF special. We can use this to indicate
that we can branch to this function without emitting a no-op after the
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-30 11:17 ` Franz Sirl
2002-08-30 11:26 ` Franz Sirl
@ 2002-08-30 11:29 ` David Edelsohn
1 sibling, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-08-30 11:29 UTC (permalink / raw)
To: Franz Sirl; +Cc: Alan Modra, Richard Henderson, Geoff Keating, gcc-patches
>>>>> Franz Sirl writes:
Franz> What might be acceptable for 3.3 still is the appended patch which
Franz> basically just copies the varasm routines to rs6000.c and adds SDATA2 and
Franz> AIXELF PIC handling. Briefly tested on powerpc-linux-gnu without
Franz> regressions. Can the AIXELF people give it a try?
No, this is not acceptable for GCC 3.3. This is not a bugfix.
For GCC 3.4 we can explore merging the PowerPC functionality in
with the default implementation in varasm.c -- either with an explicit
"pic" argument or modifying flag_pic around the calls.
None of the larger, intrusive patches are open for discussion for
GCC 3.3.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-30 8:42 ` David Edelsohn
2002-08-30 11:17 ` Franz Sirl
@ 2002-08-30 17:32 ` Alan Modra
2002-08-30 18:17 ` Richard Henderson
1 sibling, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-08-30 17:32 UTC (permalink / raw)
To: David Edelsohn; +Cc: Richard Henderson, Franz Sirl, Geoff Keating, gcc-patches
On Fri, Aug 30, 2002 at 11:27:25AM -0400, David Edelsohn wrote:
> >>>>> Alan Modra writes:
>
> Alan> Uh, oh. If I understand binds_local_p and mark_constant_function
> Alan> correctly, setting flag_pic is actually a bug-fix when compiling
> Alan> powerpc64-linux shared libs. We have the standard ELF binding of
> Alan> global syms. That is, global functions may be overridden by functions
> Alan> in another shared library or by the main application.
>
> Alan> So powerpc64-linux-gcc should allow -fpic/PIC to twiddle flag_pic for
> Alan> binds_local_p, and users should set -fPIC when compiling shared libs
> Alan> as is common on other ELF targets. We could use another flag, because
> Alan> like that annoying rs6000.c warning says "all code is position
> Alan> independent" on ppc64, but that would make powerpc64-linux just that
> Alan> more odd. Lots of packages set -fPIC to mean "compile me code for a
> Alan> shared library".
>
> This is what the patch that I applied to both gcc-3.2 and the
> trunk already does, without utilizing the generic infrastructure. The
> PowerPC port currently does not use the targetm.binds_local_p. We can
> discuss evolving to the generic infrastructure for GCC 3.4.
The PowerPC back-end code doesn't use binds_local_p, but
mark_constant_function does.
I think I'm correct in claiming that powerpc64-linux-gcc lacks a way
to say "I want this code compiled for a shared library; Don't try to
analyze global functions for pure/const as the function in this file
may not be the one called at runtime."
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-30 17:32 ` Alan Modra
@ 2002-08-30 18:17 ` Richard Henderson
2002-08-30 18:48 ` Geoff Keating
2002-09-02 15:41 ` [RFC] PowerPC select_section / unique_section David Edelsohn
0 siblings, 2 replies; 875+ messages in thread
From: Richard Henderson @ 2002-08-30 18:17 UTC (permalink / raw)
To: David Edelsohn, Franz Sirl, Geoff Keating, gcc-patches
On Sat, Aug 31, 2002 at 09:19:30AM +0930, Alan Modra wrote:
> The PowerPC back-end code doesn't use binds_local_p, but
> mark_constant_function does.
The inliner will use it in a moment as well. There's an outstanding
bug wrt -O3 that inlines functions that it shouldn't.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-30 18:17 ` Richard Henderson
@ 2002-08-30 18:48 ` Geoff Keating
2002-08-30 19:40 ` -finline-functions vs -fpic Richard Henderson
2002-09-02 15:41 ` [RFC] PowerPC select_section / unique_section David Edelsohn
1 sibling, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-08-30 18:48 UTC (permalink / raw)
To: rth; +Cc: dje, Franz.Sirl-kernel, gcc-patches
> Date: Fri, 30 Aug 2002 18:09:27 -0700
> From: Richard Henderson <rth@redhat.com>
> On Sat, Aug 31, 2002 at 09:19:30AM +0930, Alan Modra wrote:
> > The PowerPC back-end code doesn't use binds_local_p, but
> > mark_constant_function does.
>
> The inliner will use it in a moment as well. There's an outstanding
> bug wrt -O3 that inlines functions that it shouldn't.
FYI, I tried to fix this the obvious way,
Index: gcc/gcc/c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.349
diff -p -u -p -r1.349 c-decl.c
--- gcc/gcc/c-decl.c 21 Aug 2002 16:31:34 -0000 1.349
+++ gcc/gcc/c-decl.c 31 Aug 2002 01:33:02 -0000
@@ -4546,9 +4546,14 @@ grokdeclarator (declarator, declspecs, d
}
}
/* If -finline-functions, assume it can be inlined. This does
- two things: let the function be deferred until it is actually
- needed, and let dwarf2 know that the function is inlinable. */
- else if (flag_inline_trees == 2 && initialized)
+ two things: let the function be deferred until it is
+ actually needed, and let dwarf2 know that the function is
+ inlinable. Don't inline anything that might not actually
+ be this function from this file---this is done here because
+ if the user explicitly specifies 'inline' then we want to
+ inline anyway. */
+ else if (flag_inline_trees == 2 && initialized
+ && (*targetm.binds_local_p) (decl))
{
DECL_INLINE (decl) = 1;
DECL_DECLARED_INLINE_P (decl) = 0;
(and equivalently for C++) but this doesn't allow globally-visible
functions to be inlined when not -fpic on x86. Possibly this means
binds_local_p is wrong on x86.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* -finline-functions vs -fpic
2002-08-30 18:48 ` Geoff Keating
@ 2002-08-30 19:40 ` Richard Henderson
2002-08-30 20:57 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-08-30 19:40 UTC (permalink / raw)
To: Geoff Keating; +Cc: gcc-patches
On Fri, Aug 30, 2002 at 06:43:25PM -0700, Geoff Keating wrote:
> > The inliner will use it in a moment as well. There's an outstanding
> > bug wrt -O3 that inlines functions that it shouldn't.
>
> FYI, I tried to fix this the obvious way,
[...]
> (and equivalently for C++) but this doesn't allow globally-visible
> functions to be inlined when not -fpic on x86. Possibly this means
> binds_local_p is wrong on x86.
Nope. The decl isn't properly constructed yet. In particular,
DECL_EXTERNAL is still set, and won't be cleared until start_function.
I thought about moving where we set DECL_INLINE, or changing where
we set DECL_EXTERNAL, but the former didn't seem particularly clean,
and the later made me nervous.
The following, however, makes me happy. I'll fix up the C++ front
end similarly in a moment.
r~
* c-objc-common.c: Include target.h.
(c_cannot_inline_tree_fn): Don't auto-inline functions that
don't bind locally. Factor setting DECL_UNINLINABLE.
* Makefile.in (c-objc-common.o): Update.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.939
diff -c -p -d -r1.939 Makefile.in
*** Makefile.in 22 Aug 2002 04:29:34 -0000 1.939
--- Makefile.in 31 Aug 2002 02:21:22 -0000
*************** c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H
*** 1190,1196 ****
c-objc-common.o : c-objc-common.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
$(C_TREE_H) $(RTL_H) insn-config.h integrate.h $(EXPR_H) $(C_TREE_H) \
flags.h toplev.h tree-inline.h diagnostic.h integrate.h $(VARRAY_H) \
! langhooks.h $(GGC_H) gt-c-objc-common.h
c-aux-info.o : c-aux-info.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
flags.h toplev.h
c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h toplev.h \
--- 1190,1196 ----
c-objc-common.o : c-objc-common.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
$(C_TREE_H) $(RTL_H) insn-config.h integrate.h $(EXPR_H) $(C_TREE_H) \
flags.h toplev.h tree-inline.h diagnostic.h integrate.h $(VARRAY_H) \
! langhooks.h $(GGC_H) gt-c-objc-common.h $(TARGET_H)
c-aux-info.o : c-aux-info.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
flags.h toplev.h
c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h toplev.h \
Index: c-objc-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-objc-common.c,v
retrieving revision 1.15
diff -c -p -d -r1.15 c-objc-common.c
*** c-objc-common.c 16 Jul 2002 02:16:31 -0000 1.15
--- c-objc-common.c 31 Aug 2002 02:21:22 -0000
*************** Software Foundation, 59 Temple Place - S
*** 34,39 ****
--- 34,40 ----
#include "varray.h"
#include "ggc.h"
#include "langhooks.h"
+ #include "target.h"
static bool c_tree_printer PARAMS ((output_buffer *, text_info *));
static tree inline_forbidden_p PARAMS ((tree *, int *, void *));
*************** c_cannot_inline_tree_fn (fnp)
*** 150,160 ****
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
return 1;
if (! function_attribute_inlinable_p (fn))
! {
! DECL_UNINLINABLE (fn) = 1;
! return 1;
! }
/* If a function has pending sizes, we must not defer its
compilation, and we can't inline it as a tree. */
--- 151,163 ----
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
return 1;
+ /* Don't auto-inline anything that might not be bound within
+ this unit of translation. */
+ if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
+ goto cannot_inline;
+
if (! function_attribute_inlinable_p (fn))
! goto cannot_inline;
/* If a function has pending sizes, we must not defer its
compilation, and we can't inline it as a tree. */
*************** c_cannot_inline_tree_fn (fnp)
*** 164,173 ****
put_pending_sizes (t);
if (t)
! {
! DECL_UNINLINABLE (fn) = 1;
! return 1;
! }
}
if (DECL_CONTEXT (fn))
--- 167,173 ----
put_pending_sizes (t);
if (t)
! goto cannot_inline;
}
if (DECL_CONTEXT (fn))
*************** c_cannot_inline_tree_fn (fnp)
*** 175,184 ****
/* If a nested function has pending sizes, we may have already
saved them. */
if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
! {
! DECL_UNINLINABLE (fn) = 1;
! return 1;
! }
}
else
{
--- 175,181 ----
/* If a nested function has pending sizes, we may have already
saved them. */
if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
! goto cannot_inline;
}
else
{
*************** c_cannot_inline_tree_fn (fnp)
*** 201,212 ****
}
if (walk_tree (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn, NULL))
! {
! DECL_UNINLINABLE (fn) = 1;
! return 1;
! }
return 0;
}
/* Called from check_global_declarations. */
--- 198,210 ----
}
if (walk_tree (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn, NULL))
! goto cannot_inline;
return 0;
+
+ cannot_inline:
+ DECL_UNINLINABLE (fn) = 1;
+ return 1;
}
/* Called from check_global_declarations. */
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: -finline-functions vs -fpic
2002-08-30 19:40 ` -finline-functions vs -fpic Richard Henderson
@ 2002-08-30 20:57 ` Richard Henderson
0 siblings, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-08-30 20:57 UTC (permalink / raw)
To: gcc-patches
On Fri, Aug 30, 2002 at 07:28:33PM -0700, Richard Henderson wrote:
> The following, however, makes me happy. I'll fix up the C++ front
> end similarly in a moment.
Like so.
r~
* tree.c: Include target.h.
(cp_cannot_inline_tree_fn): Don't auto-inline functions that
don't bind locally.
* Makefile.in (tree.o): Update.
Index: cp/Make-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/Make-lang.in,v
retrieving revision 1.121
diff -c -p -d -r1.121 Make-lang.in
*** cp/Make-lang.in 8 Aug 2002 09:10:36 -0000 1.121
--- cp/Make-lang.in 31 Aug 2002 02:36:15 -0000
*************** cp/method.o: cp/method.c $(CXX_TREE_H) t
*** 280,286 ****
cp/cvt.o: cp/cvt.c $(CXX_TREE_H) cp/decl.h flags.h toplev.h convert.h
cp/search.o: cp/search.c $(CXX_TREE_H) stack.h flags.h toplev.h $(RTL_H)
cp/tree.o: cp/tree.c $(CXX_TREE_H) flags.h toplev.h $(GGC_H) $(RTL_H) \
! insn-config.h integrate.h tree-inline.h real.h gt-cp-tree.h
cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(SYSTEM_H)
cp/rtti.o: cp/rtti.c $(CXX_TREE_H) flags.h toplev.h
cp/except.o: cp/except.c $(CXX_TREE_H) flags.h $(RTL_H) except.h toplev.h \
--- 280,286 ----
cp/cvt.o: cp/cvt.c $(CXX_TREE_H) cp/decl.h flags.h toplev.h convert.h
cp/search.o: cp/search.c $(CXX_TREE_H) stack.h flags.h toplev.h $(RTL_H)
cp/tree.o: cp/tree.c $(CXX_TREE_H) flags.h toplev.h $(GGC_H) $(RTL_H) \
! insn-config.h integrate.h tree-inline.h real.h gt-cp-tree.h $(TARGET_H)
cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(SYSTEM_H)
cp/rtti.o: cp/rtti.c $(CXX_TREE_H) flags.h toplev.h
cp/except.o: cp/except.c $(CXX_TREE_H) flags.h $(RTL_H) except.h toplev.h \
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.296
diff -c -p -d -r1.296 tree.c
*** cp/tree.c 25 Aug 2002 04:57:15 -0000 1.296
--- cp/tree.c 31 Aug 2002 02:36:15 -0000
*************** Boston, MA 02111-1307, USA. */
*** 32,37 ****
--- 32,38 ----
#include "insn-config.h"
#include "integrate.h"
#include "tree-inline.h"
+ #include "target.h"
static tree bot_manip PARAMS ((tree *, int *, void *));
static tree bot_replace PARAMS ((tree *, int *, void *));
*************** cp_cannot_inline_tree_fn (fnp)
*** 2209,2214 ****
--- 2210,2223 ----
fn = *fnp = instantiate_decl (fn, /*defer_ok=*/0);
if (TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
return 1;
+ }
+
+ /* Don't auto-inline anything that might not be bound within
+ this unit of translation. */
+ if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
+ {
+ DECL_UNINLINABLE (fn) = 1;
+ return 1;
}
if (varargs_function_p (fn))
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-08-30 18:17 ` Richard Henderson
2002-08-30 18:48 ` Geoff Keating
@ 2002-09-02 15:41 ` David Edelsohn
2002-09-02 16:32 ` Alan Modra
1 sibling, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-09-02 15:41 UTC (permalink / raw)
To: Richard Henderson, Alan Modra, Franz Sirl, Geoff Keating; +Cc: gcc-patches
>>>>> Richard Henderson writes:
Richard> The inliner will use it in a moment as well. There's an outstanding
Richard> bug wrt -O3 that inlines functions that it shouldn't.
Either this is a bug which needs to be fixed in GCC 3.2/3.3 or can
wait until GCC 3.4.
If this needs to be fixed in GCC 3.2/3.3, then either it can be
fixed by tweaking the current PowerPC-specific functions or we need to
extend the default functionality in varasm.c so that the PowerPC port can
tie into it.
I am happy to help extend the current varasm.c infrastructure for
the PowerPC port to use in the GCC 3.3 release. I do not believe that
creating yet another different, private set of functions in rs6000.c for
the PowerPC port (even in the short term) is necessary or a good strategy.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-02 15:41 ` [RFC] PowerPC select_section / unique_section David Edelsohn
@ 2002-09-02 16:32 ` Alan Modra
2002-09-02 16:51 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-09-02 16:32 UTC (permalink / raw)
To: David Edelsohn; +Cc: Richard Henderson, Franz Sirl, Geoff Keating, gcc-patches
You can simply allow -fpic to be accepted by ppc64 gcc, and qualify
all the occurrences of flag_pic in rs6000/* with a test on
DEFAULT_ABI. No special private functions, no modifications to
varasm.c, and as a bonus, a reduction in the size of rs6000.o.
We (linux people) need a flag to say "build for a shared library".
Too many packages use -fpic for this purpose to warrant choosing
some other flag for PowerPC64.
As I said before, I have a patch that does this but David curtly
told me, without explanation, "Don't bother" posting it.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-02 16:32 ` Alan Modra
@ 2002-09-02 16:51 ` David Edelsohn
2002-09-02 17:13 ` Alan Modra
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-09-02 16:51 UTC (permalink / raw)
To: Alan Modra; +Cc: Richard Henderson, Franz Sirl, Geoff Keating, gcc-patches
Again, no one has said what is incorrect about about GCC's current
code generation, other than Richard's report about inlining and -O3. Not
what is inefficient, but what produces incorrect code.
GCC targeted for AIX and linuxppc64 currently always should
produce code appropriate for shared libraries, with the most recent
changes, other than the problem reported above. If GCC should produce
different code without -fpic, that is a different question and not a bug.
Alan> We (linux people) need a flag to say "build for a shared library".
You have not justified this statement.
All I have seen so far is a bunch of proposed patches and
assumptions without analysis (other than Richard). When I see a report of
an actual problem, then we can discuss how to solve it, not patches in
search of a bug.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-02 16:51 ` David Edelsohn
@ 2002-09-02 17:13 ` Alan Modra
2002-09-02 17:57 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-09-02 17:13 UTC (permalink / raw)
To: David Edelsohn; +Cc: Richard Henderson, Franz Sirl, Geoff Keating, gcc-patches
On Mon, Sep 02, 2002 at 07:51:07PM -0400, David Edelsohn wrote:
> Alan> We (linux people) need a flag to say "build for a shared library".
>
> You have not justified this statement.
See http://gcc.gnu.org/ml/gcc-patches/2002-08/msg01821.html
Note "global functions may be overridden". A silly example, but gcc
cannot optimize the calls to foo in the following if this code appears
in an ELF shared library, as the actual foo called might do something
completely different, like open an emacs window.
int foo (void)
{
return 0;
}
int bar (void)
{
return foo () + foo ();
}
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-02 17:13 ` Alan Modra
@ 2002-09-02 17:57 ` David Edelsohn
2002-09-02 18:27 ` Alan Modra
2002-09-03 8:41 ` Geoff Keating
0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2002-09-02 17:57 UTC (permalink / raw)
To: Alan Modra, Richard Henderson; +Cc: Franz Sirl, Geoff Keating, gcc-patches
To fix the need for GCC to know that it is compiling in PIC mode,
the linuxppc64 and AIX targets can:
1) allow flag_pic to be set on the commandline (creating an artificial
distinction between PIC and non-PIC object files), or
2) uniformly set flag_pic (creating problems because of the other uses of
flag_pic in the compiler), or
3) set and unset flag_pic around calls to the select section and
default_binds_local_p functions, or
4) modify the default select section and default_binds_local_p functions
to accept a "pic" argument (and override targetm.binds_local_p for
PowerPC).
I prefer option 4 to allow finer-grained control, allow greater
compiler optimization opportunities, and use better programming practice.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-02 17:57 ` David Edelsohn
@ 2002-09-02 18:27 ` Alan Modra
2002-09-02 18:49 ` David Edelsohn
` (2 more replies)
2002-09-03 8:41 ` Geoff Keating
1 sibling, 3 replies; 875+ messages in thread
From: Alan Modra @ 2002-09-02 18:27 UTC (permalink / raw)
To: David Edelsohn; +Cc: Richard Henderson, Franz Sirl, Geoff Keating, gcc-patches
On Mon, Sep 02, 2002 at 08:57:31PM -0400, David Edelsohn wrote:
> To fix the need for GCC to know that it is compiling in PIC mode,
> the linuxppc64 and AIX targets can:
>
> 1) allow flag_pic to be set on the commandline (creating an artificial
> distinction between PIC and non-PIC object files), or
This is the one we want. In our case -fpic doesn't mean "position
independent code", as we're always that sort of PIC. Instead it just
means create code for shared library linking semantics. Note that
-fpic means both PIC code _and_ shared library code generation on
other targets. Which is perhaps unfortunate as they are really two
separate issues.
> 2) uniformly set flag_pic (creating problems because of the other uses of
> flag_pic in the compiler), or
No, because then you lose optimization opportunities, as rth pointed
out.
> 3) set and unset flag_pic around calls to the select section and
> default_binds_local_p functions, or
>
> 4) modify the default select section and default_binds_local_p functions
> to accept a "pic" argument (and override targetm.binds_local_p for
> PowerPC).
>
> I prefer option 4 to allow finer-grained control, allow greater
> compiler optimization opportunities, and use better programming practice.
3) and 4) don't address how gcc should be told to generate code for
shared libraries. You seem to be assuming some flag other than -fpic
would be used.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-02 18:27 ` Alan Modra
@ 2002-09-02 18:49 ` David Edelsohn
2002-09-02 19:41 ` Alan Modra
2002-09-02 20:17 ` Richard Henderson
2002-09-02 20:11 ` Jeff Sturm
2002-09-03 9:29 ` Mark Mitchell
2 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2002-09-02 18:49 UTC (permalink / raw)
To: Alan Modra; +Cc: Richard Henderson, Franz Sirl, Geoff Keating, gcc-patches
>>>>> Alan Modra writes:
Alan> 3) and 4) don't address how gcc should be told to generate code for
Alan> shared libraries. You seem to be assuming some flag other than -fpic
Alan> would be used.
I am not assuming any additional flags.
The question is whether we ever need to distinguish between code
generation for shared libraries and code generation for regular object
files. AIX compilers never make any distinction.
AIX default to tight binding within shared objects, but AIX 4.2
and above added the runtime-linking flag to allow SVR4-type symbol
overriding. No changes have been necessary to IBM's compilers or to GCC
to support this. There is no "prepare for runtime-linking" compiler
option.
GCC always accesses globals through the TOC and always calls
public functions through glue, so symbols always can be overridden -- at
least until the recent binds_local_p changes.
It is not obvious that GCC should behave differently for shared
libraries and regular object files when targeting ABI_AIX.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-02 18:49 ` David Edelsohn
@ 2002-09-02 19:41 ` Alan Modra
2002-09-02 19:59 ` David Edelsohn
2002-09-02 20:17 ` Richard Henderson
1 sibling, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-09-02 19:41 UTC (permalink / raw)
To: David Edelsohn; +Cc: Richard Henderson, Franz Sirl, Geoff Keating, gcc-patches
On Mon, Sep 02, 2002 at 09:49:11PM -0400, David Edelsohn wrote:
> It is not obvious that GCC should behave differently for shared
> libraries and regular object files when targeting ABI_AIX.
I don't know how to make it any more obvious to you. Do you disagree
with:
1) Current mainline powerpc64-linux gcc, in the face of inlining and
const function folding optimizations, is broken when building
shared libraries.
2) Therefore these optimizations must be turned off when building
shared libraries.
3) If shared and regular objects are to be built the same, then these
optimizations must be turned off for regular objects too.
You may make the decision that AIX gcc doesn't need these
optimizations, but please don't hobble PowerPC64 Linux.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-02 19:41 ` Alan Modra
@ 2002-09-02 19:59 ` David Edelsohn
0 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-09-02 19:59 UTC (permalink / raw)
To: Alan Modra; +Cc: Richard Henderson, Franz Sirl, Geoff Keating, gcc-patches
>>>>> Alan Modra writes:
Alan> You may make the decision that AIX gcc doesn't need these
Alan> optimizations, but please don't hobble PowerPC64 Linux.
Please tone it down and stop making this personal.
This type of decision needs input from others, including other
experts on calling conventions and compilers within IBM.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-02 18:27 ` Alan Modra
2002-09-02 18:49 ` David Edelsohn
@ 2002-09-02 20:11 ` Jeff Sturm
2002-09-02 20:19 ` David Edelsohn
2002-09-03 9:29 ` Mark Mitchell
2 siblings, 1 reply; 875+ messages in thread
From: Jeff Sturm @ 2002-09-02 20:11 UTC (permalink / raw)
To: Alan Modra
Cc: David Edelsohn, Richard Henderson, Franz Sirl, Geoff Keating,
gcc-patches
On Tue, 3 Sep 2002, Alan Modra wrote:
> Note that -fpic means both PIC code _and_ shared library code generation
> on other targets.
Some targets. Unless I'm very mistaken, all code is PIC on alpha, so that
-fPIC has little effect apart from binds_local_p.
Irrespective of PPC, wouldn't it be a desirable to have uniformity across
GNU/Linux targets over this issue?
Jeff
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-02 18:49 ` David Edelsohn
2002-09-02 19:41 ` Alan Modra
@ 2002-09-02 20:17 ` Richard Henderson
1 sibling, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-09-02 20:17 UTC (permalink / raw)
To: David Edelsohn; +Cc: Alan Modra, Franz Sirl, Geoff Keating, gcc-patches
On Mon, Sep 02, 2002 at 09:49:11PM -0400, David Edelsohn wrote:
> GCC always accesses globals through the TOC and always calls
> public functions through glue, so symbols always can be overridden -- at
> least until the recent binds_local_p changes.
This is actually incorrect. Until the binds_local_p changes, various
parts of gcc did various checks (or not), somewhat at random. The
binds_local_p change "merely" centralizes the logic.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-02 20:11 ` Jeff Sturm
@ 2002-09-02 20:19 ` David Edelsohn
2002-09-03 0:16 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-09-02 20:19 UTC (permalink / raw)
To: Jeff Sturm
Cc: Alan Modra, Richard Henderson, Franz Sirl, Geoff Keating, gcc-patches
>>>>> Jeff Sturm writes:
Jeff> Some targets. Unless I'm very mistaken, all code is PIC on alpha, so that
Jeff> -fPIC has little effect apart from binds_local_p.
Jeff> Irrespective of PPC, wouldn't it be a desirable to have uniformity across
Jeff> GNU/Linux targets over this issue?
Which seems like a good argument for default_binds_local_p and
others using a "pic" function parameter instead of grabbing the global
flag_pic. This would allow -fpic/-fPIC to affect targetm.binds_local_p
while not affecting the other functions.
For instance, rs6000_override_options could reset the GCC global
flag_pic to zero while remembering the original value privately and then
using that value to affect binds_local_p.
These uses of flag_pic seem like orthogonal decisions to me and
ports should have finer-grained control only available if binds_local_p
and select_section accept arguments.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-02 20:19 ` David Edelsohn
@ 2002-09-03 0:16 ` Richard Henderson
2002-09-03 8:22 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-09-03 0:16 UTC (permalink / raw)
To: David Edelsohn
Cc: Jeff Sturm, Alan Modra, Franz Sirl, Geoff Keating, gcc-patches
On Mon, Sep 02, 2002 at 11:19:11PM -0400, David Edelsohn wrote:
> Jeff> Some targets. Unless I'm very mistaken, all code is PIC on alpha,
> Jeff> so that -fPIC has little effect apart from binds_local_p.
Well, it also changes what sections data with relocations are placed in.
But I think you underestimate what effect binds_local_p has -- variables
that are known to be local are addressed with gp-relative relocations
instead of through the got, calls within the same UOT use bsr, etc.
> Jeff> Irrespective of PPC, wouldn't it be a desirable to have uniformity
> Jeff> across GNU/Linux targets over this issue?
Yes. But aside from PPC, I think we largely have that already.
> Which seems like a good argument for default_binds_local_p and
> others using a "pic" function parameter instead of grabbing the global
> flag_pic. This would allow -fpic/-fPIC to affect targetm.binds_local_p
> while not affecting the other functions.
I don't see how that follows. In fact, I think that would simply
be confusing to the many places that want to call binds_local_p.
I would be willing to extract the bulk of default_binds_local_p
into a default_binds_local_p_1 that did have a "shlib" parameter,
and similar for select_section, but I don't want the choice of
what value of flag_pic to pass to binds_local_p to reside at all
of the call sites.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-03 0:16 ` Richard Henderson
@ 2002-09-03 8:22 ` David Edelsohn
2002-09-03 9:04 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-09-03 8:22 UTC (permalink / raw)
To: Richard Henderson
Cc: Jeff Sturm, Alan Modra, Franz Sirl, Geoff Keating, gcc-patches
>>>>> Richard Henderson writes:
Richard> I would be willing to extract the bulk of default_binds_local_p
Richard> into a default_binds_local_p_1 that did have a "shlib" parameter,
Richard> and similar for select_section, but I don't want the choice of
Richard> what value of flag_pic to pass to binds_local_p to reside at all
Richard> of the call sites.
Like the appended patch?
Do you want all of the default_* functions wrapped around a
default_*_1 function instead of adding flag_pic at the call sites?
Thanks, David
* varasm.c (default_binds_local_p): Rename as
default_binds_local_p_1 with shlib parameter. Use original name
to call new function with flag_pic.
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.303
diff -c -p -r1.303 varasm.c
*** varasm.c 21 Aug 2002 02:41:44 -0000 1.303
--- varasm.c 3 Sep 2002 15:15:36 -0000
*************** default_strip_name_encoding (str)
*** 5202,5209 ****
wrt cross-module name binding. */
bool
! default_binds_local_p (exp)
tree exp;
{
bool local_p;
--- 5205,5213 ----
wrt cross-module name binding. */
bool
! default_binds_local_p_1 (exp, shlib)
tree exp;
+ int shlib;
{
bool local_p;
*************** default_binds_local_p (exp)
*** 5224,5230 ****
local_p = false;
/* If PIC, then assume that any global name can be overridden by
symbols resolved from other modules. */
! else if (flag_pic)
local_p = false;
/* Uninitialized COMMON variable may be unified with symbols
resolved from other modules. */
--- 5228,5234 ----
local_p = false;
/* If PIC, then assume that any global name can be overridden by
symbols resolved from other modules. */
! else if (shlib)
local_p = false;
/* Uninitialized COMMON variable may be unified with symbols
resolved from other modules. */
*************** default_binds_local_p (exp)
*** 5238,5243 ****
--- 5242,5254 ----
local_p = true;
return local_p;
+ }
+
+ bool
+ default_binds_local_p (exp)
+ tree exp;
+ {
+ return default_binds_local_p (exp, flag_pic);
}
/* Default function to output code that will globalize a label. A
Index: output.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/output.h,v
retrieving revision 1.109
diff -c -p -r1.109 output.h
*** output.h 21 Aug 2002 02:41:44 -0000 1.109
--- output.h 3 Sep 2002 15:15:37 -0000
*************** extern void default_elf_select_rtx_secti
*** 537,542 ****
--- 537,543 ----
unsigned HOST_WIDE_INT));
extern const char *default_strip_name_encoding PARAMS ((const char *));
extern bool default_binds_local_p PARAMS ((tree));
+ extern bool default_binds_local_p_1 PARAMS ((tree, int));
extern void default_globalize_label PARAMS ((FILE *, const char *));
/* Emit data for vtable gc for GNU binutils. */
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-02 17:57 ` David Edelsohn
2002-09-02 18:27 ` Alan Modra
@ 2002-09-03 8:41 ` Geoff Keating
2002-09-03 9:50 ` David Edelsohn
1 sibling, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2002-09-03 8:41 UTC (permalink / raw)
To: dje; +Cc: amodra, rth, Franz.Sirl-kernel, gcc-patches
> X-Sieve: cmu-sieve 2.0
> cc: Franz Sirl <Franz.Sirl-kernel@lauterbach.com>,
> Geoff Keating <geoffk@redhat.com>, gcc-patches@gcc.gnu.org
> Date: Mon, 02 Sep 2002 20:57:31 -0400
> From: David Edelsohn <dje@watson.ibm.com>
>
> To fix the need for GCC to know that it is compiling in PIC mode,
> the linuxppc64 and AIX targets can:
Do you need to do this for AIX? I thought the symbol binding rules
for AIX shared libraries were different, they didn't permit overriding
a symbol in a shared library.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-03 8:22 ` David Edelsohn
@ 2002-09-03 9:04 ` Richard Henderson
2002-09-03 10:40 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-09-03 9:04 UTC (permalink / raw)
To: David Edelsohn
Cc: Jeff Sturm, Alan Modra, Franz Sirl, Geoff Keating, gcc-patches
On Tue, Sep 03, 2002 at 11:21:18AM -0400, David Edelsohn wrote:
> Like the appended patch?
Yes, thanks.
> Do you want all of the default_* functions wrapped around a
> default_*_1 function instead of adding flag_pic at the call sites?
I think so, yes.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-02 18:27 ` Alan Modra
2002-09-02 18:49 ` David Edelsohn
2002-09-02 20:11 ` Jeff Sturm
@ 2002-09-03 9:29 ` Mark Mitchell
2 siblings, 0 replies; 875+ messages in thread
From: Mark Mitchell @ 2002-09-03 9:29 UTC (permalink / raw)
To: Alan Modra, David Edelsohn
Cc: Richard Henderson, Franz Sirl, Geoff Keating, gcc-patches
--On Tuesday, September 03, 2002 10:57:54 AM +0930 Alan Modra
<amodra@bigpond.net.au> wrote:
> On Mon, Sep 02, 2002 at 08:57:31PM -0400, David Edelsohn wrote:
>> To fix the need for GCC to know that it is compiling in PIC mode,
>> the linuxppc64 and AIX targets can:
>>
>> 1) allow flag_pic to be set on the commandline (creating an artificial
>> distinction between PIC and non-PIC object files), or
>
> This is the one we want. In our case -fpic doesn't mean "position
> independent code", as we're always that sort of PIC. Instead it just
> means create code for shared library linking semantics. Note that
> -fpic means both PIC code _and_ shared library code generation on
> other targets. Which is perhaps unfortunate as they are really two
> separate issues.
So why not fix this?
Add -fshared-lib, and have -fpic turn it on. Then, test flag_shared_lib
where you mean that, and flag_pic where you mean that. There's no
compatibility problem for existing code, and on systems where the two
ideas are different, people now have a way of saying which mode they
want.
(You have to notice -fpic -fno_pic which now means something different
than it did before, and warn about that, but that will be a rare case.)
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-03 8:41 ` Geoff Keating
@ 2002-09-03 9:50 ` David Edelsohn
0 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-09-03 9:50 UTC (permalink / raw)
To: Geoff Keating; +Cc: amodra, rth, Franz.Sirl-kernel, gcc-patches
>>>>> Geoff Keating writes:
Geoff> Do you need to do this for AIX? I thought the symbol binding rules
Geoff> for AIX shared libraries were different, they didn't permit overriding
Geoff> a symbol in a shared library.
Because AIX does support a run-time linking mode, this could be an
issue. IBM's compilers currently do not change their code generation to
make this easier or more difficult.
The two issues for both AIX and linuxppc64 are placing certain
types of data in writeable versus read-only sections and the ability to
interpose functions (binds_local_p).
My current belief is that AIX and linuxppc64 always should default
to PIC and shareable, and that -fpic should only affect binds_local_p to
ensure that symbols can be interposed. The 64-bit PowerPC SVR4 ABI
already does have a non-PIC mode which GCC does not generate, so having a
non-PIC mode for PIC code would add confusion. Some of the choice of
sections depends on the PowerPC architecture and how best to utilize it.
I don't think that any policy change from the current defaults
should be made without a lot more investigation -- which I am doing.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-03 9:04 ` Richard Henderson
@ 2002-09-03 10:40 ` David Edelsohn
2002-09-03 13:44 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2002-09-03 10:40 UTC (permalink / raw)
To: Richard Henderson
Cc: Jeff Sturm, Alan Modra, Franz Sirl, Geoff Keating, gcc-patches
>>>>> Richard Henderson writes:
>> Do you want all of the default_* functions wrapped around a
>> default_*_1 function instead of adding flag_pic at the call sites?
Richard> I think so, yes.
How about the following patch? Then we can move on to integrating
sdata.
Thanks, David
* varasm.c (default_section_type_flags): Append _1 to name with
shlib parameter. Use original name to call new function with
implicit flag_pic.
(decl_readonly_section): Likewise.
(default_elf_select_section): Likewise.
(default_unique_section): Likewise.
(default_bind_local_p): Likewise.
(categorize_decl_for_section): Add shlib parameter to use in place
of implicit flag_pic.
* output.h: Declare new functions with _1 and shlib argument.
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.303
diff -c -p -r1.303 varasm.c
*** varasm.c 21 Aug 2002 02:41:44 -0000 1.303
--- varasm.c 3 Sep 2002 17:29:08 -0000
*************** init_varasm_once ()
*** 4686,4701 ****
read-only for a const data decl, and writable for a non-const data decl. */
unsigned int
! default_section_type_flags (decl, name, reloc)
tree decl;
const char *name;
int reloc;
{
unsigned int flags;
if (decl && TREE_CODE (decl) == FUNCTION_DECL)
flags = SECTION_CODE;
! else if (decl && decl_readonly_section (decl, reloc))
flags = 0;
else
flags = SECTION_WRITE;
--- 4686,4702 ----
read-only for a const data decl, and writable for a non-const data decl. */
unsigned int
! default_section_type_flags_1 (decl, name, reloc, shlib)
tree decl;
const char *name;
int reloc;
+ int shlib;
{
unsigned int flags;
if (decl && TREE_CODE (decl) == FUNCTION_DECL)
flags = SECTION_CODE;
! else if (decl && decl_readonly_section_1 (decl, reloc, shlib))
flags = 0;
else
flags = SECTION_WRITE;
*************** default_section_type_flags (decl, name,
*** 4725,4730 ****
--- 4726,4740 ----
return flags;
}
+ unsigned int
+ default_section_type_flags (decl, name, reloc)
+ tree decl;
+ const char *name;
+ int reloc;
+ {
+ return default_section_type_flags_1 (decl, name, reloc, flag_pic);
+ }
+
/* Output assembly to switch to section NAME with attribute FLAGS.
Four variants for common object file formats. */
*************** enum section_category
*** 4913,4924 ****
SECCAT_TBSS
};
! static enum section_category categorize_decl_for_section PARAMS ((tree, int));
static enum section_category
! categorize_decl_for_section (decl, reloc)
tree decl;
int reloc;
{
enum section_category ret;
--- 4923,4936 ----
SECCAT_TBSS
};
! static enum section_category
! categorize_decl_for_section PARAMS ((tree, int, int));
static enum section_category
! categorize_decl_for_section (decl, reloc, shlib)
tree decl;
int reloc;
+ int shlib;
{
enum section_category ret;
*************** categorize_decl_for_section (decl, reloc
*** 4940,4955 ****
|| TREE_SIDE_EFFECTS (decl)
|| ! TREE_CONSTANT (DECL_INITIAL (decl)))
{
! if (flag_pic && (reloc & 2))
ret = SECCAT_DATA_REL;
! else if (flag_pic && reloc)
ret = SECCAT_DATA_REL_LOCAL;
else
ret = SECCAT_DATA;
}
! else if (flag_pic && (reloc & 2))
ret = SECCAT_DATA_REL_RO;
! else if (flag_pic && reloc)
ret = SECCAT_DATA_REL_RO_LOCAL;
else if (flag_merge_constants < 2)
/* C and C++ don't allow different variables to share the same
--- 4952,4967 ----
|| TREE_SIDE_EFFECTS (decl)
|| ! TREE_CONSTANT (DECL_INITIAL (decl)))
{
! if (shlib && (reloc & 2))
ret = SECCAT_DATA_REL;
! else if (shlib && reloc)
ret = SECCAT_DATA_REL_LOCAL;
else
ret = SECCAT_DATA;
}
! else if (shlib && (reloc & 2))
ret = SECCAT_DATA_REL_RO;
! else if (shlib && reloc)
ret = SECCAT_DATA_REL_RO_LOCAL;
else if (flag_merge_constants < 2)
/* C and C++ don't allow different variables to share the same
*************** categorize_decl_for_section (decl, reloc
*** 4963,4969 ****
}
else if (TREE_CODE (decl) == CONSTRUCTOR)
{
! if ((flag_pic && reloc)
|| TREE_SIDE_EFFECTS (decl)
|| ! TREE_CONSTANT (decl))
ret = SECCAT_DATA;
--- 4975,4981 ----
}
else if (TREE_CODE (decl) == CONSTRUCTOR)
{
! if ((shlib && reloc)
|| TREE_SIDE_EFFECTS (decl)
|| ! TREE_CONSTANT (decl))
ret = SECCAT_DATA;
*************** categorize_decl_for_section (decl, reloc
*** 4995,5005 ****
}
bool
! decl_readonly_section (decl, reloc)
tree decl;
int reloc;
{
! switch (categorize_decl_for_section (decl, reloc))
{
case SECCAT_RODATA:
case SECCAT_RODATA_MERGE_STR:
--- 5007,5018 ----
}
bool
! decl_readonly_section_1 (decl, reloc, shlib)
tree decl;
int reloc;
+ int shlib;
{
! switch (categorize_decl_for_section (decl, reloc, shlib))
{
case SECCAT_RODATA:
case SECCAT_RODATA_MERGE_STR:
*************** decl_readonly_section (decl, reloc)
*** 5013,5027 ****
}
}
/* Select a section based on the above categorization. */
void
! default_elf_select_section (decl, reloc, align)
tree decl;
int reloc;
unsigned HOST_WIDE_INT align;
{
! switch (categorize_decl_for_section (decl, reloc))
{
case SECCAT_TEXT:
/* We're not supposed to be called on FUNCTION_DECLs. */
--- 5026,5049 ----
}
}
+ bool
+ decl_readonly_section (decl, reloc)
+ tree decl;
+ int reloc;
+ {
+ return decl_readonly_section_1 (decl, reloc, flag_pic);
+ }
+
/* Select a section based on the above categorization. */
void
! default_elf_select_section_1 (decl, reloc, align, shlib)
tree decl;
int reloc;
unsigned HOST_WIDE_INT align;
+ int shlib;
{
! switch (categorize_decl_for_section (decl, reloc, shlib))
{
case SECCAT_TEXT:
/* We're not supposed to be called on FUNCTION_DECLs. */
*************** default_elf_select_section (decl, reloc,
*** 5077,5096 ****
}
}
/* Construct a unique section name based on the decl name and the
categorization performed above. */
void
! default_unique_section (decl, reloc)
tree decl;
int reloc;
{
bool one_only = DECL_ONE_ONLY (decl);
const char *prefix, *name;
size_t nlen, plen;
char *string;
! switch (categorize_decl_for_section (decl, reloc))
{
case SECCAT_TEXT:
prefix = one_only ? ".gnu.linkonce.t." : ".text.";
--- 5099,5128 ----
}
}
+ void
+ default_elf_select_section (decl, reloc, align)
+ tree decl;
+ int reloc;
+ unsigned HOST_WIDE_INT align;
+ {
+ return default_elf_select_section_1 (decl, reloc, align, flag_pic);
+ }
+
/* Construct a unique section name based on the decl name and the
categorization performed above. */
void
! default_unique_section_1 (decl, reloc, shlib)
tree decl;
int reloc;
+ int shlib;
{
bool one_only = DECL_ONE_ONLY (decl);
const char *prefix, *name;
size_t nlen, plen;
char *string;
! switch (categorize_decl_for_section (decl, reloc, shlib))
{
case SECCAT_TEXT:
prefix = one_only ? ".gnu.linkonce.t." : ".text.";
*************** default_unique_section (decl, reloc)
*** 5140,5145 ****
--- 5172,5185 ----
}
void
+ default_unique_section (decl, reloc)
+ tree decl;
+ int reloc;
+ {
+ return default_unique_section_1 (decl, reloc, flag_pic);
+ }
+
+ void
default_select_rtx_section (mode, x, align)
enum machine_mode mode ATTRIBUTE_UNUSED;
rtx x;
*************** default_strip_name_encoding (str)
*** 5202,5209 ****
wrt cross-module name binding. */
bool
! default_binds_local_p (exp)
tree exp;
{
bool local_p;
--- 5242,5250 ----
wrt cross-module name binding. */
bool
! default_binds_local_p_1 (exp, shlib)
tree exp;
+ int shlib;
{
bool local_p;
*************** default_binds_local_p (exp)
*** 5224,5230 ****
local_p = false;
/* If PIC, then assume that any global name can be overridden by
symbols resolved from other modules. */
! else if (flag_pic)
local_p = false;
/* Uninitialized COMMON variable may be unified with symbols
resolved from other modules. */
--- 5265,5271 ----
local_p = false;
/* If PIC, then assume that any global name can be overridden by
symbols resolved from other modules. */
! else if (shlib)
local_p = false;
/* Uninitialized COMMON variable may be unified with symbols
resolved from other modules. */
*************** default_binds_local_p (exp)
*** 5238,5243 ****
--- 5279,5291 ----
local_p = true;
return local_p;
+ }
+
+ bool
+ default_binds_local_p (exp)
+ tree exp;
+ {
+ return default_binds_local_p (exp, flag_pic);
}
/* Default function to output code that will globalize a label. A
Index: output.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/output.h,v
retrieving revision 1.109
diff -c -p -r1.109 output.h
*** output.h 21 Aug 2002 02:41:44 -0000 1.109
--- output.h 3 Sep 2002 17:29:08 -0000
*************** extern rtx this_is_asm_operands;
*** 468,473 ****
--- 468,474 ----
/* Decide whether DECL needs to be in a writable section.
RELOC is the same as for SELECT_SECTION. */
extern bool decl_readonly_section PARAMS ((tree, int));
+ extern bool decl_readonly_section_1 PARAMS ((tree, int, int));
/* User label prefix in effect for this compilation. */
extern const char *user_label_prefix;
*************** extern bool named_section_first_declarat
*** 508,513 ****
--- 509,517 ----
union tree_node;
extern unsigned int default_section_type_flags PARAMS ((union tree_node *,
const char *, int));
+ extern unsigned int default_section_type_flags_1 PARAMS ((union tree_node *,
+ const char *,
+ int, int));
extern void default_no_named_section PARAMS ((const char *, unsigned int));
extern void default_elf_asm_named_section PARAMS ((const char *, unsigned int));
*************** extern void default_select_section PARAM
*** 530,542 ****
--- 534,550 ----
unsigned HOST_WIDE_INT));
extern void default_elf_select_section PARAMS ((tree, int,
unsigned HOST_WIDE_INT));
+ extern void default_elf_select_section_1 PARAMS ((tree, int,
+ unsigned HOST_WIDE_INT, int));
extern void default_unique_section PARAMS ((tree, int));
+ extern void default_unique_section_1 PARAMS ((tree, int, int));
extern void default_select_rtx_section PARAMS ((enum machine_mode, rtx,
unsigned HOST_WIDE_INT));
extern void default_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
unsigned HOST_WIDE_INT));
extern const char *default_strip_name_encoding PARAMS ((const char *));
extern bool default_binds_local_p PARAMS ((tree));
+ extern bool default_binds_local_p_1 PARAMS ((tree, int));
extern void default_globalize_label PARAMS ((FILE *, const char *));
/* Emit data for vtable gc for GNU binutils. */
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [RFC] PowerPC select_section / unique_section
2002-09-03 10:40 ` David Edelsohn
@ 2002-09-03 13:44 ` Richard Henderson
0 siblings, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2002-09-03 13:44 UTC (permalink / raw)
To: David Edelsohn
Cc: Jeff Sturm, Alan Modra, Franz Sirl, Geoff Keating, gcc-patches
On Tue, Sep 03, 2002 at 01:40:19PM -0400, David Edelsohn wrote:
> * varasm.c (default_section_type_flags): Append _1 to name with
> shlib parameter. Use original name to call new function with
> implicit flag_pic.
> (decl_readonly_section): Likewise.
> (default_elf_select_section): Likewise.
> (default_unique_section): Likewise.
> (default_bind_local_p): Likewise.
> (categorize_decl_for_section): Add shlib parameter to use in place
> of implicit flag_pic.
> * output.h: Declare new functions with _1 and shlib argument.
Ok.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: SYMBOL_REF_FLAG
[not found] ` <200209140219.WAA25730@makai.watson.ibm.com>
@ 2002-09-13 19:59 ` Alan Modra
2002-09-13 22:17 ` SYMBOL_REF_FLAG Richard Henderson
2002-09-14 0:01 ` SYMBOL_REF_FLAG David Edelsohn
0 siblings, 2 replies; 875+ messages in thread
From: Alan Modra @ 2002-09-13 19:59 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
On Fri, Sep 13, 2002 at 10:19:45PM -0400, David Edelsohn wrote:
> Yes, this should be changed in all locations.
OK here we go.
* config/rs6000/rs6000.c (rs6000_elf_encode_section_info): Use
targetm.binds_local_p to set SYMBOL_REF_FLAG.
(rs6000_xcoff_encode_section_info): Likewise.
(config/rs6000/xcoff.h): Likewise.
OK mainline? This should probably also be fixed on the gcc-3.2 branch,
and the flag_pic issue too. Alternatively, if that is too large a fix
for the branch to risk destabilizing rs6000-aix gcc, I can continue
putting such fixes in a patcheset for powerpc64-linux.
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.377
diff -u -p -r1.377 rs6000.c
--- gcc/config/rs6000/rs6000.c 13 Sep 2002 01:40:43 -0000 1.377
+++ gcc/config/rs6000/rs6000.c 14 Sep 2002 02:35:27 -0000
@@ -12424,8 +12424,7 @@ rs6000_elf_encode_section_info (decl, fi
if (TREE_CODE (decl) == FUNCTION_DECL)
{
rtx sym_ref = XEXP (DECL_RTL (decl), 0);
- if ((TREE_ASM_WRITTEN (decl) || ! TREE_PUBLIC (decl))
- && ! DECL_WEAK (decl))
+ if ((*targetm.binds_local_p) (decl))
SYMBOL_REF_FLAG (sym_ref) = 1;
if (DEFAULT_ABI == ABI_AIX)
@@ -13121,8 +13120,7 @@ rs6000_xcoff_encode_section_info (decl,
int first ATTRIBUTE_UNUSED;
{
if (TREE_CODE (decl) == FUNCTION_DECL
- && (TREE_ASM_WRITTEN (decl) || ! TREE_PUBLIC (decl))
- && ! DECL_WEAK (decl))
+ && (*targetm.binds_local_p) (decl))
SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
}
Index: gcc/config/rs6000/xcoff.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/xcoff.h,v
retrieving revision 1.36
diff -u -p -r1.36 xcoff.h
--- gcc/config/rs6000/xcoff.h 11 Sep 2002 17:36:06 -0000 1.36
+++ gcc/config/rs6000/xcoff.h 14 Sep 2002 02:47:20 -0000
@@ -266,7 +266,7 @@ toc_section () \
#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \
{ rtx sym_ref = XEXP (DECL_RTL (DECL), 0); \
- if (!DECL_WEAK (DECL)) \
+ if ((*targetm.binds_local_p) (DECL)) \
SYMBOL_REF_FLAG (sym_ref) = 1; \
if (TREE_PUBLIC (DECL)) \
{ \
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: SYMBOL_REF_FLAG
2002-09-13 19:59 ` SYMBOL_REF_FLAG Alan Modra
@ 2002-09-13 22:17 ` Richard Henderson
2002-09-14 0:09 ` SYMBOL_REF_FLAG David Edelsohn
2002-09-14 0:01 ` SYMBOL_REF_FLAG David Edelsohn
1 sibling, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2002-09-13 22:17 UTC (permalink / raw)
To: David Edelsohn, gcc-patches
On Sat, Sep 14, 2002 at 12:29:50PM +0930, Alan Modra wrote:
> This should probably also be fixed on the gcc-3.2 branch,
> and the flag_pic issue too.
3.2 doesn't have binds_local_p, so the fix is going to
be uglier by far.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: SYMBOL_REF_FLAG
2002-09-13 19:59 ` SYMBOL_REF_FLAG Alan Modra
2002-09-13 22:17 ` SYMBOL_REF_FLAG Richard Henderson
@ 2002-09-14 0:01 ` David Edelsohn
1 sibling, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-09-14 0:01 UTC (permalink / raw)
To: Alan Modra; +Cc: gcc-patches
* config/rs6000/rs6000.c (rs6000_elf_encode_section_info): Use
targetm.binds_local_p to set SYMBOL_REF_FLAG.
(rs6000_xcoff_encode_section_info): Likewise.
(config/rs6000/xcoff.h): Likewise.
Yes, this is okay.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: SYMBOL_REF_FLAG
2002-09-13 22:17 ` SYMBOL_REF_FLAG Richard Henderson
@ 2002-09-14 0:09 ` David Edelsohn
0 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-09-14 0:09 UTC (permalink / raw)
To: Alan Modra; +Cc: Richard Henderson, gcc-patches
I think the flag_pic issues require changes that are too invasive
to be fixed on the GCC 3.2 branch. There wasn't powerpc64-linux support
before, so it cannot be a regression. The flag_pic stuff needs to remain
as patches in the private source tree of backported GCC 3.3 functionality.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* powerpc fix for gcc.dg/asm-names.c failure
@ 2002-10-03 19:25 ` Alan Modra
2002-10-03 19:32 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2002-10-03 19:25 UTC (permalink / raw)
To: gcc-patches; +Cc: David Edelsohn
Fixes gcc.dg/asm-names.c failure on powerpc64. Stripping out '*' from
the function name too early meant that a duplicate label was emitted,
as asm-names.c has two "main" functions with different asm names.
Note that the traceback table still uses the C function name. I'm not
sure whether this needs changin too.
* config/rs6000/rs6000.c (rs6000_output_function_epilogue): Use a
name for the tbtab label that depends on the function asm name.
Don't output tbtab label unless optional_tbtab.
(output_mi_thunk): Formatting.
OK mainline? Bootstrapped and regression tested powerpc-linux,
xcompiled and regression tested powerpc64-linux.
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.387
diff -u -p -r1.387 rs6000.c
--- gcc/config/rs6000/rs6000.c 28 Sep 2002 15:29:44 -0000 1.387
+++ gcc/config/rs6000/rs6000.c 4 Oct 2002 00:43:11 -0000
@@ -10967,7 +10967,7 @@ rs6000_output_function_epilogue (file, s
if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
&& rs6000_traceback != traceback_none)
{
- const char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
+ const char *fname = NULL;
const char *language_string = lang_hooks.name;
int fixed_parms = 0, float_parms = 0, parm_info = 0;
int i;
@@ -10980,15 +10980,17 @@ rs6000_output_function_epilogue (file, s
else
optional_tbtab = !optimize_size && !TARGET_ELF;
- while (*fname == '.') /* V.4 encodes . in the name */
- fname++;
-
- /* Need label immediately before tbtab, so we can compute its offset
- from the function start. */
- if (*fname == '*')
- ++fname;
- ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
- ASM_OUTPUT_LABEL (file, fname);
+ if (optional_tbtab)
+ {
+ fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
+ while (*fname == '.') /* V.4 encodes . in the name */
+ fname++;
+
+ /* Need label immediately before tbtab, so we can compute
+ its offset from the function start. */
+ ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
+ ASM_OUTPUT_LABEL (file, fname);
+ }
/* The .tbtab pseudo-op can only be used for the first eight
expressions, since it can't handle the possibly variable
@@ -11160,6 +11162,8 @@ rs6000_output_function_epilogue (file, s
/* Omit this list of longs, because there are no CTL anchors. */
/* Length of function name. */
+ if (*fname == '*')
+ ++fname;
fprintf (file, "\t.short %d\n", (int) strlen (fname));
/* Function name. */
@@ -11285,7 +11289,6 @@ output_mi_thunk (file, thunk_fndecl, del
TYPE_ATTRIBUTES (TREE_TYPE (function)))
|| lookup_attribute ("shortcall",
TYPE_ATTRIBUTES (TREE_TYPE (function)))))
-
{
fprintf (file, "\tb %s", prefix);
assemble_name (file, fname);
@@ -11320,7 +11323,7 @@ output_mi_thunk (file, thunk_fndecl, del
if (TARGET_ELF)
function_section (current_function_decl);
else
- text_section();
+ text_section ();
if (TARGET_MINIMAL_TOC)
asm_fprintf (file, (TARGET_32BIT)
? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: powerpc fix for gcc.dg/asm-names.c failure
2002-10-03 19:25 ` powerpc fix for gcc.dg/asm-names.c failure Alan Modra
@ 2002-10-03 19:32 ` David Edelsohn
0 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2002-10-03 19:32 UTC (permalink / raw)
To: gcc-patches
* config/rs6000/rs6000.c (rs6000_output_function_epilogue): Use a
name for the tbtab label that depends on the function asm name.
Don't output tbtab label unless optional_tbtab.
(output_mi_thunk): Formatting.
Okay.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* [PATCH] fold-const.c use of BRANCH_COST
@ 2003-04-09 19:34 David Edelsohn
2003-04-11 4:11 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2003-04-09 19:34 UTC (permalink / raw)
To: gcc-patches
While investigating PowerPC performance, I have discovered that
the threshold levels used to test BRANCH_COST are not always correct for
PowerPC. Instead of arguing to change the threshold, I propose allowing
the test to be overridden in the machine description, with the default
being the former BRANCH_COST-based test.
If the patch below is approved, I will add the appropriate
documentation as well. The motivation is:
Unmodified:
200.sixtrack 1100 651 169* 1100 535 206*
254.gap 1100 249 442* 1100 262 419*
255.vortex 1900 283 672* 1900 275 691*
BRANCH_COST=1:
200.sixtrack 1100 1492 73.7* 1100 743 148*
254.gap 1100 248 444* 1100 239 460*
255.vortex 1900 293 647* 1900 276 688*
Modified fold-const.c only:
200.sixtrack 1100 649 169* 1100 675 163*
254.gap 1100 281 391* 1100 249 442*
255.vortex 1900 295 644* 1900 275 692*
Modified fold-const.c:fold_range_test() only:
200.sixtrack 1100 964 114* 1100 529 208*
254.gap 1100 245 449* 1100 243 452*
255.vortex 1900 284 668* 1900 274 694*
Yes, BRANCH_COST=1 really does degrade 200.sixtrack that much -- it is
completely repeatable.
Thanks, David
* fold-const.c (fold_range_test): Add new macro defaulting
to BRANCH_COST.
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.242
diff -c -p -r1.242 fold-const.c
*** fold-const.c 23 Mar 2003 22:57:25 -0000 1.242
--- fold-const.c 9 Apr 2003 19:25:26 -0000
*************** fold_range_test (exp)
*** 3449,3455 ****
/* On machines where the branch cost is expensive, if this is a
short-circuited branch and the underlying object on both sides
is the same, make a non-short-circuit operation. */
! else if (BRANCH_COST >= 2
&& lhs != 0 && rhs != 0
&& (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
|| TREE_CODE (exp) == TRUTH_ORIF_EXPR)
--- 3449,3460 ----
/* On machines where the branch cost is expensive, if this is a
short-circuited branch and the underlying object on both sides
is the same, make a non-short-circuit operation. */
!
! #ifndef RANGE_TEST_SHORT_CIRCUIT
! #define RANGE_TEST_SHORT_CIRCUIT (BRANCH_COST >= 2)
! #endif
!
! else if (RANGE_TEST_SHORT_CIRCUIT
&& lhs != 0 && rhs != 0
&& (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
|| TREE_CODE (exp) == TRUTH_ORIF_EXPR)
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-09 19:34 [PATCH] fold-const.c use of BRANCH_COST David Edelsohn
@ 2003-04-11 4:11 ` Richard Henderson
2003-04-11 4:23 ` Andrew Pinski
2003-04-11 4:24 ` David Edelsohn
0 siblings, 2 replies; 875+ messages in thread
From: Richard Henderson @ 2003-04-11 4:11 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
On Wed, Apr 09, 2003 at 03:34:31PM -0400, David Edelsohn wrote:
> Yes, BRANCH_COST=1 really does degrade 200.sixtrack that much -- it is
> completely repeatable.
But why would you want to set BRANCH_COST that low?
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 4:11 ` Richard Henderson
@ 2003-04-11 4:23 ` Andrew Pinski
2003-04-11 17:47 ` Geoff Keating
2003-04-11 4:24 ` David Edelsohn
1 sibling, 1 reply; 875+ messages in thread
From: Andrew Pinski @ 2003-04-11 4:23 UTC (permalink / raw)
To: Richard Henderson; +Cc: Andrew Pinski, David Edelsohn, gcc-patches
Because with BRANCH_COST set to 3, gcc on PPC produces
serializing instructions (adde, subfe, subfme, subfze) on some
processors, like 750 and 7400.
It also sometimes produces smaller code.
Thanks,
Andrew Pinski
On Friday, Apr 11, 2003, at 00:09 US/Eastern, Richard Henderson wrote:
> On Wed, Apr 09, 2003 at 03:34:31PM -0400, David Edelsohn wrote:
>> Yes, BRANCH_COST=1 really does degrade 200.sixtrack that much -- it is
>> completely repeatable.
>
> But why would you want to set BRANCH_COST that low?
>
>
> r~
>
>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 4:11 ` Richard Henderson
2003-04-11 4:23 ` Andrew Pinski
@ 2003-04-11 4:24 ` David Edelsohn
2003-04-11 4:43 ` Richard Henderson
1 sibling, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2003-04-11 4:24 UTC (permalink / raw)
To: Richard Henderson, gcc-patches
>>>>> Richard Henderson writes:
>> Yes, BRANCH_COST=1 really does degrade 200.sixtrack that much -- it is
>> completely repeatable.
Richard> But why would you want to set BRANCH_COST that low?
Because one of the design points for the POWER/PowerPC
architecture was "branches are free" and good branch prediction makes the
cost very low. I do not want to set BRANCH_COST that low, but it is hard
to argue when setting BRANCH_COST=1 does improve performance of some
testcases.
The issue is what effect of BRANCH_COST=1 is actually improving
performance. My investigation lead me to fold_range_test.
I would like to change the heuristic used by fold_range_test for
PowerPC. Instead of arguing that the threshold should be some arbitrary
value greater than the setting of BRANCH_COST on PowerPC, it seems more
useful to add port-specific finer granularity of control.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 4:24 ` David Edelsohn
@ 2003-04-11 4:43 ` Richard Henderson
2003-04-11 4:58 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2003-04-11 4:43 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
On Fri, Apr 11, 2003 at 12:24:49AM -0400, David Edelsohn wrote:
> I would like to change the heuristic used by fold_range_test for
> PowerPC. Instead of arguing that the threshold should be some arbitrary
> value greater than the setting of BRANCH_COST on PowerPC, it seems more
> useful to add port-specific finer granularity of control.
Well, ok. I just wonder if you'll wind up with a whole set of
knobs for ifcvt.c too...
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 4:43 ` Richard Henderson
@ 2003-04-11 4:58 ` David Edelsohn
2003-04-11 5:11 ` Richard Henderson
2003-04-11 17:08 ` Dale Johannesen
0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2003-04-11 4:58 UTC (permalink / raw)
To: Richard Henderson, gcc-patches
>>>>> Richard Henderson writes:
Richard> Well, ok. I just wonder if you'll wind up with a whole set of
Richard> knobs for ifcvt.c too...
PowerPC won't, because it looks like the threshold in ifcvt.c is
okay already, but what is wrong with more knobs? The problem is that
BRANCH_COST is too coarse an adjustment and it seems to be tested against
arbitrary values or values chosen for whichever processor the optimization
was developed. It just does not capture enough detail about the effect on
various architectures and processors, i.e., one avoids the branch but the
alternative code sequence may be worse, such as serializations.
As you probably can infer, Apple sets BRANCH_COST=1 in their
sources because it had a positive effect on their testcases. That is not
really the correct value, so I investigated the source of the benefits and
would like to provide that benefit without the negative side-effects.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 4:58 ` David Edelsohn
@ 2003-04-11 5:11 ` Richard Henderson
2003-04-11 14:41 ` David Edelsohn
2003-04-11 17:08 ` Dale Johannesen
1 sibling, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2003-04-11 5:11 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
On Fri, Apr 11, 2003 at 12:57:56AM -0400, David Edelsohn wrote:
> PowerPC won't, because it looks like the threshold in ifcvt.c is
> okay already, but what is wrong with more knobs?
Nothing, except that it'd be better to go at them in a more
organized sort of way than a basketful of random defines.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 5:11 ` Richard Henderson
@ 2003-04-11 14:41 ` David Edelsohn
2003-04-11 14:47 ` Jan Hubicka
2003-04-11 17:49 ` Geoff Keating
0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2003-04-11 14:41 UTC (permalink / raw)
To: Richard Henderson, gcc-patches
>>>>> Richard Henderson writes:
Richard> Nothing, except that it'd be better to go at them in a more
Richard> organized sort of way than a basketful of random defines.
We can add the knobs for both uses of BRANCH_COST in fold-const.c
in this pass, if you want. BRANCH_COST isn't actually used in that many
parts of GCC.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 14:41 ` David Edelsohn
@ 2003-04-11 14:47 ` Jan Hubicka
2003-04-11 15:51 ` David Edelsohn
2003-04-11 17:49 ` Geoff Keating
1 sibling, 1 reply; 875+ messages in thread
From: Jan Hubicka @ 2003-04-11 14:47 UTC (permalink / raw)
To: David Edelsohn; +Cc: Richard Henderson, gcc-patches
> >>>>> Richard Henderson writes:
>
> Richard> Nothing, except that it'd be better to go at them in a more
> Richard> organized sort of way than a basketful of random defines.
>
> We can add the knobs for both uses of BRANCH_COST in fold-const.c
> in this pass, if you want. BRANCH_COST isn't actually used in that many
> parts of GCC.
I would like to see this happen. Definitly i386 CPUs are other where
BRANCH_COST choice doesn't match. It would be nice to have separate
knobs for when optimizing for size or speed (decided using
maybe_hot_bb_p inside ifcvt.c)
Honza
>
> David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 14:47 ` Jan Hubicka
@ 2003-04-11 15:51 ` David Edelsohn
2003-04-11 16:57 ` Jan Hubicka
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2003-04-11 15:51 UTC (permalink / raw)
To: Jan Hubicka; +Cc: Richard Henderson, gcc-patches
>>>>> Jan Hubicka writes:
Jan> I would like to see this happen. Definitly i386 CPUs are other where
Jan> BRANCH_COST choice doesn't match. It would be nice to have separate
Jan> knobs for when optimizing for size or speed (decided using
Jan> maybe_hot_bb_p inside ifcvt.c)
If we are going to separate all of the thresholds, should they be
target hooks or macros?
The basic breakdown is the following:
1) ifcvt.c
a) MAX_CONDITIONAL_EXECUTE (BRANCH_COST + 1)
b) store_flag normalize (true/false BRANCH_COST >= 2)
c) store_flag normalize (default BRANCH_COST >= 3)
d) store_flag addcc (BRANCH_COST >= 2)
e) store_flag mask (BRANCH_COST >= 2)
f) cmove arith (BRANCH_COST >= 5)
2) expmed.c
a) div quotient jump vs shift (BRANCH_COST < 1 or < 3)
b) emit_store_flag SCC (BRANCH_COST > 0)
3) expr.c
a) trinary const (BRANCH_COST >= 3)
call do_store_flag cheap (BRANCH_COST <= 1)
b) do_store_flag SCC (BRANCH_COST >= 0)
4) fold-const.c
a) range_test short-circuit (BRANCH_COST >= 2)
b) fold_truthop unconditionally evaluate RHS (BRANCH_COST >= 2)
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 15:51 ` David Edelsohn
@ 2003-04-11 16:57 ` Jan Hubicka
2003-04-11 16:58 ` David Edelsohn
2003-04-21 17:24 ` David Edelsohn
0 siblings, 2 replies; 875+ messages in thread
From: Jan Hubicka @ 2003-04-11 16:57 UTC (permalink / raw)
To: David Edelsohn; +Cc: Jan Hubicka, Richard Henderson, gcc-patches
> >>>>> Jan Hubicka writes:
>
> Jan> I would like to see this happen. Definitly i386 CPUs are other where
> Jan> BRANCH_COST choice doesn't match. It would be nice to have separate
> Jan> knobs for when optimizing for size or speed (decided using
> Jan> maybe_hot_bb_p inside ifcvt.c)
>
> If we are going to separate all of the thresholds, should they be
> target hooks or macros?
I believe we are mocing from macros to the hooks, so it should be hook.
I think it can be a bitmap (ie one value) so we don't need to have so
many of them. This opens a question how we will deal with adding new
transformations....
>
> The basic breakdown is the following:
>
> 1) ifcvt.c
> a) MAX_CONDITIONAL_EXECUTE (BRANCH_COST + 1)
> b) store_flag normalize (true/false BRANCH_COST >= 2)
> c) store_flag normalize (default BRANCH_COST >= 3)
> d) store_flag addcc (BRANCH_COST >= 2)
> e) store_flag mask (BRANCH_COST >= 2)
> f) cmove arith (BRANCH_COST >= 5)
>
> 2) expmed.c
> a) div quotient jump vs shift (BRANCH_COST < 1 or < 3)
> b) emit_store_flag SCC (BRANCH_COST > 0)
>
> 3) expr.c
> a) trinary const (BRANCH_COST >= 3)
> call do_store_flag cheap (BRANCH_COST <= 1)
> b) do_store_flag SCC (BRANCH_COST >= 0)
>
> 4) fold-const.c
> a) range_test short-circuit (BRANCH_COST >= 2)
> b) fold_truthop unconditionally evaluate RHS (BRANCH_COST >= 2)
optabs.c for instance is missing in your list.
Honza
>
>
> David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 16:57 ` Jan Hubicka
@ 2003-04-11 16:58 ` David Edelsohn
2003-04-21 17:24 ` David Edelsohn
1 sibling, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2003-04-11 16:58 UTC (permalink / raw)
To: Jan Hubicka; +Cc: Richard Henderson, gcc-patches
>>>>> Jan Hubicka writes:
Jan> optabs.c for instance is missing in your list.
Yes, sorry, I forgot to list that. It's choosing how to compute
absolute value.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 4:58 ` David Edelsohn
2003-04-11 5:11 ` Richard Henderson
@ 2003-04-11 17:08 ` Dale Johannesen
2003-04-11 17:54 ` David Edelsohn
1 sibling, 1 reply; 875+ messages in thread
From: Dale Johannesen @ 2003-04-11 17:08 UTC (permalink / raw)
To: David Edelsohn; +Cc: Dale Johannesen, Richard Henderson, gcc-patches
On Thursday, April 10, 2003, at 09:57 PM, David Edelsohn wrote:
>>>>>> Richard Henderson writes:
>
> As you probably can infer, Apple sets BRANCH_COST=1 in their
> sources because it had a positive effect on their testcases. That is
> not
> really the correct value, so I investigated the source of the benefits
> and
> would like to provide that benefit without the negative side-effects.
Yes, Apple has done this since the 2.95 days, and it is a consistent
winner. Every so often somebody tries setting it back up to 2 or 3
but it's always been a lose overall. Despite David's 3 examples, SPEC
still does better overall with BRANCH_COST==1.
As for "not really the correct value", I don't see why not. Branches
really are very cheap on the ppc, typically 0 or 1 cycle. If the
macro is being used to mean something other than "cost of a branch",
I'd say that indicates a problem in its use or naming. I'm glad to
see David's attempt to treat the different uses of it differently; I
think that's a good approach.
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 4:23 ` Andrew Pinski
@ 2003-04-11 17:47 ` Geoff Keating
2003-04-12 2:48 ` Segher Boessenkool
0 siblings, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2003-04-11 17:47 UTC (permalink / raw)
To: Andrew Pinski; +Cc: David Edelsohn, gcc-patches
Andrew Pinski <pinskia@physics.uc.edu> writes:
> Because with BRANCH_COST set to 3, gcc on PPC produces
> serializing instructions (adde, subfe, subfme, subfze) on some
> processors, like 750 and 7400.
> It also sometimes produces smaller code.
If these instructions are serializing, it's probably not useful for
GCC to be producing them at all on these processors; they'll always be
slower than a branch.
--
- Geoffrey Keating <geoffk@geoffk.org>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 14:41 ` David Edelsohn
2003-04-11 14:47 ` Jan Hubicka
@ 2003-04-11 17:49 ` Geoff Keating
1 sibling, 0 replies; 875+ messages in thread
From: Geoff Keating @ 2003-04-11 17:49 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
David Edelsohn <dje@watson.ibm.com> writes:
> >>>>> Richard Henderson writes:
>
> Richard> Nothing, except that it'd be better to go at them in a more
> Richard> organized sort of way than a basketful of random defines.
>
> We can add the knobs for both uses of BRANCH_COST in fold-const.c
> in this pass, if you want. BRANCH_COST isn't actually used in that many
> parts of GCC.
It'd be better if we could assign a meaning to each macro, like
"this is the relative cost of a branch compared to an integer
instruction" rather than "this is the knob you tweak to affect this
code path which may or may not affect this optimisation".
--
- Geoffrey Keating <geoffk@geoffk.org>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 17:08 ` Dale Johannesen
@ 2003-04-11 17:54 ` David Edelsohn
0 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2003-04-11 17:54 UTC (permalink / raw)
To: Dale Johannesen, Richard Henderson; +Cc: gcc-patches
>>>>> Dale Johannesen writes:
> As for "not really the correct value", I don't see why not. Branches
> really are very cheap on the ppc, typically 0 or 1 cycle. If the
> macro is being used to mean something other than "cost of a branch",
> I'd say that indicates a problem in its use or naming. I'm glad to
> see David's attempt to treat the different uses of it differently; I
> think that's a good approach.
I think the two problems with BRANCH_COST are:
1) Possibly arbitrary thresholds. Yes, the alternate code is better
(ignoring all other issues) if branch costs are expensive, but what is
the choice for "expensive".
2) Cost of alternate code. The non-branch code may generate more
expensive instruction sequences on the target architecture, e.g.,
materializing condition codes in GPRs. BRANCH_COST and the threshold
value do not take those case-by-case issues into effect.
So a large value for BRANCH_COST may be correct, but its benefit is
getting wiped out by the missed architecture-specific optimizations.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 17:47 ` Geoff Keating
@ 2003-04-12 2:48 ` Segher Boessenkool
0 siblings, 0 replies; 875+ messages in thread
From: Segher Boessenkool @ 2003-04-12 2:48 UTC (permalink / raw)
To: Geoff Keating; +Cc: Andrew Pinski, David Edelsohn, gcc-patches
Geoff Keating wrote:
> Andrew Pinski <pinskia@physics.uc.edu> writes:
>
>>Because with BRANCH_COST set to 3, gcc on PPC produces
>>serializing instructions (adde, subfe, subfme, subfze) on some
>>processors, like 750 and 7400.
>>It also sometimes produces smaller code.
>
> If these instructions are serializing, it's probably not useful for
> GCC to be producing them at all on these processors; they'll always be
> slower than a branch.
On G3 and G4, these insns are only execution serialized (because
XER is not renamed), not completion serialized or worse. They
can be quite useful, especially if interleaved with integer, load
or AltiVec insns; it's certainly not worse then branching in
most cases. Current GCC seems to like them a little bit *too*
much, though.
Segher
[Execution serialization means: the insn won't execute until all
prior insns have completed; for most such insns the results of
the insn are only available after the insn has completed.]
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-11 16:57 ` Jan Hubicka
2003-04-11 16:58 ` David Edelsohn
@ 2003-04-21 17:24 ` David Edelsohn
2003-04-21 18:00 ` Richard Henderson
1 sibling, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2003-04-21 17:24 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches
Where do we stand with respect to my proposal to allow
finer-grained control of heuristics involving BRANCH_COST? If you want a
more organized re-organization, a little guidance would help. I do not
see an easy way to group the changes into categories that are appropriate
to all targets because I am trying to address the problem of the
non-branch implementation possibly being slower on some processors with
high branch cost.
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-21 17:24 ` David Edelsohn
@ 2003-04-21 18:00 ` Richard Henderson
2003-04-22 15:02 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2003-04-21 18:00 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
On Mon, Apr 21, 2003 at 01:24:23PM -0400, David Edelsohn wrote:
> Where do we stand with respect to my proposal to allow
> finer-grained control of heuristics involving BRANCH_COST? If you want a
> more organized re-organization, a little guidance would help.
I don't have any, sorry. I guess going with what you have is
fine until we come up with a more unified scheme.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: [PATCH] fold-const.c use of BRANCH_COST
2003-04-21 18:00 ` Richard Henderson
@ 2003-04-22 15:02 ` David Edelsohn
0 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2003-04-22 15:02 UTC (permalink / raw)
To: gcc-patches
FYI, appended is the complete patch I applied.
David
* fold-const.c (fold_range_test): Use RANGE_TEST_NON_SHORT_CIRCUIT
macro defaulting to original BRANCH_COST heuristic.
* doc/tm.texi (RANGE_TEST_NON_SHORT_CIRCUIT): Document.
* config/rs6000/rs6000.h (RANGE_TEST_NON_SHORT_CIRCUIT): Define.
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.247
diff -c -p -r1.247 fold-const.c
*** fold-const.c 16 Apr 2003 21:33:19 -0000 1.247
--- fold-const.c 21 Apr 2003 18:21:19 -0000
*************** merge_ranges (pin_p, plow, phigh, in0_p,
*** 3414,3419 ****
--- 3414,3423 ----
return 1;
}
\f
+ #ifndef RANGE_TEST_NON_SHORT_CIRCUIT
+ #define RANGE_TEST_NON_SHORT_CIRCUIT (BRANCH_COST >= 2)
+ #endif
+
/* EXP is some logical combination of boolean tests. See if we can
merge it into some range test. Return the new tree if so. */
*************** fold_range_test (exp)
*** 3450,3456 ****
/* On machines where the branch cost is expensive, if this is a
short-circuited branch and the underlying object on both sides
is the same, make a non-short-circuit operation. */
! else if (BRANCH_COST >= 2
&& lhs != 0 && rhs != 0
&& (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
|| TREE_CODE (exp) == TRUTH_ORIF_EXPR)
--- 3454,3460 ----
/* On machines where the branch cost is expensive, if this is a
short-circuited branch and the underlying object on both sides
is the same, make a non-short-circuit operation. */
! else if (RANGE_TEST_NON_SHORT_CIRCUIT
&& lhs != 0 && rhs != 0
&& (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
|| TREE_CODE (exp) == TRUTH_ORIF_EXPR)
Index: tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.214
diff -c -p -r1.214 tm.texi
*** tm.texi 20 Apr 2003 18:20:39 -0000 1.214
--- tm.texi 21 Apr 2003 18:33:01 -0000
*************** function address than to call an address
*** 5529,5534 ****
--- 5529,5540 ----
Define this macro if it is as good or better for a function to call
itself with an explicit address than to call an address kept in a
register.
+
+ @findex RANGE_TEST_NON_SHORT_CIRCUIT
+ @item RANGE_TEST_NON_SHORT_CIRCUIT
+ Define this macro if a non-short-circuit operation produced by
+ @samp{fold_range_test ()} is optimal. This macro defaults to true if
+ @code{BRANCH_COST} is greater than or equal to the value 2.
@end table
@deftypefn {Target Hook} bool TARGET_RTX_COSTS (rtx @var{x}, int @var{code}, int @var{outer_code}, int *@var{total})
Index: rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.267
diff -c -p -r1.267 rs6000.h
*** rs6000.h 17 Apr 2003 23:18:57 -0000 1.267
--- rs6000.h 22 Apr 2003 14:43:20 -0000
*************** extern int rs6000_default_long_calls;
*** 992,997 ****
--- 992,1001 ----
#define BRANCH_COST 3
+ /* Override BRANCH_COST heuristic which empirically produces worse
+ performance for fold_range_test(). */
+
+ #define RANGE_TEST_NON_SHORT_CIRCUIT 0
/* A fixed register used at prologue and epilogue generation to fix
addressing modes. The SPE needs heavy addressing fixes at the last
^ permalink raw reply [flat|nested] 875+ messages in thread
* function parms in regs, patch 3 of 3
@ 2003-04-24 15:34 Alan Modra
0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2003-04-24 15:34 UTC (permalink / raw)
To: gcc-patches
This patch defines a new macro, BLOCK_REG_PADDING, and uses it to
determine what to do with odd-sized struct pieces in regs. I wanted
to make use of FUNCTION_ARG_PADDING in its default definition, so
that meant passing TYPE to emit_group_{load,store}. Anyway, what
this does is allow powerpc64 to pad structs upward, downward and
every which way to our heart's content, in registers, without using
the PARALLELs invented for Irix support. All controlled in one place,
rs6000.c:function_arg_padding. Hmm. It might be a good idea to make
the default PAD_VARARGS_DOWN use FUNCTION_ARG_PADDING too.
The rs6000 code has been tested using AGGREGATE_PADDING_FIXED == 0,
AGGREGATE_PADDING_FIXED == 1 and AGGREGATES_PAD_UPWARD_ALWAYS == 0,
AGGREGATE_PADDING_FIXED == 1 and AGGREGATES_PAD_UPWARD_ALWAYS == 1,
with and without MUST_PASS_IN_STACK redefined. All seems well.
Of course, redefining MUST_PASS_IN_STACK means that code compiled
with previous versions of gcc might not be compatible with a new
gcc, but I think we need to suffer the pain now so that we're
compliant with the ABI.
* expr.h (struct locate_and_pad_arg_data): Add where_pad.
(BLOCK_REG_PADDING): Define.
(emit_group_load, emit_group_store): Adjust declarations.
* expr.c (emit_group_load): Add "type" param, and use
BLOCK_REG_PADDING to determine need for a shift. Optimize non-
aligned accesses if !SLOW_UNALIGNED_ACCESS.
(emit_group_store): Likewise.
(emit_push_insn, expand_assignment, store_expr, expand_expr): Adjust
emit_group_load and emit_group_store calls.
* calls.c (store_unaligned_arguments_into_pseudos): Tidy. Use
BLOCK_REG_PADDING to determine whether we need endian_correction.
(load_register_parameters): Localize vars. Handle shifting of
small values to the correct end of regs. Adjust emit_group_load
call.
(expand_call, emit_library_call_value_1): Adjust emit_group_load
and emit_group_store calls.
* function.c (assign_parms): Set mem alignment for stack slots.
Adjust emit_group_store call. Store values at the "wrong" end
of regs to the stack. Use BLOCK_REG_PADDING.
(locate_and_pad_parm): Save where_pad.
(expand_function_end): Adjust emit_group_load call.
* stmt.c (expand_value_return): Adjust emit_group_load call.
* Makefile.in (calls.o): Depend on $(OPTABS_H).
* config/rs6000/linux64.h (TARGET_BIG_ENDIAN): Redefine as 1.
(FIXED_R13): Delete.
(AGGREGATE_PADDING_FIXED): Define.
(MUST_PASS_IN_STACK): Define.
* config/rs6000/rs6000.h (struct rs6000_args): Remove orig_nargs.
(PAD_VARARGS_DOWN): Define in terms of FUNCTION_ARG_PADDING.
* config/rs6000/rs6000.c (init_cumulative_args): Don't set orig_nargs.
(function_arg_padding): !AGGREGATE_PADDING_FIXED compatibility code.
Act on AGGREGATES_PAD_UPWARD_ALWAYS.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
diff -urp gcc2/gcc/expr.h gcc3/gcc/expr.h
--- gcc2/gcc/expr.h 2003-04-24 15:31:56.000000000 +0930
+++ gcc3/gcc/expr.h 2003-04-24 21:07:17.000000000 +0930
@@ -93,6 +93,8 @@ struct locate_and_pad_arg_data
/* The amount that the stack pointer needs to be adjusted to
force alignment for the next argument. */
struct args_size alignment_pad;
+ /* Which way we should pad this arg. */
+ enum direction where_pad;
};
#endif
@@ -150,6 +152,14 @@ do { \
? downward : upward))
#endif
+/* Specify padding for the last element of a block move between
+ registers and memory. FIRST is non-zero if this is the only
+ element. */
+#ifndef BLOCK_REG_PADDING
+#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
+ (!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
+#endif
+
/* Supply a default definition for FUNCTION_ARG_BOUNDARY. Normally, we let
FUNCTION_ARG_PADDING, which also pads the length, handle any needed
alignment. */
@@ -416,19 +426,21 @@ extern void move_block_from_reg PARAMS (
/* Generate a non-consecutive group of registers represented by a PARALLEL. */
extern rtx gen_group_rtx PARAMS ((rtx));
+#ifdef TREE_CODE
/* Load a BLKmode value into non-consecutive registers represented by a
PARALLEL. */
-extern void emit_group_load PARAMS ((rtx, rtx, int));
+extern void emit_group_load PARAMS ((rtx, rtx, tree, int));
+#endif
/* Move a non-consecutive group of registers represented by a PARALLEL into
a non-consecutive group of registers represented by a PARALLEL. */
extern void emit_group_move PARAMS ((rtx, rtx));
+#ifdef TREE_CODE
/* Store a BLKmode value from non-consecutive registers represented by a
PARALLEL. */
-extern void emit_group_store PARAMS ((rtx, rtx, int));
+extern void emit_group_store PARAMS ((rtx, rtx, tree, int));
-#ifdef TREE_CODE
/* Copy BLKmode object from a set of registers. */
extern rtx copy_blkmode_from_reg PARAMS ((rtx, rtx, tree));
#endif
diff -urp gcc2/gcc/expr.c gcc3/gcc/expr.c
--- gcc2/gcc/expr.c 2003-04-24 14:46:04.000000000 +0930
+++ gcc3/gcc/expr.c 2003-04-24 21:07:17.000000000 +0930
@@ -2212,19 +2212,15 @@ gen_group_rtx (orig)
return gen_rtx_PARALLEL (GET_MODE (orig), gen_rtvec_v (length, tmps));
}
-/* Emit code to move a block SRC to a block DST, where DST is non-consecutive
- registers represented by a PARALLEL. SSIZE represents the total size of
- block SRC in bytes, or -1 if not known. */
-/* ??? If SSIZE % UNITS_PER_WORD != 0, we make the blatant assumption that
- the balance will be in what would be the low-order memory addresses, i.e.
- left justified for big endian, right justified for little endian. This
- happens to be true for the targets currently using this support. If this
- ever changes, a new target macro along the lines of FUNCTION_ARG_PADDING
- would be needed. */
+/* Emit code to move a block ORIG_SRC of type TYPE to a block DST,
+ where DST is non-consecutive registers represented by a PARALLEL.
+ SSIZE represents the total size of block ORIG_SRC in bytes, or -1
+ if not known. */
void
-emit_group_load (dst, orig_src, ssize)
+emit_group_load (dst, orig_src, type, ssize)
rtx dst, orig_src;
+ tree type;
int ssize;
{
rtx *tmps, src;
@@ -2253,7 +2249,11 @@ emit_group_load (dst, orig_src, ssize)
/* Handle trailing fragments that run over the size of the struct. */
if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
{
- shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
+ /* Arrange to shift the fragment to where it belongs.
+ extract_bit_field loads to the lsb of the reg. */
+ if (BLOCK_REG_PADDING (GET_MODE (orig_src), type, i == start)
+ == (BYTES_BIG_ENDIAN ? upward : downward))
+ shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
bytelen = ssize - bytepos;
if (bytelen <= 0)
abort ();
@@ -2278,7 +2278,8 @@ emit_group_load (dst, orig_src, ssize)
/* Optimize the access just a bit. */
if (GET_CODE (src) == MEM
- && MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode)
+ && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (src))
+ || MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode))
&& bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
&& bytelen == GET_MODE_SIZE (mode))
{
@@ -2321,7 +2322,7 @@ emit_group_load (dst, orig_src, ssize)
bytepos * BITS_PER_UNIT, 1, NULL_RTX,
mode, mode, ssize);
- if (BYTES_BIG_ENDIAN && shift)
+ if (shift)
expand_binop (mode, ashl_optab, tmps[i], GEN_INT (shift),
tmps[i], 0, OPTAB_WIDEN);
}
@@ -2353,13 +2354,16 @@ emit_group_move (dst, src)
XEXP (XVECEXP (src, 0, i), 0));
}
-/* Emit code to move a block SRC to a block DST, where SRC is non-consecutive
- registers represented by a PARALLEL. SSIZE represents the total size of
- block DST, or -1 if not known. */
+/* Emit code to move a block SRC to a block ORIG_DST of type TYPE,
+ where SRC is non-consecutive registers represented by a PARALLEL.
+ SSIZE represents the total size of block ORIG_DST, or -1 if not
+ known. */
void
-emit_group_store (orig_dst, src, ssize)
- rtx orig_dst, src;
+emit_group_store (orig_dst, src, type, ssize)
+ rtx orig_dst;
+ rtx src;
+ tree type ATTRIBUTE_UNUSED;
int ssize;
{
rtx *tmps, dst;
@@ -2404,8 +2408,8 @@ emit_group_store (orig_dst, src, ssize)
the temporary. */
temp = assign_stack_temp (GET_MODE (dst), ssize, 0);
- emit_group_store (temp, src, ssize);
- emit_group_load (dst, temp, ssize);
+ emit_group_store (temp, src, type, ssize);
+ emit_group_load (dst, temp, type, ssize);
return;
}
else if (GET_CODE (dst) != MEM && GET_CODE (dst) != CONCAT)
@@ -2426,7 +2430,10 @@ emit_group_store (orig_dst, src, ssize)
/* Handle trailing fragments that run over the size of the struct. */
if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
{
- if (BYTES_BIG_ENDIAN)
+ /* store_bit_field always takes its value from the lsb.
+ Move the fragment to the lsb if it's not already there. */
+ if (BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
+ == (BYTES_BIG_ENDIAN ? upward : downward))
{
int shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
expand_binop (mode, ashr_optab, tmps[i], GEN_INT (shift),
@@ -2459,7 +2466,8 @@ emit_group_store (orig_dst, src, ssize)
/* Optimize the access just a bit. */
if (GET_CODE (dest) == MEM
- && MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode)
+ && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (dest))
+ || MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
&& bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
&& bytelen == GET_MODE_SIZE (mode))
emit_move_insn (adjust_address (dest, mode, bytepos), tmps[i]);
@@ -3991,7 +3999,7 @@ emit_push_insn (x, mode, type, size, ali
/* Handle calls that pass values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
if (GET_CODE (reg) == PARALLEL)
- emit_group_load (reg, x, -1); /* ??? size? */
+ emit_group_load (reg, x, type, -1);
else
move_block_to_reg (REGNO (reg), x, partial, mode);
}
@@ -4194,7 +4202,8 @@ expand_assignment (to, from, want_value,
/* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
if (GET_CODE (to_rtx) == PARALLEL)
- emit_group_load (to_rtx, value, int_size_in_bytes (TREE_TYPE (from)));
+ emit_group_load (to_rtx, value, TREE_TYPE (from),
+ int_size_in_bytes (TREE_TYPE (from)));
else if (GET_MODE (to_rtx) == BLKmode)
emit_block_move (to_rtx, value, expr_size (from), BLOCK_OP_NORMAL);
else
@@ -4228,7 +4237,8 @@ expand_assignment (to, from, want_value,
temp = expand_expr (from, 0, GET_MODE (to_rtx), 0);
if (GET_CODE (to_rtx) == PARALLEL)
- emit_group_load (to_rtx, temp, int_size_in_bytes (TREE_TYPE (from)));
+ emit_group_load (to_rtx, temp, TREE_TYPE (from),
+ int_size_in_bytes (TREE_TYPE (from)));
else
emit_move_insn (to_rtx, temp);
@@ -4641,7 +4651,8 @@ store_expr (exp, target, want_value)
/* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
else if (GET_CODE (target) == PARALLEL)
- emit_group_load (target, temp, int_size_in_bytes (TREE_TYPE (exp)));
+ emit_group_load (target, temp, TREE_TYPE (exp),
+ int_size_in_bytes (TREE_TYPE (exp)));
else if (GET_MODE (temp) == BLKmode)
emit_block_move (target, temp, expr_size (exp),
(want_value & 2
@@ -9182,7 +9193,7 @@ expand_expr (exp, target, tmode, modifie
/* Handle calls that pass values in multiple
non-contiguous locations. The Irix 6 ABI has examples
of this. */
- emit_group_store (memloc, op0,
+ emit_group_store (memloc, op0, inner_type,
int_size_in_bytes (inner_type));
else
emit_move_insn (memloc, op0);
diff -urp gcc2/gcc/calls.c gcc3/gcc/calls.c
--- gcc2/gcc/calls.c 2003-04-24 11:25:45.000000000 +0930
+++ gcc3/gcc/calls.c 2003-04-24 21:07:17.000000000 +0930
@@ -27,6 +27,7 @@ Software Foundation, 59 Temple Place - S
#include "tree.h"
#include "flags.h"
#include "expr.h"
+#include "optabs.h"
#include "libfuncs.h"
#include "function.h"
#include "regs.h"
@@ -1015,22 +1016,22 @@ store_unaligned_arguments_into_pseudos (
< (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD)))
{
int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
- int big_endian_correction = 0;
-
- args[i].n_aligned_regs
- = args[i].partial ? args[i].partial
- : (bytes + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
+ int nregs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ int endian_correction = 0;
+ args[i].n_aligned_regs = args[i].partial ? args[i].partial : nregs;
args[i].aligned_regs = (rtx *) xmalloc (sizeof (rtx)
* args[i].n_aligned_regs);
- /* Structures smaller than a word are aligned to the least
- significant byte (to the right). On a BYTES_BIG_ENDIAN machine,
+ /* Structures smaller than a word are normally aligned to the
+ least significant byte. On a BYTES_BIG_ENDIAN machine,
this means we must skip the empty high order bytes when
calculating the bit offset. */
- if (BYTES_BIG_ENDIAN
- && bytes < UNITS_PER_WORD)
- big_endian_correction = (BITS_PER_WORD - (bytes * BITS_PER_UNIT));
+ if (bytes < UNITS_PER_WORD
+ && (BLOCK_REG_PADDING (args[i].mode,
+ TREE_TYPE (args[i].tree_value), 1)
+ == downward))
+ endian_correction = BITS_PER_WORD - bytes * BITS_PER_UNIT;
for (j = 0; j < args[i].n_aligned_regs; j++)
{
@@ -1039,6 +1040,8 @@ store_unaligned_arguments_into_pseudos (
int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);
args[i].aligned_regs[j] = reg;
+ word = extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
+ word_mode, word_mode, BITS_PER_WORD);
/* There is no need to restrict this code to loading items
in TYPE_ALIGN sized hunks. The bitfield instructions can
@@ -1054,11 +1057,8 @@ store_unaligned_arguments_into_pseudos (
emit_move_insn (reg, const0_rtx);
bytes -= bitsize / BITS_PER_UNIT;
- store_bit_field (reg, bitsize, big_endian_correction, word_mode,
- extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
- word_mode, word_mode,
- BITS_PER_WORD),
- BITS_PER_WORD);
+ store_bit_field (reg, bitsize, endian_correction, word_mode,
+ word, BITS_PER_WORD);
}
}
}
@@ -1689,34 +1689,45 @@ load_register_parameters (args, num_actu
{
rtx reg = ((flags & ECF_SIBCALL)
? args[i].tail_call_reg : args[i].reg);
- int partial = args[i].partial;
- int nregs;
-
if (reg)
{
+ int partial = args[i].partial;
+ int nregs;
+ int size = 0;
rtx before_arg = get_last_insn ();
/* Set to non-negative if must move a word at a time, even if just
one word (e.g, partial == 1 && mode == DFmode). Set to -1 if
we just use a normal move insn. This value can be zero if the
argument is a zero size structure with no fields. */
- nregs = (partial ? partial
- : (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode
- ? ((int_size_in_bytes (TREE_TYPE (args[i].tree_value))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
- : -1));
+ nregs = -1;
+ if (partial)
+ nregs = partial;
+ else if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode)
+ {
+ size = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
+ nregs = (size + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
+ }
+ else
+ size = GET_MODE_SIZE (args[i].mode);
/* Handle calls that pass values in multiple non-contiguous
locations. The Irix 6 ABI has examples of this. */
if (GET_CODE (reg) == PARALLEL)
- emit_group_load (reg, args[i].value,
- int_size_in_bytes (TREE_TYPE (args[i].tree_value)));
+ {
+ tree type = TREE_TYPE (args[i].tree_value);
+ emit_group_load (reg, args[i].value, type,
+ int_size_in_bytes (type));
+ }
/* If simple case, just do move. If normal partial, store_one_arg
has already loaded the register for us. In all other cases,
load the register(s) from memory. */
- else if (nregs == -1)
+ else if (nregs == -1
+ && !(size < UNITS_PER_WORD
+ && (args[i].locate.where_pad
+ == (BYTES_BIG_ENDIAN ? upward : downward))))
emit_move_insn (reg, args[i].value);
/* If we have pre-computed the values to put in the registers in
@@ -1728,9 +1739,42 @@ load_register_parameters (args, num_actu
args[i].aligned_regs[j]);
else if (partial == 0 || args[i].pass_on_stack)
- move_block_to_reg (REGNO (reg),
- validize_mem (args[i].value), nregs,
- args[i].mode);
+ {
+ rtx mem = validize_mem (args[i].value);
+
+ /* Handle case where we have a value that needs shifting
+ up to the msb. eg. a QImode value and we're padding
+ upward on a BYTES_BIG_ENDIAN machine. */
+ if (nregs == -1)
+ {
+ rtx ri = gen_rtx_REG (word_mode, REGNO (reg));
+ rtx x;
+ int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
+ x = expand_binop (word_mode, ashl_optab, mem,
+ GEN_INT (shift), ri, 1, OPTAB_WIDEN);
+ if (x != ri)
+ emit_move_insn (ri, x);
+ }
+
+ /* Handle a BLKmode that needs shifting. */
+ else if (nregs == 1 && size < UNITS_PER_WORD
+ && args[i].locate.where_pad == downward)
+ {
+ rtx tem = operand_subword_force (mem, 0, args[i].mode);
+ rtx ri = gen_rtx_REG (word_mode, REGNO (reg));
+ rtx x = gen_reg_rtx (word_mode);
+ int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
+ optab dir = BYTES_BIG_ENDIAN ? lshr_optab : ashl_optab;
+
+ emit_move_insn (x, tem);
+ x = expand_binop (word_mode, dir, x, GEN_INT (shift),
+ ri, 1, OPTAB_WIDEN);
+ if (x != ri)
+ emit_move_insn (ri, x);
+ }
+ else
+ move_block_to_reg (REGNO (reg), mem, nregs, args[i].mode);
+ }
/* When a parameter is a block, and perhaps in other cases, it is
possible that it did a load from an argument slot that was
@@ -3225,7 +3269,7 @@ expand_call (exp, target, ignore)
}
if (! rtx_equal_p (target, valreg))
- emit_group_store (target, valreg,
+ emit_group_store (target, valreg, TREE_TYPE (exp),
int_size_in_bytes (TREE_TYPE (exp)));
/* We can not support sibling calls for this case. */
@@ -3976,7 +4020,7 @@ emit_library_call_value_1 (retval, orgfu
/* Handle calls that pass values in multiple non-contiguous
locations. The PA64 has examples of this for library calls. */
if (reg != 0 && GET_CODE (reg) == PARALLEL)
- emit_group_load (reg, val, GET_MODE_SIZE (GET_MODE (val)));
+ emit_group_load (reg, val, NULL_TREE, GET_MODE_SIZE (GET_MODE (val)));
else if (reg != 0 && partial == 0)
emit_move_insn (reg, val);
@@ -4080,7 +4124,7 @@ emit_library_call_value_1 (retval, orgfu
if (GET_CODE (valreg) == PARALLEL)
{
temp = gen_reg_rtx (outmode);
- emit_group_store (temp, valreg, outmode);
+ emit_group_store (temp, valreg, NULL_TREE, outmode);
valreg = temp;
}
@@ -4123,7 +4167,7 @@ emit_library_call_value_1 (retval, orgfu
{
if (value == 0)
value = gen_reg_rtx (outmode);
- emit_group_store (value, valreg, outmode);
+ emit_group_store (value, valreg, NULL_TREE, outmode);
}
else if (value != 0)
emit_move_insn (value, valreg);
diff -urp gcc2/gcc/function.c gcc3/gcc/function.c
--- gcc2/gcc/function.c 2003-04-24 17:52:45.000000000 +0930
+++ gcc3/gcc/function.c 2003-04-24 21:07:17.000000000 +0930
@@ -4623,6 +4623,8 @@ assign_parms (fndecl)
offset_rtx));
set_mem_attributes (stack_parm, parm, 1);
+ if (entry_parm && MEM_ATTRS (stack_parm)->align < PARM_BOUNDARY)
+ set_mem_align (stack_parm, PARM_BOUNDARY);
/* Set also REG_ATTRS if parameter was passed in a register. */
if (entry_parm)
@@ -4654,6 +4656,7 @@ assign_parms (fndecl)
locations. The Irix 6 ABI has examples of this. */
if (GET_CODE (entry_parm) == PARALLEL)
emit_group_store (validize_mem (stack_parm), entry_parm,
+ TREE_TYPE (parm),
int_size_in_bytes (TREE_TYPE (parm)));
else
@@ -4757,7 +4760,10 @@ assign_parms (fndecl)
Set DECL_RTL to that place. */
- if (nominal_mode == BLKmode || GET_CODE (entry_parm) == PARALLEL)
+ if (nominal_mode == BLKmode
+ || (locate.where_pad == (BYTES_BIG_ENDIAN ? upward : downward)
+ && GET_MODE_SIZE (promoted_mode) < UNITS_PER_WORD)
+ || GET_CODE (entry_parm) == PARALLEL)
{
/* If a BLKmode arrives in registers, copy it to a stack slot.
Handle calls that pass values in multiple non-contiguous
@@ -4793,7 +4799,7 @@ assign_parms (fndecl)
/* Handle calls that pass values in multiple non-contiguous
locations. The Irix 6 ABI has examples of this. */
if (GET_CODE (entry_parm) == PARALLEL)
- emit_group_store (mem, entry_parm, size);
+ emit_group_store (mem, entry_parm, TREE_TYPE (parm), size);
/* If SIZE is that of a mode no bigger than a word, just use
that mode's store operation. */
@@ -4802,7 +4808,10 @@ assign_parms (fndecl)
enum machine_mode mode
= mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
- if (mode != BLKmode)
+ if (mode != BLKmode
+ && (size == UNITS_PER_WORD
+ || (BLOCK_REG_PADDING (mode, TREE_TYPE (parm), 1)
+ != (BYTES_BIG_ENDIAN ? upward : downward))))
{
rtx reg = gen_rtx_REG (mode, REGNO (entry_parm));
emit_move_insn (change_address (mem, mode, 0), reg);
@@ -4813,7 +4822,8 @@ assign_parms (fndecl)
to memory. Note that the previous test doesn't
handle all cases (e.g. SIZE == 3). */
else if (size != UNITS_PER_WORD
- && BYTES_BIG_ENDIAN)
+ && (BLOCK_REG_PADDING (mode, TREE_TYPE (parm), 1)
+ == downward))
{
rtx tem, x;
int by = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
@@ -5411,6 +5421,7 @@ locate_and_pad_parm (passed_mode, type,
= type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
+ locate->where_pad = where_pad;
#ifdef ARGS_GROW_DOWNWARD
locate->slot_offset.constant = -initial_offset_ptr->constant;
@@ -7142,6 +7153,7 @@ expand_function_end (filename, line, end
emit_group_move (real_decl_rtl, decl_rtl);
else
emit_group_load (real_decl_rtl, decl_rtl,
+ TREE_TYPE (decl_result),
int_size_in_bytes (TREE_TYPE (decl_result)));
}
else
diff -urp gcc2/gcc/stmt.c gcc3/gcc/stmt.c
--- gcc2/gcc/stmt.c 2003-04-22 18:55:34.000000000 +0930
+++ gcc3/gcc/stmt.c 2003-04-24 21:07:18.000000000 +0930
@@ -3008,7 +3008,7 @@ expand_value_return (val)
val = convert_modes (mode, old_mode, val, unsignedp);
#endif
if (GET_CODE (return_reg) == PARALLEL)
- emit_group_load (return_reg, val, int_size_in_bytes (type));
+ emit_group_load (return_reg, val, type, int_size_in_bytes (type));
else
emit_move_insn (return_reg, val);
}
diff -urp gcc2/gcc/Makefile.in gcc3/gcc/Makefile.in
--- gcc2/gcc/Makefile.in 2003-04-24 15:47:39.000000000 +0930
+++ gcc3/gcc/Makefile.in 2003-04-24 21:14:33.000000000 +0930
@@ -1531,7 +1531,7 @@ builtins.o : builtins.c $(CONFIG_H) $(SY
$(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \
except.h $(TM_P_H) $(PREDICT_H) libfuncs.h real.h langhooks.h
calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) flags.h \
- $(EXPR_H) langhooks.h $(TARGET_H) \
+ $(EXPR_H) $(OPTABS_H) langhooks.h $(TARGET_H) \
libfuncs.h $(REGS_H) toplev.h output.h function.h $(TIMEVAR_H) $(TM_P_H) cgraph.h except.h
expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
flags.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) real.h \
diff -urp gcc2/gcc/config/rs6000/linux64.h gcc3/gcc/config/rs6000/linux64.h
--- gcc2/gcc/config/rs6000/linux64.h 2003-04-22 18:55:34.000000000 +0930
+++ gcc3/gcc/config/rs6000/linux64.h 2003-04-24 21:07:17.000000000 +0930
@@ -49,6 +49,10 @@
#undef TARGET_64BIT
#define TARGET_64BIT 1
+/* And we're always big-endian. */
+#undef TARGET_BIG_ENDIAN
+#define TARGET_BIG_ENDIAN 1
+
/* 64-bit PowerPC Linux always has a TOC. */
#undef TARGET_NO_TOC
#define TARGET_NO_TOC 0
@@ -143,8 +147,25 @@
#undef JUMP_TABLES_IN_TEXT_SECTION
#define JUMP_TABLES_IN_TEXT_SECTION 1
-/* 64-bit PowerPC Linux always has GPR13 fixed. */
-#define FIXED_R13 1
+/* The linux ppc64 ABI isn't explicit on whether aggregates smaller
+ than a doubleword should be padded upward or downward. You could
+ reasonably assume that they follow the normal rules for structure
+ layout treating the parameter area as any other block of memory,
+ then map the reg param area to registers. ie. pad updard.
+ Setting both of the following defines results in this behaviour.
+ Setting just the first one will result in aggregates that fit in a
+ doubleword being padded downward, and others being padded upward.
+ Not a bad idea as this results in struct { int x; } being passed
+ the same way as an int. */
+#define AGGREGATE_PADDING_FIXED 1
+/* #define AGGREGATES_PAD_UPWARD_ALWAYS 1 */
+
+/* We don't want anything in the reg parm area being passed on the
+ stack. */
+#define MUST_PASS_IN_STACK(MODE, TYPE) \
+ ((TYPE) != 0 \
+ && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
+ || TREE_ADDRESSABLE (TYPE)))
/* __throw will restore its own return address to be the same as the
return address of the function that the throw is being made to.
diff -urp gcc2/gcc/config/rs6000/rs6000.h gcc3/gcc/config/rs6000/rs6000.h
--- gcc2/gcc/config/rs6000/rs6000.h 2003-04-23 11:29:04.000000000 +0930
+++ gcc3/gcc/config/rs6000/rs6000.h 2003-04-24 21:07:17.000000000 +0930
@@ -1701,7 +1701,6 @@ typedef struct rs6000_args
int fregno; /* next available FP register */
int vregno; /* next available AltiVec register */
int nargs_prototype; /* # args left in the current prototype */
- int orig_nargs; /* Original value of nargs_prototype */
int prototype; /* Whether a prototype was defined */
int call_cookie; /* Do special things for this call */
int sysv_gregno; /* next available GP register */
@@ -1832,13 +1831,8 @@ typedef struct rs6000_args
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
rs6000_va_arg (valist, type)
-/* For AIX, the rule is that structures are passed left-aligned in
- their stack slot. However, GCC does not presently do this:
- structures which are the same size as integer types are passed
- right-aligned, as if they were in fact integers. This only
- matters for structures of size 1 or 2, or 4 when TARGET_64BIT.
- ABI_V4 does not use std_expand_builtin_va_arg. */
-#define PAD_VARARGS_DOWN (TYPE_MODE (type) != BLKmode)
+#define PAD_VARARGS_DOWN \
+ (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
/* Define this macro to be a nonzero value if the location where a function
argument is passed depends on whether or not it is a named argument. */
diff -urp gcc2/gcc/config/rs6000/rs6000.c gcc3/gcc/config/rs6000/rs6000.c
--- gcc2/gcc/config/rs6000/rs6000.c 2003-04-24 14:46:04.000000000 +0930
+++ gcc3/gcc/config/rs6000/rs6000.c 2003-04-24 21:43:35.000000000 +0930
@@ -3132,8 +3132,6 @@ init_cumulative_args (cum, fntype, libna
else
cum->nargs_prototype = 0;
- cum->orig_nargs = cum->nargs_prototype;
-
/* Check for a longcall attribute. */
if (fntype
&& lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
@@ -3172,8 +3170,37 @@ function_arg_padding (mode, type)
enum machine_mode mode;
tree type;
{
+#if !AGGREGATE_PADDING_FIXED
+ /* GCC used to pass structures of the same size as integer types as
+ if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
+ ie. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
+ passed padded downward, except that -mstrict-align further
+ muddied the water in that multi-component structures of 2 and 4
+ bytes in size were passed padded upward.
+
+ The following arranges for best compatibility with previous
+ versions of gcc, but removes the -mstrict-align dependency. */
+ if (BYTES_BIG_ENDIAN)
+ {
+ HOST_WIDE_INT size = 0;
+
+ if (mode == BLKmode)
+ {
+ if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
+ size = int_size_in_bytes (type);
+ }
+ else
+ size = GET_MODE_SIZE (mode);
+
+ if (size == 1 || size == 2 || size == 4)
+ return downward;
+ }
+ return upward;
+#else
+#if AGGREGATES_PAD_UPWARD_ALWAYS
if (type != 0 && AGGREGATE_TYPE_P (type))
return upward;
+#endif
/* This is the default definition. */
return (! BYTES_BIG_ENDIAN
@@ -3183,6 +3210,7 @@ function_arg_padding (mode, type)
&& int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
: GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
? downward : upward));
+#endif
}
/* If defined, a C expression that gives the alignment boundary, in bits,
^ permalink raw reply [flat|nested] 875+ messages in thread
* function parms in regs, patch 1 of 3
@ 2003-04-24 15:34 Alan Modra
2003-04-25 22:44 ` Richard Henderson
2003-05-02 5:06 ` function parms in regs, patch 1 " Jim Wilson
0 siblings, 2 replies; 875+ messages in thread
From: Alan Modra @ 2003-04-24 15:34 UTC (permalink / raw)
To: gcc-patches
I've been playing with gcc's function call code over the last week or
so. The goal was to properly pass structures by value in registers,
according to the PowerPC64 ABI, and avoid the problems illustrated
in PR 10397 and PR 10408. What started out as a relatively straight-
forward patch using PARALLELs in rs6000.c:function_arg has grown a
little.. So much so that it needs splitting up.
Patch 1 of 3 (this one) mostly mucks about with locate_and_pad_parm.
Patch 2 of 3 moves special case code out of move_block_from_reg.
Patch 3 of 3 is the new code to handle big-endian reg parms, and
rs6000 specific changes.
Patch 1 and 2 can probably be applied in reverse order as they're
independent, although I haven't tested that. Regression tested
powerpc64-linux after each patch cumulatively applied. I'll also
bootstrap and regression test i686-linux and powerpc-linux again
(these were tested on earlier versions of the patch).
This patch
a) Packages struct arg_data fields set by locate_and_pad_parm into a
separate struct, reducing the number of function parms. The resulting
change to callers happens to fix a bug in emit_library_call_value_1
where alignment_pad was being set for each arg in one loop, then used
in another loop for each arg. ie. we used the last arg's
alignment_pad for all args.
b) Calculates slot_offset in locate_and_pad_parm. This requires an
extra input parm to specify partial-in-reg parms, which also lets us
correct the arg size calculation in the function instead of adjusting
it externally. Incidentally fixes a bug in calls.c:
initialize_argument_information ARGS_GROW_DOWNWARD calculation of
slot_offset for variable size args by deleting the buggy code.
c) Fixes bugs in locate_and_pad_parm handling of initial_offset_ptr.
I can't see anything that guarantees when initial_offset_ptr->var
is non-NULL that initial_offset_ptr->constant == 0, but that's what
the old code assumes.
d) Removes the hacks in locate_and_pad_parm that fudged the stack offset
for pad-down reg parms. Instead we choose slot_offset externally.
Note! For !ARGS_GROW_DOWNWARD, downward padding and non-BLKmode args,
this changes the stack home for a reg arg, which shouldn't be a
problem. I'm raising the point here for full disclosure. :)
e) Optimizes a few things in assign_parms.
* calls.c (struct arg_data): Move offset, slot_offset, size and
alignment_pad to struct locate_and_pad_arg_data. Update all refs.
(initialize_argument_information): Adjust call to locate_and_pad_parm.
Delete alignment_pad var. Don't calculate slot_offset here.
(emit_library_call_value_1): Delete alignment_pad, offset and size
vars. Use struct locate_and_pad_arg_data instead. Adjust refs.
Adjust call to locate_and_pad_parm. Don't tweak arg size for
partial in-regs here. Formatting fixes.
* expr.h (struct locate_and_pad_arg_data): New struct.
(locate_and_pad_parm): Adjust declaration.
* function.c (assign_parms): Localize vars. Use "locate" instead of
other arg location vars. Don't invoke FUNCTION_ARG or
FUNCTION_INCOMING_ARG unless pretend_named is different from
named_arg. Heed MUST_PASS_IN_STACK and set up "partial" before
calling locate_and_pad_parm. Adjust locate_and_pad_parm call.
Use slot_offset for stack home of reg parms. Correct test for
parm passed in memory. Formatting fixes.
(locate_and_pad_parm): Add "partial" to params. Replace offset_ptr
arg_size_ptr and alignment pad with "locate". Set slot_offset here.
Correct initial_offset_ptr handling. Localize vars. Always pad
locate->offset even when in_regs.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
diff -urp gcc.orig/gcc/calls.c gcc1/gcc/calls.c
--- gcc.orig/gcc/calls.c 2003-04-22 18:55:34.000000000 +0930
+++ gcc1/gcc/calls.c 2003-04-24 11:25:45.000000000 +0930
@@ -98,16 +98,8 @@ struct arg_data
even though pass_on_stack is zero, just because FUNCTION_ARG says so.
pass_on_stack identifies arguments that *cannot* go in registers. */
int pass_on_stack;
- /* Offset of this argument from beginning of stack-args. */
- struct args_size offset;
- /* Similar, but offset to the start of the stack slot. Different from
- OFFSET if this arg pads downward. */
- struct args_size slot_offset;
- /* Size of this argument on the stack, rounded up for any padding it gets,
- parts of the argument passed in registers do not count.
- If REG_PARM_STACK_SPACE is defined, then register parms
- are counted here as well. */
- struct args_size size;
+ /* Some fields packaged up for locate_and_pad_parm. */
+ struct locate_and_pad_arg_data locate;
/* Location on the stack at which parameter should be stored. The store
has already been done if STACK == VALUE. */
rtx stack;
@@ -123,9 +115,6 @@ struct arg_data
word-sized pseudos we made. */
rtx *aligned_regs;
int n_aligned_regs;
- /* The amount that the stack pointer needs to be adjusted to
- force alignment for the next argument. */
- struct args_size alignment_pad;
};
/* A vector of one char per byte of stack space. A byte if nonzero if
@@ -1120,7 +1109,6 @@ initialize_argument_information (num_act
/* Count arg position in order args appear. */
int argpos;
- struct args_size alignment_pad;
int i;
tree p;
@@ -1331,39 +1319,14 @@ initialize_argument_information (num_act
#else
args[i].reg != 0,
#endif
- fndecl, args_size, &args[i].offset,
- &args[i].size, &alignment_pad);
-
-#ifndef ARGS_GROW_DOWNWARD
- args[i].slot_offset = *args_size;
-#endif
-
- args[i].alignment_pad = alignment_pad;
-
- /* If a part of the arg was put into registers,
- don't include that part in the amount pushed. */
- if (reg_parm_stack_space == 0 && ! args[i].pass_on_stack)
- args[i].size.constant -= ((args[i].partial * UNITS_PER_WORD)
- / (PARM_BOUNDARY / BITS_PER_UNIT)
- * (PARM_BOUNDARY / BITS_PER_UNIT));
+ args[i].pass_on_stack ? 0 : args[i].partial,
+ fndecl, args_size, &args[i].locate);
/* Update ARGS_SIZE, the total stack space for args so far. */
- args_size->constant += args[i].size.constant;
- if (args[i].size.var)
- {
- ADD_PARM_SIZE (*args_size, args[i].size.var);
- }
-
- /* Since the slot offset points to the bottom of the slot,
- we must record it after incrementing if the args grow down. */
-#ifdef ARGS_GROW_DOWNWARD
- args[i].slot_offset = *args_size;
-
- args[i].slot_offset.constant = -args_size->constant;
- if (args_size->var)
- SUB_PARM_SIZE (args[i].slot_offset, args_size->var);
-#endif
+ args_size->constant += args[i].locate.size.constant;
+ if (args[i].locate.size.var)
+ ADD_PARM_SIZE (*args_size, args[i].locate.size.var);
/* Increment ARGS_SO_FAR, which has info about which arg-registers
have been used, etc. */
@@ -1616,8 +1579,8 @@ compute_argument_addresses (args, argblo
for (i = 0; i < num_actuals; i++)
{
- rtx offset = ARGS_SIZE_RTX (args[i].offset);
- rtx slot_offset = ARGS_SIZE_RTX (args[i].slot_offset);
+ rtx offset = ARGS_SIZE_RTX (args[i].locate.offset);
+ rtx slot_offset = ARGS_SIZE_RTX (args[i].locate.slot_offset);
rtx addr;
/* Skip this parm if it will not be passed on the stack. */
@@ -2060,12 +2023,12 @@ check_sibcall_argument_overlap (insn, ar
if (mark_stored_args_map)
{
#ifdef ARGS_GROW_DOWNWARD
- low = -arg->slot_offset.constant - arg->size.constant;
+ low = -arg->locate.slot_offset.constant - arg->locate.size.constant;
#else
- low = arg->slot_offset.constant;
+ low = arg->locate.slot_offset.constant;
#endif
- for (high = low + arg->size.constant; low < high; low++)
+ for (high = low + arg->locate.size.constant; low < high; low++)
SET_BIT (stored_args_map, low);
}
return insn != NULL_RTX;
@@ -3358,7 +3321,7 @@ expand_call (exp, target, ignore)
emit_move_insn (stack_area, args[i].save_area);
else
emit_block_move (stack_area, args[i].save_area,
- GEN_INT (args[i].size.constant),
+ GEN_INT (args[i].locate.size.constant),
BLOCK_OP_CALL_PARM);
}
@@ -3507,7 +3470,6 @@ emit_library_call_value_1 (retval, orgfu
rtx fun;
int inc;
int count;
- struct args_size alignment_pad;
rtx argblock = 0;
CUMULATIVE_ARGS args_so_far;
struct arg
@@ -3516,8 +3478,7 @@ emit_library_call_value_1 (retval, orgfu
enum machine_mode mode;
rtx reg;
int partial;
- struct args_size offset;
- struct args_size size;
+ struct locate_and_pad_arg_data locate;
rtx save_area;
};
struct arg *argvec;
@@ -3677,12 +3638,11 @@ emit_library_call_value_1 (retval, orgfu
#else
argvec[count].reg != 0,
#endif
- NULL_TREE, &args_size, &argvec[count].offset,
- &argvec[count].size, &alignment_pad);
+ 0, NULL_TREE, &args_size, &argvec[count].locate);
if (argvec[count].reg == 0 || argvec[count].partial != 0
|| reg_parm_stack_space > 0)
- args_size.constant += argvec[count].size.constant;
+ args_size.constant += argvec[count].locate.size.constant;
FUNCTION_ARG_ADVANCE (args_so_far, Pmode, (tree) 0, 1);
@@ -3796,18 +3756,15 @@ emit_library_call_value_1 (retval, orgfu
#else
argvec[count].reg != 0,
#endif
- NULL_TREE, &args_size, &argvec[count].offset,
- &argvec[count].size, &alignment_pad);
+ argvec[count].partial,
+ NULL_TREE, &args_size, &argvec[count].locate);
- if (argvec[count].size.var)
+ if (argvec[count].locate.size.var)
abort ();
- if (reg_parm_stack_space == 0 && argvec[count].partial)
- argvec[count].size.constant -= argvec[count].partial * UNITS_PER_WORD;
-
if (argvec[count].reg == 0 || argvec[count].partial != 0
|| reg_parm_stack_space > 0)
- args_size.constant += argvec[count].size.constant;
+ args_size.constant += argvec[count].locate.size.constant;
FUNCTION_ARG_ADVANCE (args_so_far, mode, (tree) 0, 1);
}
@@ -3945,11 +3902,11 @@ emit_library_call_value_1 (retval, orgfu
#ifdef ARGS_GROW_DOWNWARD
/* stack_slot is negative, but we want to index stack_usage_map
with positive values. */
- upper_bound = -argvec[argnum].offset.constant + 1;
- lower_bound = upper_bound - argvec[argnum].size.constant;
+ upper_bound = -argvec[argnum].locate.offset.constant + 1;
+ lower_bound = upper_bound - argvec[argnum].lcoate.size.constant;
#else
- lower_bound = argvec[argnum].offset.constant;
- upper_bound = lower_bound + argvec[argnum].size.constant;
+ lower_bound = argvec[argnum].locate.offset.constant;
+ upper_bound = lower_bound + argvec[argnum].locate.size.constant;
#endif
i = lower_bound;
@@ -3962,19 +3919,16 @@ emit_library_call_value_1 (retval, orgfu
if (i < upper_bound)
{
- /* We need to make a save area. See what mode we can make
- it. */
+ /* We need to make a save area. */
+ unsigned int size
+ = argvec[argnum].locate.size.constant * BITS_PER_UNIT;
enum machine_mode save_mode
- = mode_for_size (argvec[argnum].size.constant
- * BITS_PER_UNIT,
- MODE_INT, 1);
+ = mode_for_size (size, MODE_INT, 1);
+ rtx adr
+ = plus_constant (argblock,
+ argvec[argnum].locate.offset.constant);
rtx stack_area
- = gen_rtx_MEM
- (save_mode,
- memory_address
- (save_mode,
- plus_constant (argblock,
- argvec[argnum].offset.constant)));
+ = gen_rtx_MEM (save_mode, memory_address (save_mode, adr));
argvec[argnum].save_area = gen_reg_rtx (save_mode);
emit_move_insn (argvec[argnum].save_area, stack_area);
@@ -3983,8 +3937,9 @@ emit_library_call_value_1 (retval, orgfu
emit_push_insn (val, mode, NULL_TREE, NULL_RTX, PARM_BOUNDARY,
partial, reg, 0, argblock,
- GEN_INT (argvec[argnum].offset.constant),
- reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
+ GEN_INT (argvec[argnum].locate.offset.constant),
+ reg_parm_stack_space,
+ ARGS_SIZE_RTX (argvec[argnum].locate.alignment_pad));
/* Now mark the segment we just used. */
if (ACCUMULATE_OUTGOING_ARGS)
@@ -4189,12 +4144,10 @@ emit_library_call_value_1 (retval, orgfu
if (argvec[count].save_area)
{
enum machine_mode save_mode = GET_MODE (argvec[count].save_area);
- rtx stack_area
- = gen_rtx_MEM (save_mode,
- memory_address
- (save_mode,
- plus_constant (argblock,
- argvec[count].offset.constant)));
+ rtx adr = plus_constant (argblock,
+ argvec[count].locate.offset.constant);
+ rtx stack_area = gen_rtx_MEM (save_mode,
+ memory_address (save_mode, adr));
emit_move_insn (stack_area, argvec[count].save_area);
}
@@ -4321,14 +4274,14 @@ store_one_arg (arg, argblock, flags, var
else
upper_bound = 0;
- lower_bound = upper_bound - arg->size.constant;
+ lower_bound = upper_bound - arg->locate.size.constant;
#else
if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS)
lower_bound = INTVAL (XEXP (XEXP (arg->stack_slot, 0), 1));
else
lower_bound = 0;
- upper_bound = lower_bound + arg->size.constant;
+ upper_bound = lower_bound + arg->locate.size.constant;
#endif
i = lower_bound;
@@ -4341,13 +4294,11 @@ store_one_arg (arg, argblock, flags, var
if (i < upper_bound)
{
- /* We need to make a save area. See what mode we can make it. */
- enum machine_mode save_mode
- = mode_for_size (arg->size.constant * BITS_PER_UNIT, MODE_INT, 1);
- rtx stack_area
- = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- XEXP (arg->stack_slot, 0)));
+ /* We need to make a save area. */
+ unsigned int size = arg->locate.size.constant * BITS_PER_UNIT;
+ enum machine_mode save_mode = mode_for_size (size, MODE_INT, 1);
+ rtx adr = memory_address (save_mode, XEXP (arg->stack_slot, 0));
+ rtx stack_area = gen_rtx_MEM (save_mode, adr);
if (save_mode == BLKmode)
{
@@ -4475,8 +4426,8 @@ store_one_arg (arg, argblock, flags, var
This can either be done with push or copy insns. */
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX,
PARM_BOUNDARY, partial, reg, used - size, argblock,
- ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
- ARGS_SIZE_RTX (arg->alignment_pad));
+ ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space,
+ ARGS_SIZE_RTX (arg->locate.alignment_pad));
/* Unless this is a partially-in-register argument, the argument is now
in the stack. */
@@ -4498,16 +4449,17 @@ store_one_arg (arg, argblock, flags, var
/* Round its size up to a multiple
of the allocation unit for arguments. */
- if (arg->size.var != 0)
+ if (arg->locate.size.var != 0)
{
excess = 0;
- size_rtx = ARGS_SIZE_RTX (arg->size);
+ size_rtx = ARGS_SIZE_RTX (arg->locate.size);
}
else
{
/* PUSH_ROUNDING has no effect on us, because
emit_push_insn for BLKmode is careful to avoid it. */
- excess = (arg->size.constant - int_size_in_bytes (TREE_TYPE (pval))
+ excess = (arg->locate.size.constant
+ - int_size_in_bytes (TREE_TYPE (pval))
+ partial * UNITS_PER_WORD);
size_rtx = expand_expr (size_in_bytes (TREE_TYPE (pval)),
NULL_RTX, TYPE_MODE (sizetype), 0);
@@ -4521,7 +4473,7 @@ store_one_arg (arg, argblock, flags, var
PARM_BOUNDARY, but the actual argument isn't. */
if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
{
- if (arg->size.var)
+ if (arg->locate.size.var)
parm_align = BITS_PER_UNIT;
else if (excess)
{
@@ -4533,7 +4485,7 @@ store_one_arg (arg, argblock, flags, var
if ((flags & ECF_SIBCALL) && GET_CODE (arg->value) == MEM)
{
/* emit_push_insn might not work properly if arg->value and
- argblock + arg->offset areas overlap. */
+ argblock + arg->locate.offset areas overlap. */
rtx x = arg->value;
int i = 0;
@@ -4547,17 +4499,17 @@ store_one_arg (arg, argblock, flags, var
i = INTVAL (XEXP (XEXP (x, 0), 1));
/* expand_call should ensure this */
- if (arg->offset.var || GET_CODE (size_rtx) != CONST_INT)
+ if (arg->locate.offset.var || GET_CODE (size_rtx) != CONST_INT)
abort ();
- if (arg->offset.constant > i)
+ if (arg->locate.offset.constant > i)
{
- if (arg->offset.constant < i + INTVAL (size_rtx))
+ if (arg->locate.offset.constant < i + INTVAL (size_rtx))
sibcall_failure = 1;
}
- else if (arg->offset.constant < i)
+ else if (arg->locate.offset.constant < i)
{
- if (i < arg->offset.constant + INTVAL (size_rtx))
+ if (i < arg->locate.offset.constant + INTVAL (size_rtx))
sibcall_failure = 1;
}
}
@@ -4565,8 +4517,8 @@ store_one_arg (arg, argblock, flags, var
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
parm_align, partial, reg, excess, argblock,
- ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
- ARGS_SIZE_RTX (arg->alignment_pad));
+ ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space,
+ ARGS_SIZE_RTX (arg->locate.alignment_pad));
/* Unless this is a partially-in-register argument, the argument is now
in the stack.
diff -urp gcc.orig/gcc/expr.h gcc1/gcc/expr.h
--- gcc.orig/gcc/expr.h 2003-04-22 18:55:34.000000000 +0930
+++ gcc1/gcc/expr.h 2003-04-24 11:29:11.000000000 +0930
@@ -63,6 +63,8 @@ enum expand_modifier {EXPAND_NORMAL = 0,
more information. */
#define OK_DEFER_POP (inhibit_defer_pop -= 1)
\f
+enum direction {none, upward, downward};
+
#ifdef TREE_CODE /* Don't lose if tree.h not included. */
/* Structure to record the size of a sequence of arguments
as the sum of a tree-expression and a constant. This structure is
@@ -74,6 +76,24 @@ struct args_size
HOST_WIDE_INT constant;
tree var;
};
+
+/* Package up various arg related fields of struct args for
+ locate_and_pad_parm. */
+struct locate_and_pad_arg_data
+{
+ /* Size of this argument on the stack, rounded up for any padding it
+ gets. If REG_PARM_STACK_SPACE is defined, then register parms are
+ counted here, otherwise they aren't. */
+ struct args_size size;
+ /* Offset of this argument from beginning of stack-args. */
+ struct args_size offset;
+ /* Offset to the start of the stack slot. Different from OFFSET
+ if this arg pads downward. */
+ struct args_size slot_offset;
+ /* The amount that the stack pointer needs to be adjusted to
+ force alignment for the next argument. */
+ struct args_size alignment_pad;
+};
#endif
/* Add the value of the tree INC to the `struct args_size' TO. */
@@ -119,8 +139,6 @@ do { \
usually pad upward, but pad short args downward on
big-endian machines. */
-enum direction {none, upward, downward}; /* Value has this type. */
-
#ifndef FUNCTION_ARG_PADDING
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
(! BYTES_BIG_ENDIAN \
@@ -567,11 +585,9 @@ extern rtx expand_shift PARAMS ((enum tr
rtx, int));
extern rtx expand_divmod PARAMS ((int, enum tree_code, enum machine_mode, rtx,
rtx, rtx, int));
-extern void locate_and_pad_parm PARAMS ((enum machine_mode, tree, int, tree,
- struct args_size *,
- struct args_size *,
- struct args_size *,
- struct args_size *));
+extern void locate_and_pad_parm PARAMS ((enum machine_mode, tree, int, int,
+ tree, struct args_size *,
+ struct locate_and_pad_arg_data *));
extern rtx expand_inline_function PARAMS ((tree, tree, rtx, int, tree, rtx));
/* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary. */
diff -urp gcc.orig/gcc/function.c gcc1/gcc/function.c
--- gcc.orig/gcc/function.c 2003-04-23 11:29:02.000000000 +0930
+++ gcc1/gcc/function.c 2003-04-24 17:50:45.000000000 +0930
@@ -4338,12 +4338,7 @@ assign_parms (fndecl)
tree fndecl;
{
tree parm;
- rtx entry_parm = 0;
- rtx stack_parm = 0;
CUMULATIVE_ARGS args_so_far;
- enum machine_mode promoted_mode, passed_mode;
- enum machine_mode nominal_mode, promoted_nominal_mode;
- int unsignedp;
/* Total space needed so far for args on the stack,
given as a constant and a tree-expression. */
struct args_size stack_args_size;
@@ -4357,8 +4352,8 @@ assign_parms (fndecl)
#ifdef SETUP_INCOMING_VARARGS
int varargs_setup = 0;
#endif
+ int reg_parm_stack_space = 0;
rtx conversion_insns = 0;
- struct args_size alignment_pad;
/* Nonzero if function takes extra anonymous args.
This means the last named arg must be on the stack
@@ -4405,6 +4400,14 @@ assign_parms (fndecl)
max_parm_reg = LAST_VIRTUAL_REGISTER + 1;
parm_reg_stack_loc = (rtx *) ggc_alloc_cleared (max_parm_reg * sizeof (rtx));
+#ifdef REG_PARM_STACK_SPACE
+#ifdef MAYBE_REG_PARM_STACK_SPACE
+ reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
+#else
+ reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
+#endif
+#endif
+
#ifdef INIT_CUMULATIVE_INCOMING_ARGS
INIT_CUMULATIVE_INCOMING_ARGS (args_so_far, fntype, NULL_RTX);
#else
@@ -4417,14 +4420,19 @@ assign_parms (fndecl)
for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
{
- struct args_size stack_offset;
- struct args_size arg_size;
+ rtx entry_parm;
+ rtx stack_parm;
+ enum machine_mode promoted_mode, passed_mode;
+ enum machine_mode nominal_mode, promoted_nominal_mode;
+ int unsignedp;
+ struct locate_and_pad_arg_data locate;
int passed_pointer = 0;
int did_conversion = 0;
tree passed_type = DECL_ARG_TYPE (parm);
tree nominal_type = TREE_TYPE (parm);
- int pretend_named;
int last_named = 0, named_arg;
+ int in_regs;
+ int partial = 0;
/* Set LAST_NAMED if this is last named arg before last
anonymous args. */
@@ -4488,7 +4496,7 @@ assign_parms (fndecl)
|| TREE_ADDRESSABLE (passed_type)
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
|| FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, passed_mode,
- passed_type, named_arg)
+ passed_type, named_arg)
#endif
)
{
@@ -4558,27 +4566,52 @@ assign_parms (fndecl)
it came in a register so that REG_PARM_STACK_SPACE isn't skipped.
In this case, we call FUNCTION_ARG with NAMED set to 1 instead of
0 as it was the previous time. */
-
- pretend_named = named_arg || PRETEND_OUTGOING_VARARGS_NAMED;
- locate_and_pad_parm (promoted_mode, passed_type,
+ in_regs = entry_parm != 0;
#ifdef STACK_PARMS_IN_REG_PARM_AREA
- 1,
-#else
+ in_regs = 1;
+#endif
+ if (!in_regs && !named_arg)
+ {
+ int pretend_named = PRETEND_OUTGOING_VARARGS_NAMED;
+ if (pretend_named)
+ {
#ifdef FUNCTION_INCOMING_ARG
- FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
- passed_type,
- pretend_named) != 0,
+ in_regs = FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
+ passed_type,
+ pretend_named) != 0;
#else
- FUNCTION_ARG (args_so_far, promoted_mode,
- passed_type,
- pretend_named) != 0,
+ in_regs = FUNCTION_ARG (args_so_far, promoted_mode,
+ passed_type,
+ pretend_named) != 0;
#endif
+ }
+ }
+
+ /* If this parameter was passed both in registers and in the stack,
+ use the copy on the stack. */
+ if (MUST_PASS_IN_STACK (promoted_mode, passed_type))
+ entry_parm = 0;
+
+#ifdef FUNCTION_ARG_PARTIAL_NREGS
+ if (entry_parm)
+ partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, promoted_mode,
+ passed_type, named_arg);
#endif
- fndecl, &stack_args_size, &stack_offset, &arg_size,
- &alignment_pad);
+
+ memset (&locate, 0, sizeof (locate));
+ locate_and_pad_parm (promoted_mode, passed_type, in_regs,
+ entry_parm ? partial : 0, fndecl,
+ &stack_args_size, &locate);
{
- rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);
+ rtx offset_rtx;
+
+ /* If we're passing this arg using a reg, make its stack home
+ the aligned stack slot. */
+ if (entry_parm)
+ offset_rtx = ARGS_SIZE_RTX (locate.slot_offset);
+ else
+ offset_rtx = ARGS_SIZE_RTX (locate.offset);
if (offset_rtx == const0_rtx)
stack_parm = gen_rtx_MEM (promoted_mode, internal_arg_pointer);
@@ -4595,12 +4628,6 @@ assign_parms (fndecl)
set_reg_attrs_for_parm (entry_parm, stack_parm);
}
- /* If this parameter was passed both in registers and in the stack,
- use the copy on the stack. */
- if (MUST_PASS_IN_STACK (promoted_mode, passed_type))
- entry_parm = 0;
-
-#ifdef FUNCTION_ARG_PARTIAL_NREGS
/* If this parm was passed part in regs and part in memory,
pretend it arrived entirely in memory
by pushing the register-part onto the stack.
@@ -4609,39 +4636,31 @@ assign_parms (fndecl)
we could put it together in a pseudoreg directly,
but for now that's not worth bothering with. */
- if (entry_parm)
+ if (partial)
{
- int nregs = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, promoted_mode,
- passed_type, named_arg);
-
- if (nregs > 0)
- {
-#if defined (REG_PARM_STACK_SPACE) && !defined (MAYBE_REG_PARM_STACK_SPACE)
- /* When REG_PARM_STACK_SPACE is nonzero, stack space for
- split parameters was allocated by our caller, so we
- won't be pushing it in the prolog. */
- if (REG_PARM_STACK_SPACE (fndecl) == 0)
-#endif
- current_function_pretend_args_size
- = (((nregs * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
- / (PARM_BOUNDARY / BITS_PER_UNIT)
- * (PARM_BOUNDARY / BITS_PER_UNIT));
+#ifndef MAYBE_REG_PARM_STACK_SPACE
+ /* When REG_PARM_STACK_SPACE is nonzero, stack space for
+ split parameters was allocated by our caller, so we
+ won't be pushing it in the prolog. */
+ if (reg_parm_stack_space)
+#endif
+ current_function_pretend_args_size
+ = (((partial * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
+ / (PARM_BOUNDARY / BITS_PER_UNIT)
+ * (PARM_BOUNDARY / BITS_PER_UNIT));
- /* Handle calls that pass values in multiple non-contiguous
- locations. The Irix 6 ABI has examples of this. */
- if (GET_CODE (entry_parm) == PARALLEL)
- emit_group_store (validize_mem (stack_parm), entry_parm,
- int_size_in_bytes (TREE_TYPE (parm)));
+ /* Handle calls that pass values in multiple non-contiguous
+ locations. The Irix 6 ABI has examples of this. */
+ if (GET_CODE (entry_parm) == PARALLEL)
+ emit_group_store (validize_mem (stack_parm), entry_parm,
+ int_size_in_bytes (TREE_TYPE (parm)));
- else
- move_block_from_reg (REGNO (entry_parm),
- validize_mem (stack_parm), nregs,
- int_size_in_bytes (TREE_TYPE (parm)));
+ else
+ move_block_from_reg (REGNO (entry_parm), validize_mem (stack_parm),
+ partial, int_size_in_bytes (TREE_TYPE (parm)));
- entry_parm = stack_parm;
- }
+ entry_parm = stack_parm;
}
-#endif
/* If we didn't decide this parm came in a register,
by default it came on the stack. */
@@ -4672,9 +4691,9 @@ assign_parms (fndecl)
#endif
)
{
- stack_args_size.constant += arg_size.constant;
- if (arg_size.var)
- ADD_PARM_SIZE (stack_args_size, arg_size.var);
+ stack_args_size.constant += locate.size.constant;
+ if (locate.size.var)
+ ADD_PARM_SIZE (stack_args_size, locate.size.var);
}
else
/* No stack slot was pushed for this parm. */
@@ -4698,7 +4717,7 @@ assign_parms (fndecl)
/* If parm was passed in memory, and we need to convert it on entry,
don't store it back in that same slot. */
- if (entry_parm != 0
+ if (entry_parm == stack_parm
&& nominal_mode != BLKmode && nominal_mode != passed_mode)
stack_parm = 0;
@@ -5021,7 +5040,7 @@ assign_parms (fndecl)
&& ! did_conversion
&& stack_parm != 0
&& GET_CODE (stack_parm) == MEM
- && stack_offset.var == 0
+ && locate.offset.var == 0
&& reg_mentioned_p (virtual_incoming_args_rtx,
XEXP (stack_parm, 0)))
{
@@ -5107,7 +5126,8 @@ assign_parms (fndecl)
{
stack_parm
= assign_stack_local (GET_MODE (entry_parm),
- GET_MODE_SIZE (GET_MODE (entry_parm)), 0);
+ GET_MODE_SIZE (GET_MODE (entry_parm)),
+ 0);
set_mem_attributes (stack_parm, parm, 1);
}
@@ -5278,8 +5298,11 @@ promoted_input_arg (regno, pmode, punsig
INITIAL_OFFSET_PTR points to the current offset into the stacked
arguments.
- The starting offset and size for this parm are returned in *OFFSET_PTR
- and *ARG_SIZE_PTR, respectively.
+ The starting offset and size for this parm are returned in
+ LOCATE->OFFSET and LOCATE->SIZE, respectively. When IN_REGS is
+ nonzero, the offset is that of stack slot, which is returned in
+ LOCATE->SLOT_OFFSET. LOCATE->ALIGNMENT_PAD is the amount of
+ padding required from the initial offset ptr to the stack slot.
IN_REGS is nonzero if the argument will be passed in registers. It will
never be set if REG_PARM_STACK_SPACE is not defined.
@@ -5296,45 +5319,39 @@ promoted_input_arg (regno, pmode, punsig
initial offset is not affected by this rounding, while the size always
is and the starting offset may be. */
-/* offset_ptr will be negative for ARGS_GROW_DOWNWARD case;
- initial_offset_ptr is positive because locate_and_pad_parm's
+/* LOCATE->OFFSET will be negative for ARGS_GROW_DOWNWARD case;
+ INITIAL_OFFSET_PTR is positive because locate_and_pad_parm's
callers pass in the total size of args so far as
- initial_offset_ptr. arg_size_ptr is always positive. */
+ INITIAL_OFFSET_PTR. LOCATE->SIZE is always positive. */
void
-locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
- initial_offset_ptr, offset_ptr, arg_size_ptr,
- alignment_pad)
+locate_and_pad_parm (passed_mode, type, in_regs, partial, fndecl,
+ initial_offset_ptr, locate)
enum machine_mode passed_mode;
tree type;
- int in_regs ATTRIBUTE_UNUSED;
+ int in_regs;
+ int partial;
tree fndecl ATTRIBUTE_UNUSED;
struct args_size *initial_offset_ptr;
- struct args_size *offset_ptr;
- struct args_size *arg_size_ptr;
- struct args_size *alignment_pad;
-
+ struct locate_and_pad_arg_data *locate;
{
- tree sizetree
- = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
- enum direction where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
- int boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
-#ifdef ARGS_GROW_DOWNWARD
- tree s2 = sizetree;
-#endif
+ tree sizetree;
+ enum direction where_pad;
+ int boundary;
+ int reg_parm_stack_space = 0;
+ int part_size_in_regs;
#ifdef REG_PARM_STACK_SPACE
+#ifdef MAYBE_REG_PARM_STACK_SPACE
+ reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
+#else
+ reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
+#endif
+
/* If we have found a stack parm before we reach the end of the
area reserved for registers, skip that area. */
if (! in_regs)
{
- int reg_parm_stack_space = 0;
-
-#ifdef MAYBE_REG_PARM_STACK_SPACE
- reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
-#else
- reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
-#endif
if (reg_parm_stack_space > 0)
{
if (initial_offset_ptr->var)
@@ -5350,54 +5367,56 @@ locate_and_pad_parm (passed_mode, type,
}
#endif /* REG_PARM_STACK_SPACE */
- arg_size_ptr->var = 0;
- arg_size_ptr->constant = 0;
- alignment_pad->var = 0;
- alignment_pad->constant = 0;
+ part_size_in_regs = 0;
+ if (reg_parm_stack_space == 0)
+ part_size_in_regs = ((partial * UNITS_PER_WORD)
+ / (PARM_BOUNDARY / BITS_PER_UNIT)
+ * (PARM_BOUNDARY / BITS_PER_UNIT));
+
+ sizetree
+ = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
+ where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
+ boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
#ifdef ARGS_GROW_DOWNWARD
+ locate->slot_offset.constant = -initial_offset_ptr->constant;
if (initial_offset_ptr->var)
- {
- offset_ptr->constant = 0;
- offset_ptr->var = size_binop (MINUS_EXPR, ssize_int (0),
- initial_offset_ptr->var);
- }
- else
- {
- offset_ptr->constant = -initial_offset_ptr->constant;
- offset_ptr->var = 0;
- }
+ locate->slot_offset.var = size_binop (MINUS_EXPR, ssize_int (0),
+ initial_offset_ptr->var);
- if (where_pad != none
- && (!host_integerp (sizetree, 1)
- || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
- s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT);
- SUB_PARM_SIZE (*offset_ptr, s2);
+ {
+ tree s2 = sizetree;
+ if (where_pad != none
+ && (!host_integerp (sizetree, 1)
+ || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
+ s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT);
+ SUB_PARM_SIZE (locate->slot_offset, s2);
+ }
+
+ locate->slot_offset.constant += part_size_in_regs;
if (!in_regs
#ifdef REG_PARM_STACK_SPACE
|| REG_PARM_STACK_SPACE (fndecl) > 0
#endif
)
- pad_to_arg_alignment (offset_ptr, boundary, alignment_pad);
+ pad_to_arg_alignment (&locate->slot_offset, boundary,
+ &locate->alignment_pad);
+ locate->size.constant = (-initial_offset_ptr->constant
+ - locate->slot_offset.constant);
if (initial_offset_ptr->var)
- arg_size_ptr->var = size_binop (MINUS_EXPR,
- size_binop (MINUS_EXPR,
- ssize_int (0),
- initial_offset_ptr->var),
- offset_ptr->var);
-
- else
- arg_size_ptr->constant = (-initial_offset_ptr->constant
- - offset_ptr->constant);
-
- /* Pad_below needs the pre-rounded size to know how much to pad below.
- We only pad parameters which are not in registers as they have their
- padding done elsewhere. */
- if (where_pad == downward
- && !in_regs)
- pad_below (offset_ptr, passed_mode, sizetree);
+ locate->size.var = size_binop (MINUS_EXPR,
+ size_binop (MINUS_EXPR,
+ ssize_int (0),
+ initial_offset_ptr->var),
+ locate->slot_offset.var);
+
+ /* Pad_below needs the pre-rounded size to know how much to pad
+ below. */
+ locate->offset = locate->slot_offset;
+ if (where_pad == downward)
+ pad_below (&locate->offset, passed_mode, sizetree);
#else /* !ARGS_GROW_DOWNWARD */
if (!in_regs
@@ -5405,8 +5424,9 @@ locate_and_pad_parm (passed_mode, type,
|| REG_PARM_STACK_SPACE (fndecl) > 0
#endif
)
- pad_to_arg_alignment (initial_offset_ptr, boundary, alignment_pad);
- *offset_ptr = *initial_offset_ptr;
+ pad_to_arg_alignment (initial_offset_ptr, boundary,
+ &locate->alignment_pad);
+ locate->slot_offset = *initial_offset_ptr;
#ifdef PUSH_ROUNDING
if (passed_mode != BLKmode)
@@ -5415,18 +5435,18 @@ locate_and_pad_parm (passed_mode, type,
/* Pad_below needs the pre-rounded size to know how much to pad below
so this must be done before rounding up. */
- if (where_pad == downward
- /* However, BLKmode args passed in regs have their padding done elsewhere.
- The stack slot must be able to hold the entire register. */
- && !(in_regs && passed_mode == BLKmode))
- pad_below (offset_ptr, passed_mode, sizetree);
+ locate->offset = locate->slot_offset;
+ if (where_pad == downward)
+ pad_below (&locate->offset, passed_mode, sizetree);
if (where_pad != none
&& (!host_integerp (sizetree, 1)
|| (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
- ADD_PARM_SIZE (*arg_size_ptr, sizetree);
+ ADD_PARM_SIZE (locate->size, sizetree);
+
+ locate->size.constant -= part_size_in_regs;
#endif /* ARGS_GROW_DOWNWARD */
}
@@ -5465,7 +5485,8 @@ pad_to_arg_alignment (offset_ptr, bounda
#endif
(ARGS_SIZE_TREE (*offset_ptr),
boundary / BITS_PER_UNIT);
- offset_ptr->constant = 0; /*?*/
+ /* ARGS_SIZE_TREE includes constant term. */
+ offset_ptr->constant = 0;
if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var,
save_var);
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: function parms in regs, patch 1 of 3
2003-04-24 15:34 function parms in regs, patch 1 of 3 Alan Modra
@ 2003-04-25 22:44 ` Richard Henderson
2003-04-26 0:33 ` Janis Johnson
2003-04-27 23:34 ` Alan Modra
2003-05-02 5:06 ` function parms in regs, patch 1 " Jim Wilson
1 sibling, 2 replies; 875+ messages in thread
From: Richard Henderson @ 2003-04-25 22:44 UTC (permalink / raw)
To: gcc-patches
On Fri, Apr 25, 2003 at 01:04:16AM +0930, Alan Modra wrote:
> Patch 1 and 2 can probably be applied in reverse order as they're
> independent, although I haven't tested that. Regression tested
> powerpc64-linux after each patch cumulatively applied. I'll also
> bootstrap and regression test i686-linux and powerpc-linux again
> (these were tested on earlier versions of the patch).
I think you need to test this more places. Particularly at least
one ARGS_GROW_DOWNWARD machine:
> + lower_bound = upper_bound - argvec[argnum].lcoate.size.constant;
^^^
It looks reasonable in concept, but I worry about silent ABI
changes.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: function parms in regs, patch 1 of 3
2003-04-25 22:44 ` Richard Henderson
@ 2003-04-26 0:33 ` Janis Johnson
2003-04-27 23:34 ` Alan Modra
1 sibling, 0 replies; 875+ messages in thread
From: Janis Johnson @ 2003-04-26 0:33 UTC (permalink / raw)
To: Richard Henderson, gcc-patches
On Fri, Apr 25, 2003 at 03:43:00PM -0700, Richard Henderson wrote:
> It looks reasonable in concept, but I worry about silent ABI
> changes.
I'm planning to add some binary compatibility tests for C, as well as
adding to the C++ tests in g++/compat. These let you compile pieces of
a test with the compiler under test plus a different version of GCC (or,
in theory, an entirely different compiler). I'll start with tests for
argument passing and function return, including structs, and including
structs with specific attributes. Suggestions for constructs to include
in these tests would be most welcome.
Janis
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: function parms in regs, patch 1 of 3
2003-04-25 22:44 ` Richard Henderson
2003-04-26 0:33 ` Janis Johnson
@ 2003-04-27 23:34 ` Alan Modra
2003-04-30 13:29 ` function parms in regs, patch 3 " Alan Modra
1 sibling, 1 reply; 875+ messages in thread
From: Alan Modra @ 2003-04-27 23:34 UTC (permalink / raw)
To: Richard Henderson, gcc-patches
On Fri, Apr 25, 2003 at 03:43:00PM -0700, Richard Henderson wrote:
> On Fri, Apr 25, 2003 at 01:04:16AM +0930, Alan Modra wrote:
> I think you need to test this more places. Particularly at least
> one ARGS_GROW_DOWNWARD machine:
>
> > + lower_bound = upper_bound - argvec[argnum].lcoate.size.constant;
Oops. Indeed. Testing hppa-linux. My old 80MHz PA box is going to
take a while to do a bootstrap..
> It looks reasonable in concept, but I worry about silent ABI
> changes.
Yes, it's tedious to prove that a patch like this is safe. For that
reason I'm going to withdraw the emit_group_load/store patches and
concentrate on proving that the rest is reasonably safe.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: function parms in regs, patch 3 of 3
2003-04-27 23:34 ` Alan Modra
@ 2003-04-30 13:29 ` Alan Modra
2003-05-02 6:05 ` Jim Wilson
2003-07-10 6:55 ` Jim Wilson
0 siblings, 2 replies; 875+ messages in thread
From: Alan Modra @ 2003-04-30 13:29 UTC (permalink / raw)
To: gcc-patches, Richard Henderson
On Mon, Apr 28, 2003 at 09:04:30AM +0930, Alan Modra wrote:
> concentrate on proving that the rest is reasonably safe.
Famous last words. Some musings on the previous BLOCK_REG_PADDING
patch. Firstly, it's fairly easy to see that targets that use the
default FUNCTION_ARG_PADDING will have no change in behaviour. The
extra code and changed tests are to support different padding from the
usual, and in every case we're operating with args strictly less than
UNITS_PER_WORD in size.
Now for the other cases. The following files define
FUNCTION_ARG_PADDING:
alpha/alpha.h: Defined as upward, but BYTES_BIG_ENDIAN == 0, so this
is the same as the default. alpha/unicosmk.h defines BYTES_BIG_ENDIAN
to 1, but #undefs FUNCTION_ARG_PADDING.
m68k/3b1.h: The same as the default for BYTES_BIG_ENDIAN and
sizes less than a word.
m68k/3b1g.h: Ditto.
m68k/crds.h: Ditto.
m88k/m88k.h: Pads BLKmode, structs and unions upwards, but
m88k_function_arg puts them on the stack unless size is
UNITS_PER_WORD. Since the changes I made only affect register parms,
we're OK here too.
mips/mips.h: MIPS uses the standard FUNCTION_ARG_PADDING, but with
some extra tests on ABI that can cause small args to pad upwards. It
looks to me like the extra tests are for float args, in which case we
should be OK here too.
pa/pa.h: PA has its own function_arg_padding, but uses
PARALLELs in function_arg for the cases where padding is different
from the default. Should be OK, I think.
rs6000/rs6000.h: This is the one I _want_ to change, at least for
powerpc64-linux. :)
sparc/sparc.h: The default FUNCTION_ARG_PADDING, but aggregates pad
upwards for TARGET_ARCH64. I think my patch will change behaviour
for small unions of 1, 2 and 4 bytes in size.
ia64/hpux.h: The default FUNCTION_ARG_PADDING, but aggregates pad
upwards. PARALLELs are used to for aggregates, so there shouldn't be
any surprises here.
m68hc11/m68hc11.h: Here, it looks like aggregates want to pad upwards,
but no special code is added to make that actually happen in
m68hc11_function_arg. My patch will change behaviour.
So, given that the previous patch will change argument padding in
two targets, even though the current behaviour is probably a bug,
here's a patch that just uses BLOCK_REG_PADDING for rs6000.
* expr.h (struct locate_and_pad_arg_data): Add where_pad.
(emit_group_load, emit_group_store): Adjust declarations.
* expr.c (emit_group_load): Add "type" param, and use
BLOCK_REG_PADDING to determine need for a shift. Optimize non-
aligned accesses if !SLOW_UNALIGNED_ACCESS.
(emit_group_store): Likewise.
(emit_push_insn, expand_assignment, store_expr, expand_expr): Adjust
emit_group_load and emit_group_store calls.
* calls.c (store_unaligned_arguments_into_pseudos): Tidy. Use
BLOCK_REG_PADDING to determine whether we need endian_correction.
(load_register_parameters): Localize vars. Handle shifting of
small values to the correct end of regs. Adjust emit_group_load
call.
(expand_call, emit_library_call_value_1): Adjust emit_group_load
and emit_group_store calls.
* function.c (assign_parms): Set mem alignment for stack slots.
Adjust emit_group_store call. Store values at the "wrong" end
of regs to the stack. Use BLOCK_REG_PADDING.
(locate_and_pad_parm): Save where_pad.
(expand_function_end): Adjust emit_group_load call.
* stmt.c (expand_value_return): Adjust emit_group_load call.
* Makefile.in (calls.o): Depend on $(OPTABS_H).
* config/rs6000/linux64.h (TARGET_BIG_ENDIAN): Redefine as 1.
(FIXED_R13): Delete.
(AGGREGATE_PADDING_FIXED): Define.
(MUST_PASS_IN_STACK): Define.
(BLOCK_REG_PADDING): Define.
* config/rs6000/rs6000.h (struct rs6000_args): Remove orig_nargs.
(PAD_VARARGS_DOWN): Define in terms of FUNCTION_ARG_PADDING.
* config/rs6000/rs6000.c (init_cumulative_args): Don't set orig_nargs.
(function_arg_padding): !AGGREGATE_PADDING_FIXED compatibility code.
Act on AGGREGATES_PAD_UPWARD_ALWAYS.
Regression tested powerpc64-linux. Bootstrapped hppa-linux,
regression testing still in progress.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
diff -urp gcc2/gcc/expr.h gcc3/gcc/expr.h
--- gcc2/gcc/expr.h 2003-04-24 15:31:56.000000000 +0930
+++ gcc3/gcc/expr.h 2003-04-30 14:37:09.000000000 +0930
@@ -93,6 +93,8 @@ struct locate_and_pad_arg_data
/* The amount that the stack pointer needs to be adjusted to
force alignment for the next argument. */
struct args_size alignment_pad;
+ /* Which way we should pad this arg. */
+ enum direction where_pad;
};
#endif
@@ -416,19 +418,21 @@ extern void move_block_from_reg PARAMS (
/* Generate a non-consecutive group of registers represented by a PARALLEL. */
extern rtx gen_group_rtx PARAMS ((rtx));
+#ifdef TREE_CODE
/* Load a BLKmode value into non-consecutive registers represented by a
PARALLEL. */
-extern void emit_group_load PARAMS ((rtx, rtx, int));
+extern void emit_group_load PARAMS ((rtx, rtx, tree, int));
+#endif
/* Move a non-consecutive group of registers represented by a PARALLEL into
a non-consecutive group of registers represented by a PARALLEL. */
extern void emit_group_move PARAMS ((rtx, rtx));
+#ifdef TREE_CODE
/* Store a BLKmode value from non-consecutive registers represented by a
PARALLEL. */
-extern void emit_group_store PARAMS ((rtx, rtx, int));
+extern void emit_group_store PARAMS ((rtx, rtx, tree, int));
-#ifdef TREE_CODE
/* Copy BLKmode object from a set of registers. */
extern rtx copy_blkmode_from_reg PARAMS ((rtx, rtx, tree));
#endif
diff -urp gcc2/gcc/expr.c gcc3/gcc/expr.c
--- gcc2/gcc/expr.c 2003-04-24 14:46:04.000000000 +0930
+++ gcc3/gcc/expr.c 2003-04-30 14:33:24.000000000 +0930
@@ -2212,19 +2212,15 @@ gen_group_rtx (orig)
return gen_rtx_PARALLEL (GET_MODE (orig), gen_rtvec_v (length, tmps));
}
-/* Emit code to move a block SRC to a block DST, where DST is non-consecutive
- registers represented by a PARALLEL. SSIZE represents the total size of
- block SRC in bytes, or -1 if not known. */
-/* ??? If SSIZE % UNITS_PER_WORD != 0, we make the blatant assumption that
- the balance will be in what would be the low-order memory addresses, i.e.
- left justified for big endian, right justified for little endian. This
- happens to be true for the targets currently using this support. If this
- ever changes, a new target macro along the lines of FUNCTION_ARG_PADDING
- would be needed. */
+/* Emit code to move a block ORIG_SRC of type TYPE to a block DST,
+ where DST is non-consecutive registers represented by a PARALLEL.
+ SSIZE represents the total size of block ORIG_SRC in bytes, or -1
+ if not known. */
void
-emit_group_load (dst, orig_src, ssize)
+emit_group_load (dst, orig_src, type, ssize)
rtx dst, orig_src;
+ tree type ATTRIBUTE_UNUSED;
int ssize;
{
rtx *tmps, src;
@@ -2253,7 +2249,17 @@ emit_group_load (dst, orig_src, ssize)
/* Handle trailing fragments that run over the size of the struct. */
if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
{
- shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
+ /* Arrange to shift the fragment to where it belongs.
+ extract_bit_field loads to the lsb of the reg. */
+ if (
+#ifdef BLOCK_REG_PADDING
+ BLOCK_REG_PADDING (GET_MODE (orig_src), type, i == start)
+ == (BYTES_BIG_ENDIAN ? upward : downward)
+#else
+ BYTES_BIG_ENDIAN
+#endif
+ )
+ shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
bytelen = ssize - bytepos;
if (bytelen <= 0)
abort ();
@@ -2278,7 +2284,8 @@ emit_group_load (dst, orig_src, ssize)
/* Optimize the access just a bit. */
if (GET_CODE (src) == MEM
- && MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode)
+ && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (src))
+ || MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode))
&& bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
&& bytelen == GET_MODE_SIZE (mode))
{
@@ -2321,7 +2328,7 @@ emit_group_load (dst, orig_src, ssize)
bytepos * BITS_PER_UNIT, 1, NULL_RTX,
mode, mode, ssize);
- if (BYTES_BIG_ENDIAN && shift)
+ if (shift)
expand_binop (mode, ashl_optab, tmps[i], GEN_INT (shift),
tmps[i], 0, OPTAB_WIDEN);
}
@@ -2353,13 +2360,16 @@ emit_group_move (dst, src)
XEXP (XVECEXP (src, 0, i), 0));
}
-/* Emit code to move a block SRC to a block DST, where SRC is non-consecutive
- registers represented by a PARALLEL. SSIZE represents the total size of
- block DST, or -1 if not known. */
+/* Emit code to move a block SRC to a block ORIG_DST of type TYPE,
+ where SRC is non-consecutive registers represented by a PARALLEL.
+ SSIZE represents the total size of block ORIG_DST, or -1 if not
+ known. */
void
-emit_group_store (orig_dst, src, ssize)
- rtx orig_dst, src;
+emit_group_store (orig_dst, src, type, ssize)
+ rtx orig_dst;
+ rtx src;
+ tree type ATTRIBUTE_UNUSED;
int ssize;
{
rtx *tmps, dst;
@@ -2404,8 +2414,8 @@ emit_group_store (orig_dst, src, ssize)
the temporary. */
temp = assign_stack_temp (GET_MODE (dst), ssize, 0);
- emit_group_store (temp, src, ssize);
- emit_group_load (dst, temp, ssize);
+ emit_group_store (temp, src, type, ssize);
+ emit_group_load (dst, temp, type, ssize);
return;
}
else if (GET_CODE (dst) != MEM && GET_CODE (dst) != CONCAT)
@@ -2426,7 +2436,16 @@ emit_group_store (orig_dst, src, ssize)
/* Handle trailing fragments that run over the size of the struct. */
if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
{
- if (BYTES_BIG_ENDIAN)
+ /* store_bit_field always takes its value from the lsb.
+ Move the fragment to the lsb if it's not already there. */
+ if (
+#ifdef BLOCK_REG_PADDING
+ BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
+ == (BYTES_BIG_ENDIAN ? upward : downward)
+#else
+ BYTES_BIG_ENDIAN
+#endif
+ )
{
int shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
expand_binop (mode, ashr_optab, tmps[i], GEN_INT (shift),
@@ -2459,7 +2478,8 @@ emit_group_store (orig_dst, src, ssize)
/* Optimize the access just a bit. */
if (GET_CODE (dest) == MEM
- && MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode)
+ && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (dest))
+ || MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
&& bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
&& bytelen == GET_MODE_SIZE (mode))
emit_move_insn (adjust_address (dest, mode, bytepos), tmps[i]);
@@ -3991,7 +4011,7 @@ emit_push_insn (x, mode, type, size, ali
/* Handle calls that pass values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
if (GET_CODE (reg) == PARALLEL)
- emit_group_load (reg, x, -1); /* ??? size? */
+ emit_group_load (reg, x, type, -1);
else
move_block_to_reg (REGNO (reg), x, partial, mode);
}
@@ -4194,7 +4214,8 @@ expand_assignment (to, from, want_value,
/* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
if (GET_CODE (to_rtx) == PARALLEL)
- emit_group_load (to_rtx, value, int_size_in_bytes (TREE_TYPE (from)));
+ emit_group_load (to_rtx, value, TREE_TYPE (from),
+ int_size_in_bytes (TREE_TYPE (from)));
else if (GET_MODE (to_rtx) == BLKmode)
emit_block_move (to_rtx, value, expr_size (from), BLOCK_OP_NORMAL);
else
@@ -4228,7 +4249,8 @@ expand_assignment (to, from, want_value,
temp = expand_expr (from, 0, GET_MODE (to_rtx), 0);
if (GET_CODE (to_rtx) == PARALLEL)
- emit_group_load (to_rtx, temp, int_size_in_bytes (TREE_TYPE (from)));
+ emit_group_load (to_rtx, temp, TREE_TYPE (from),
+ int_size_in_bytes (TREE_TYPE (from)));
else
emit_move_insn (to_rtx, temp);
@@ -4641,7 +4663,8 @@ store_expr (exp, target, want_value)
/* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
else if (GET_CODE (target) == PARALLEL)
- emit_group_load (target, temp, int_size_in_bytes (TREE_TYPE (exp)));
+ emit_group_load (target, temp, TREE_TYPE (exp),
+ int_size_in_bytes (TREE_TYPE (exp)));
else if (GET_MODE (temp) == BLKmode)
emit_block_move (target, temp, expr_size (exp),
(want_value & 2
@@ -9182,7 +9205,7 @@ expand_expr (exp, target, tmode, modifie
/* Handle calls that pass values in multiple
non-contiguous locations. The Irix 6 ABI has examples
of this. */
- emit_group_store (memloc, op0,
+ emit_group_store (memloc, op0, inner_type,
int_size_in_bytes (inner_type));
else
emit_move_insn (memloc, op0);
diff -urp gcc2/gcc/calls.c gcc3/gcc/calls.c
--- gcc2/gcc/calls.c 2003-04-27 19:07:19.000000000 +0930
+++ gcc3/gcc/calls.c 2003-04-30 14:33:24.000000000 +0930
@@ -27,6 +27,7 @@ Software Foundation, 59 Temple Place - S
#include "tree.h"
#include "flags.h"
#include "expr.h"
+#include "optabs.h"
#include "libfuncs.h"
#include "function.h"
#include "regs.h"
@@ -1015,22 +1016,27 @@ store_unaligned_arguments_into_pseudos (
< (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD)))
{
int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
- int big_endian_correction = 0;
-
- args[i].n_aligned_regs
- = args[i].partial ? args[i].partial
- : (bytes + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
+ int nregs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ int endian_correction = 0;
+ args[i].n_aligned_regs = args[i].partial ? args[i].partial : nregs;
args[i].aligned_regs = (rtx *) xmalloc (sizeof (rtx)
* args[i].n_aligned_regs);
- /* Structures smaller than a word are aligned to the least
- significant byte (to the right). On a BYTES_BIG_ENDIAN machine,
+ /* Structures smaller than a word are normally aligned to the
+ least significant byte. On a BYTES_BIG_ENDIAN machine,
this means we must skip the empty high order bytes when
calculating the bit offset. */
- if (BYTES_BIG_ENDIAN
- && bytes < UNITS_PER_WORD)
- big_endian_correction = (BITS_PER_WORD - (bytes * BITS_PER_UNIT));
+ if (bytes < UNITS_PER_WORD
+#ifdef BLOCK_REG_PADDING
+ && (BLOCK_REG_PADDING (args[i].mode,
+ TREE_TYPE (args[i].tree_value), 1)
+ == downward)
+#else
+ && BYTES_BIG_ENDIAN
+#endif
+ )
+ endian_correction = BITS_PER_WORD - bytes * BITS_PER_UNIT;
for (j = 0; j < args[i].n_aligned_regs; j++)
{
@@ -1039,6 +1045,8 @@ store_unaligned_arguments_into_pseudos (
int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);
args[i].aligned_regs[j] = reg;
+ word = extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
+ word_mode, word_mode, BITS_PER_WORD);
/* There is no need to restrict this code to loading items
in TYPE_ALIGN sized hunks. The bitfield instructions can
@@ -1054,11 +1062,8 @@ store_unaligned_arguments_into_pseudos (
emit_move_insn (reg, const0_rtx);
bytes -= bitsize / BITS_PER_UNIT;
- store_bit_field (reg, bitsize, big_endian_correction, word_mode,
- extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
- word_mode, word_mode,
- BITS_PER_WORD),
- BITS_PER_WORD);
+ store_bit_field (reg, bitsize, endian_correction, word_mode,
+ word, BITS_PER_WORD);
}
}
}
@@ -1689,34 +1694,48 @@ load_register_parameters (args, num_actu
{
rtx reg = ((flags & ECF_SIBCALL)
? args[i].tail_call_reg : args[i].reg);
- int partial = args[i].partial;
- int nregs;
-
if (reg)
{
+ int partial = args[i].partial;
+ int nregs;
+ int size = 0;
rtx before_arg = get_last_insn ();
/* Set to non-negative if must move a word at a time, even if just
one word (e.g, partial == 1 && mode == DFmode). Set to -1 if
we just use a normal move insn. This value can be zero if the
argument is a zero size structure with no fields. */
- nregs = (partial ? partial
- : (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode
- ? ((int_size_in_bytes (TREE_TYPE (args[i].tree_value))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
- : -1));
+ nregs = -1;
+ if (partial)
+ nregs = partial;
+ else if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode)
+ {
+ size = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
+ nregs = (size + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
+ }
+ else
+ size = GET_MODE_SIZE (args[i].mode);
/* Handle calls that pass values in multiple non-contiguous
locations. The Irix 6 ABI has examples of this. */
if (GET_CODE (reg) == PARALLEL)
- emit_group_load (reg, args[i].value,
- int_size_in_bytes (TREE_TYPE (args[i].tree_value)));
+ {
+ tree type = TREE_TYPE (args[i].tree_value);
+ emit_group_load (reg, args[i].value, type,
+ int_size_in_bytes (type));
+ }
/* If simple case, just do move. If normal partial, store_one_arg
has already loaded the register for us. In all other cases,
load the register(s) from memory. */
- else if (nregs == -1)
+ else if (nregs == -1
+#ifdef BLOCK_REG_PADDING
+ && !(size < UNITS_PER_WORD
+ && (args[i].locate.where_pad
+ == (BYTES_BIG_ENDIAN ? upward : downward)))
+#endif
+ )
emit_move_insn (reg, args[i].value);
/* If we have pre-computed the values to put in the registers in
@@ -1728,9 +1747,44 @@ load_register_parameters (args, num_actu
args[i].aligned_regs[j]);
else if (partial == 0 || args[i].pass_on_stack)
- move_block_to_reg (REGNO (reg),
- validize_mem (args[i].value), nregs,
- args[i].mode);
+ {
+ rtx mem = validize_mem (args[i].value);
+
+#ifdef BLOCK_REG_PADDING
+ /* Handle case where we have a value that needs shifting
+ up to the msb. eg. a QImode value and we're padding
+ upward on a BYTES_BIG_ENDIAN machine. */
+ if (nregs == -1)
+ {
+ rtx ri = gen_rtx_REG (word_mode, REGNO (reg));
+ rtx x;
+ int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
+ x = expand_binop (word_mode, ashl_optab, mem,
+ GEN_INT (shift), ri, 1, OPTAB_WIDEN);
+ if (x != ri)
+ emit_move_insn (ri, x);
+ }
+
+ /* Handle a BLKmode that needs shifting. */
+ else if (nregs == 1 && size < UNITS_PER_WORD
+ && args[i].locate.where_pad == downward)
+ {
+ rtx tem = operand_subword_force (mem, 0, args[i].mode);
+ rtx ri = gen_rtx_REG (word_mode, REGNO (reg));
+ rtx x = gen_reg_rtx (word_mode);
+ int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
+ optab dir = BYTES_BIG_ENDIAN ? lshr_optab : ashl_optab;
+
+ emit_move_insn (x, tem);
+ x = expand_binop (word_mode, dir, x, GEN_INT (shift),
+ ri, 1, OPTAB_WIDEN);
+ if (x != ri)
+ emit_move_insn (ri, x);
+ }
+ else
+#endif
+ move_block_to_reg (REGNO (reg), mem, nregs, args[i].mode);
+ }
/* When a parameter is a block, and perhaps in other cases, it is
possible that it did a load from an argument slot that was
@@ -3225,7 +3279,7 @@ expand_call (exp, target, ignore)
}
if (! rtx_equal_p (target, valreg))
- emit_group_store (target, valreg,
+ emit_group_store (target, valreg, TREE_TYPE (exp),
int_size_in_bytes (TREE_TYPE (exp)));
/* We can not support sibling calls for this case. */
@@ -3976,7 +4030,7 @@ emit_library_call_value_1 (retval, orgfu
/* Handle calls that pass values in multiple non-contiguous
locations. The PA64 has examples of this for library calls. */
if (reg != 0 && GET_CODE (reg) == PARALLEL)
- emit_group_load (reg, val, GET_MODE_SIZE (GET_MODE (val)));
+ emit_group_load (reg, val, NULL_TREE, GET_MODE_SIZE (GET_MODE (val)));
else if (reg != 0 && partial == 0)
emit_move_insn (reg, val);
@@ -4080,7 +4134,7 @@ emit_library_call_value_1 (retval, orgfu
if (GET_CODE (valreg) == PARALLEL)
{
temp = gen_reg_rtx (outmode);
- emit_group_store (temp, valreg, outmode);
+ emit_group_store (temp, valreg, NULL_TREE, outmode);
valreg = temp;
}
@@ -4123,7 +4177,7 @@ emit_library_call_value_1 (retval, orgfu
{
if (value == 0)
value = gen_reg_rtx (outmode);
- emit_group_store (value, valreg, outmode);
+ emit_group_store (value, valreg, NULL_TREE, outmode);
}
else if (value != 0)
emit_move_insn (value, valreg);
diff -urp gcc2/gcc/function.c gcc3/gcc/function.c
--- gcc2/gcc/function.c 2003-04-24 17:52:45.000000000 +0930
+++ gcc3/gcc/function.c 2003-04-30 14:33:27.000000000 +0930
@@ -4623,6 +4623,8 @@ assign_parms (fndecl)
offset_rtx));
set_mem_attributes (stack_parm, parm, 1);
+ if (entry_parm && MEM_ATTRS (stack_parm)->align < PARM_BOUNDARY)
+ set_mem_align (stack_parm, PARM_BOUNDARY);
/* Set also REG_ATTRS if parameter was passed in a register. */
if (entry_parm)
@@ -4654,6 +4656,7 @@ assign_parms (fndecl)
locations. The Irix 6 ABI has examples of this. */
if (GET_CODE (entry_parm) == PARALLEL)
emit_group_store (validize_mem (stack_parm), entry_parm,
+ TREE_TYPE (parm),
int_size_in_bytes (TREE_TYPE (parm)));
else
@@ -4757,7 +4760,12 @@ assign_parms (fndecl)
Set DECL_RTL to that place. */
- if (nominal_mode == BLKmode || GET_CODE (entry_parm) == PARALLEL)
+ if (nominal_mode == BLKmode
+#ifdef BLOCK_REG_PADDING
+ || (locate.where_pad == (BYTES_BIG_ENDIAN ? upward : downward)
+ && GET_MODE_SIZE (promoted_mode) < UNITS_PER_WORD)
+#endif
+ || GET_CODE (entry_parm) == PARALLEL)
{
/* If a BLKmode arrives in registers, copy it to a stack slot.
Handle calls that pass values in multiple non-contiguous
@@ -4793,7 +4801,7 @@ assign_parms (fndecl)
/* Handle calls that pass values in multiple non-contiguous
locations. The Irix 6 ABI has examples of this. */
if (GET_CODE (entry_parm) == PARALLEL)
- emit_group_store (mem, entry_parm, size);
+ emit_group_store (mem, entry_parm, TREE_TYPE (parm), size);
/* If SIZE is that of a mode no bigger than a word, just use
that mode's store operation. */
@@ -4802,7 +4810,13 @@ assign_parms (fndecl)
enum machine_mode mode
= mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
- if (mode != BLKmode)
+ if (mode != BLKmode
+#ifdef BLOCK_REG_PADDING
+ && (size == UNITS_PER_WORD
+ || (BLOCK_REG_PADDING (mode, TREE_TYPE (parm), 1)
+ != (BYTES_BIG_ENDIAN ? upward : downward)))
+#endif
+ )
{
rtx reg = gen_rtx_REG (mode, REGNO (entry_parm));
emit_move_insn (change_address (mem, mode, 0), reg);
@@ -4813,7 +4827,13 @@ assign_parms (fndecl)
to memory. Note that the previous test doesn't
handle all cases (e.g. SIZE == 3). */
else if (size != UNITS_PER_WORD
- && BYTES_BIG_ENDIAN)
+#ifdef BLOCK_REG_PADDING
+ && (BLOCK_REG_PADDING (mode, TREE_TYPE (parm), 1)
+ == downward)
+#else
+ && BYTES_BIG_ENDIAN
+#endif
+ )
{
rtx tem, x;
int by = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
@@ -5411,6 +5431,7 @@ locate_and_pad_parm (passed_mode, type,
= type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
+ locate->where_pad = where_pad;
#ifdef ARGS_GROW_DOWNWARD
locate->slot_offset.constant = -initial_offset_ptr->constant;
@@ -7142,6 +7163,7 @@ expand_function_end (filename, line, end
emit_group_move (real_decl_rtl, decl_rtl);
else
emit_group_load (real_decl_rtl, decl_rtl,
+ TREE_TYPE (decl_result),
int_size_in_bytes (TREE_TYPE (decl_result)));
}
else
diff -urp gcc2/gcc/stmt.c gcc3/gcc/stmt.c
--- gcc2/gcc/stmt.c 2003-04-22 18:55:34.000000000 +0930
+++ gcc3/gcc/stmt.c 2003-04-24 21:07:18.000000000 +0930
@@ -3008,7 +3008,7 @@ expand_value_return (val)
val = convert_modes (mode, old_mode, val, unsignedp);
#endif
if (GET_CODE (return_reg) == PARALLEL)
- emit_group_load (return_reg, val, int_size_in_bytes (type));
+ emit_group_load (return_reg, val, type, int_size_in_bytes (type));
else
emit_move_insn (return_reg, val);
}
diff -urp gcc2/gcc/Makefile.in gcc3/gcc/Makefile.in
--- gcc2/gcc/Makefile.in 2003-04-24 15:47:39.000000000 +0930
+++ gcc3/gcc/Makefile.in 2003-04-24 21:14:33.000000000 +0930
@@ -1531,7 +1531,7 @@ builtins.o : builtins.c $(CONFIG_H) $(SY
$(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \
except.h $(TM_P_H) $(PREDICT_H) libfuncs.h real.h langhooks.h
calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) flags.h \
- $(EXPR_H) langhooks.h $(TARGET_H) \
+ $(EXPR_H) $(OPTABS_H) langhooks.h $(TARGET_H) \
libfuncs.h $(REGS_H) toplev.h output.h function.h $(TIMEVAR_H) $(TM_P_H) cgraph.h except.h
expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
flags.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) real.h \
diff -urp gcc2/gcc/config/rs6000/linux64.h gcc3/gcc/config/rs6000/linux64.h
--- gcc2/gcc/config/rs6000/linux64.h 2003-04-22 18:55:34.000000000 +0930
+++ gcc3/gcc/config/rs6000/linux64.h 2003-04-30 14:37:08.000000000 +0930
@@ -49,6 +49,10 @@
#undef TARGET_64BIT
#define TARGET_64BIT 1
+/* And we're always big-endian. */
+#undef TARGET_BIG_ENDIAN
+#define TARGET_BIG_ENDIAN 1
+
/* 64-bit PowerPC Linux always has a TOC. */
#undef TARGET_NO_TOC
#define TARGET_NO_TOC 0
@@ -143,8 +147,33 @@
#undef JUMP_TABLES_IN_TEXT_SECTION
#define JUMP_TABLES_IN_TEXT_SECTION 1
-/* 64-bit PowerPC Linux always has GPR13 fixed. */
-#define FIXED_R13 1
+/* The linux ppc64 ABI isn't explicit on whether aggregates smaller
+ than a doubleword should be padded upward or downward. You could
+ reasonably assume that they follow the normal rules for structure
+ layout treating the parameter area as any other block of memory,
+ then map the reg param area to registers. ie. pad updard.
+ Setting both of the following defines results in this behaviour.
+ Setting just the first one will result in aggregates that fit in a
+ doubleword being padded downward, and others being padded upward.
+ Not a bad idea as this results in struct { int x; } being passed
+ the same way as an int. */
+#define AGGREGATE_PADDING_FIXED 1
+/* #define AGGREGATES_PAD_UPWARD_ALWAYS 1 */
+
+/* We don't want anything in the reg parm area being passed on the
+ stack. */
+#define MUST_PASS_IN_STACK(MODE, TYPE) \
+ ((TYPE) != 0 \
+ && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
+ || TREE_ADDRESSABLE (TYPE)))
+
+/* Specify padding for the last element of a block move between
+ registers and memory. FIRST is non-zero if this is the only
+ element. */
+#ifndef BLOCK_REG_PADDING
+#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
+ (!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
+#endif
/* __throw will restore its own return address to be the same as the
return address of the function that the throw is being made to.
diff -urp gcc2/gcc/config/rs6000/rs6000.h gcc3/gcc/config/rs6000/rs6000.h
--- gcc2/gcc/config/rs6000/rs6000.h 2003-04-23 11:29:04.000000000 +0930
+++ gcc3/gcc/config/rs6000/rs6000.h 2003-04-24 21:07:17.000000000 +0930
@@ -1701,7 +1701,6 @@ typedef struct rs6000_args
int fregno; /* next available FP register */
int vregno; /* next available AltiVec register */
int nargs_prototype; /* # args left in the current prototype */
- int orig_nargs; /* Original value of nargs_prototype */
int prototype; /* Whether a prototype was defined */
int call_cookie; /* Do special things for this call */
int sysv_gregno; /* next available GP register */
@@ -1832,13 +1831,8 @@ typedef struct rs6000_args
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
rs6000_va_arg (valist, type)
-/* For AIX, the rule is that structures are passed left-aligned in
- their stack slot. However, GCC does not presently do this:
- structures which are the same size as integer types are passed
- right-aligned, as if they were in fact integers. This only
- matters for structures of size 1 or 2, or 4 when TARGET_64BIT.
- ABI_V4 does not use std_expand_builtin_va_arg. */
-#define PAD_VARARGS_DOWN (TYPE_MODE (type) != BLKmode)
+#define PAD_VARARGS_DOWN \
+ (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
/* Define this macro to be a nonzero value if the location where a function
argument is passed depends on whether or not it is a named argument. */
diff -urp gcc2/gcc/config/rs6000/rs6000.c gcc3/gcc/config/rs6000/rs6000.c
--- gcc2/gcc/config/rs6000/rs6000.c 2003-04-24 14:46:04.000000000 +0930
+++ gcc3/gcc/config/rs6000/rs6000.c 2003-04-24 21:43:35.000000000 +0930
@@ -3132,8 +3132,6 @@ init_cumulative_args (cum, fntype, libna
else
cum->nargs_prototype = 0;
- cum->orig_nargs = cum->nargs_prototype;
-
/* Check for a longcall attribute. */
if (fntype
&& lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
@@ -3172,8 +3170,37 @@ function_arg_padding (mode, type)
enum machine_mode mode;
tree type;
{
+#if !AGGREGATE_PADDING_FIXED
+ /* GCC used to pass structures of the same size as integer types as
+ if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
+ ie. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
+ passed padded downward, except that -mstrict-align further
+ muddied the water in that multi-component structures of 2 and 4
+ bytes in size were passed padded upward.
+
+ The following arranges for best compatibility with previous
+ versions of gcc, but removes the -mstrict-align dependency. */
+ if (BYTES_BIG_ENDIAN)
+ {
+ HOST_WIDE_INT size = 0;
+
+ if (mode == BLKmode)
+ {
+ if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
+ size = int_size_in_bytes (type);
+ }
+ else
+ size = GET_MODE_SIZE (mode);
+
+ if (size == 1 || size == 2 || size == 4)
+ return downward;
+ }
+ return upward;
+#else
+#if AGGREGATES_PAD_UPWARD_ALWAYS
if (type != 0 && AGGREGATE_TYPE_P (type))
return upward;
+#endif
/* This is the default definition. */
return (! BYTES_BIG_ENDIAN
@@ -3183,6 +3210,7 @@ function_arg_padding (mode, type)
&& int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
: GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
? downward : upward));
+#endif
}
/* If defined, a C expression that gives the alignment boundary, in bits,
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: function parms in regs, patch 1 of 3
2003-04-24 15:34 function parms in regs, patch 1 of 3 Alan Modra
2003-04-25 22:44 ` Richard Henderson
@ 2003-05-02 5:06 ` Jim Wilson
2003-05-02 5:20 ` Richard Henderson
1 sibling, 1 reply; 875+ messages in thread
From: Jim Wilson @ 2003-05-02 5:06 UTC (permalink / raw)
To: Alan Modra; +Cc: gcc-patches
I looked through this patch, and didn't see any problems. It looks
pretty straight
forward. I am willing to approve it if Richard doesn't object.
I have the same concerns as Richard though. The function calling code
is complex and fragile. Problems here can result in silent ABI changes
that are difficult to detect, particularly since we have no established
testsuite for ABI compatibility. You should be prepared to revert the
patch if problems arise.
Jim
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: function parms in regs, patch 1 of 3
2003-05-02 5:06 ` function parms in regs, patch 1 " Jim Wilson
@ 2003-05-02 5:20 ` Richard Henderson
0 siblings, 0 replies; 875+ messages in thread
From: Richard Henderson @ 2003-05-02 5:20 UTC (permalink / raw)
To: Jim Wilson; +Cc: Alan Modra, gcc-patches
On Thu, May 01, 2003 at 10:07:01PM -0400, Jim Wilson wrote:
> I looked through this patch, and didn't see any problems. It looks
> pretty straight
> forward. I am willing to approve it if Richard doesn't object.
I don't object.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: function parms in regs, patch 3 of 3
2003-04-30 13:29 ` function parms in regs, patch 3 " Alan Modra
@ 2003-05-02 6:05 ` Jim Wilson
2003-05-02 12:38 ` Alan Modra
2003-07-10 6:55 ` Jim Wilson
1 sibling, 1 reply; 875+ messages in thread
From: Jim Wilson @ 2003-05-02 6:05 UTC (permalink / raw)
To: Alan Modra; +Cc: gcc-patches
This is the patch I really wanted to comment on, which is why I am
willing to review this set of patches.
I believe that we already have so many macros that interact in confusing
ways that we should avoid adding new ones. I think a better approach is
to return more info from FUNCTION_ARG, in a more structured form, so
that we can get away from the ever expanding set of macros that we have.
The PARALLEL stuff is a step in this direction. The structure of the
info is ugly, but that can always be improved. I'd like to see the
entire interface rewritten, but it isn't clear if anyone will ever have
the time for it, and we could only do this in a .0 release.
Your revised patch which only defines BLOCK_REG_PADDING for rs6000 is a
major improvement. I think there is too much risk in trying to define a
default for all targets.
There is a known IA-64 ABI problem that your patch doesn't help with.
The IA-64 ABI treats homogeneous floating-point aggregates (HFAs)
specially. A structure all of whose fields are the same FP type is an
HFA for instance. An HFA is passed in FP regs, one field per FP reg,
until the FP regs are full, and then we pass the rest in integer regs.
The part passed in integer regs is placed in the same place it would
have gone if the entire structure was passed in integer regs. Suppose
we have a structure of 5 floats, and there are 3 FP registers left. The
first 3 fields are passed in FP registers. The fourth one is passed
left-justified (little-endian) in the second integer register, because
it is the second half of the second word. The fifth one is passed
right-justified (little-endian) in the third integer register, because
it is the first half of the third word. Now the problem here is that a
float field in an integer register can require either left or right
justification depending on the context. I don't think your
BLOCK_REG_PADDING macro can handle this. It doesn't have enough info.
FUNCTION_ARG does have enough info. If the PARALLEL stuff had 3 items
location/size/alignment instead of the current 2 location/size, then I
believe we could fix this problem, your powerpc problem, and probably
also some ABI problems in other ports that we may or may not know about.
Having said that, I really should take a closer look at the patch to see
what it actually does. And I need to look at the second patch of the set.
Jim
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: function parms in regs, patch 3 of 3
2003-05-02 6:05 ` Jim Wilson
@ 2003-05-02 12:38 ` Alan Modra
2003-05-02 20:23 ` Jim Wilson
0 siblings, 1 reply; 875+ messages in thread
From: Alan Modra @ 2003-05-02 12:38 UTC (permalink / raw)
To: Jim Wilson; +Cc: gcc-patches
On Thu, May 01, 2003 at 11:06:06PM -0400, Jim Wilson wrote:
> FUNCTION_ARG does have enough info. If the PARALLEL stuff had 3 items
> location/size/alignment instead of the current 2 location/size, then I
> believe we could fix this problem, your powerpc problem, and probably
> also some ABI problems in other ports that we may or may not know about.
I like the idea. It would be nice if the called function could use
the regs in a parallel without copying to the stack too, at least for
simple cases. eg. for
struct it { char c[3]; };
int foo (struct it x) { return x.c[0]; }
I get
.foo:
sldi 3,3,40
std 3,48(1)
lbz 3,48(1)
blr
when we could dispense with the store to the stack and just have
.foo
rldicl 3,3,48,56
blr
> Having said that, I really should take a closer look at the patch to see
> what it actually does. And I need to look at the second patch of the set.
The second patch doesn't do much besides move code around and a little
tidying. The last patch is really about honouring FUNCTION_ARG_PADDING
in all cases. See the comment added to rs6000.c:function_arg_padding.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: function parms in regs, patch 3 of 3
2003-05-02 12:38 ` Alan Modra
@ 2003-05-02 20:23 ` Jim Wilson
2003-05-03 1:22 ` Alan Modra
0 siblings, 1 reply; 875+ messages in thread
From: Jim Wilson @ 2003-05-02 20:23 UTC (permalink / raw)
To: Alan Modra; +Cc: gcc-patches
On Fri, 2003-05-02 at 08:38, Alan Modra wrote:
> I like the idea. It would be nice if the called function could use
> the regs in a parallel without copying to the stack too, at least for
> simple cases.
In order to do this, we need some support for decomposing structures.
Currently, the only way to access a structure field is via an offset
from the base address for the structure. This requires that the
structure be in contiguous memory locations. In some simple cases, we
can handle structures in contiguous registers, but mostly it means they
have to be in memory. Thus we must force the object into a stack slot
so we can access fields.
If we could give each structure field its own DECL_RTL, then we could
access them in place without forcing the structure to a stack slot. Or
maybe we can put the PARALLEL into the structure's DECL_RTL, and modify
the access routines to parse it. I suspect it is simpler to have
separate DECL_RTLs for each field though.
There is also a simpler related problem. Some ABIs use big-endian
left-justified/little-endian right-justified for arguments smaller than
a word. The reason is that a simple word-sized word-aligned store can
then be used to put the argument in memory, and it will end up in the
same place in both the big and little endian cases. Likewise, a simple
word-sized word-aligned load can be used to load the argument into a
register. Unfortunately, gcc doesn't understand this convention, and
ends up doing bit-field operations to move the argument between regs and
memory. This often results in a series of shifts, masks, and byte-sized
loads/stores. I think it is a little embarrassing that we do this.
This does require that we have a word sized word aligned area to
load/store from/into, but that will often be the case. Stack slots are
always word sized and aligned for instance.
Jim
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: function parms in regs, patch 3 of 3
2003-05-02 20:23 ` Jim Wilson
@ 2003-05-03 1:22 ` Alan Modra
0 siblings, 0 replies; 875+ messages in thread
From: Alan Modra @ 2003-05-03 1:22 UTC (permalink / raw)
To: Jim Wilson; +Cc: gcc-patches
On Fri, May 02, 2003 at 01:24:40PM -0400, Jim Wilson wrote:
> There is also a simpler related problem. Some ABIs use big-endian
> left-justified/little-endian right-justified for arguments smaller than
> a word. The reason is that a simple word-sized word-aligned store can
> then be used to put the argument in memory, and it will end up in the
> same place in both the big and little endian cases. Likewise, a simple
> word-sized word-aligned load can be used to load the argument into a
> register. Unfortunately, gcc doesn't understand this convention, and
> ends up doing bit-field operations to move the argument between regs and
> memory. This often results in a series of shifts, masks, and byte-sized
> loads/stores. I think it is a little embarrassing that we do this.
> This does require that we have a word sized word aligned area to
> load/store from/into, but that will often be the case. Stack slots are
> always word sized and aligned for instance.
Yes, I noticed. Actually, it was this that led me to delve into this
code and start tidying a few things. I'd solved the powerpc64 ABI
problem originally using PARALLELs, and then found that in certain
cases (< word size struct) we could generate better code by not using
a PARALLEL for incoming args. Not exactly elegant though, so I started
to poke into why a PARALLEL was necessary in the first place.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 875+ messages in thread
* powerpc-unknown-linux-gnu bootstrap fix
@ 2003-05-14 16:25 Matt Kraai
2003-05-14 17:12 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Matt Kraai @ 2003-05-14 16:25 UTC (permalink / raw)
To: gcc-patches
Howdy,
Bootstrap on my powerpc-unknown-linux-gnu failed with the
following output:
stage1/xgcc -Bstage1/ -B/home/kraai/dev/gcc/inst/powerpc-unknown-linux-gnu/bin/ -c -g -O2 -DIN_GCC -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -pedantic -Wno-long-long -Werror -fno-common -DHAVE_CONFIG_H -I. -I. -I../../gcc/gcc -I../../gcc/gcc/. -I../../gcc/gcc/config -I../../gcc/gcc/../include ../../gcc/gcc/varasm.c -o varasm.o
../../gcc/gcc/varasm.c: In function `asm_emit_uninitialised':
../../gcc/gcc/varasm.c:1375: warning: comparison between signed and unsigned
../../gcc/gcc/varasm.c:1382: warning: comparison between signed and unsigned
../../gcc/gcc/varasm.c: In function `assemble_static_space':
../../gcc/gcc/varasm.c:1783: warning: comparison between signed and unsigned
make[2]: *** [varasm.o] Error 1
make[2]: Leaving directory `/home/kraai/dev/gcc/bld/gcc'
make[1]: *** [stage2_build] Error 2
make[1]: Leaving directory `/home/kraai/dev/gcc/bld/gcc'
make: *** [bootstrap] Error 2
Applying the appended patch allowed it to proceed. OK?
--
Matt Kraai <kraai@alumni.cmu.edu>
Debian GNU/Linux Peon
* config/rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_LOCAL): Cast
g_switch_value to unsigned HOST_WIDE_INT.
*** sysv4.h.~1.126.~ Tue May 13 21:43:03 2003
--- sysv4.h Wed May 14 07:35:47 2003
***************
*** 666,672 ****
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
do { \
if (rs6000_sdata != SDATA_NONE && (SIZE) > 0 \
! && (SIZE) <= g_switch_value) \
{ \
sbss_section (); \
ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT)); \
--- 666,672 ----
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
do { \
if (rs6000_sdata != SDATA_NONE && (SIZE) > 0 \
! && (SIZE) <= (unsigned HOST_WIDE_INT)g_switch_value) \
{ \
sbss_section (); \
ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT)); \
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: powerpc-unknown-linux-gnu bootstrap fix
2003-05-14 16:25 powerpc-unknown-linux-gnu bootstrap fix Matt Kraai
@ 2003-05-14 17:12 ` David Edelsohn
2003-05-14 17:23 ` Richard Henderson
0 siblings, 1 reply; 875+ messages in thread
From: David Edelsohn @ 2003-05-14 17:12 UTC (permalink / raw)
To: Matt Kraai, Richard Henderson; +Cc: gcc-patches
It seems like this should be a problem on other targets as well,
such as Alpha which has a similar test in elf.h.
Richard, would it be better to change g_switch_value to unsigned
int or unsigned HOST_WIDE_INT?
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: powerpc-unknown-linux-gnu bootstrap fix
2003-05-14 17:12 ` David Edelsohn
@ 2003-05-14 17:23 ` Richard Henderson
2003-05-14 17:26 ` David Edelsohn
0 siblings, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2003-05-14 17:23 UTC (permalink / raw)
To: David Edelsohn; +Cc: Matt Kraai, gcc-patches
On Wed, May 14, 2003 at 01:03:12PM -0400, David Edelsohn wrote:
> Richard, would it be better to change g_switch_value to unsigned
> int or unsigned HOST_WIDE_INT?
Yes.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: powerpc-unknown-linux-gnu bootstrap fix
2003-05-14 17:23 ` Richard Henderson
@ 2003-05-14 17:26 ` David Edelsohn
2003-05-14 17:52 ` Richard Henderson
2003-05-15 23:22 ` Geoff Keating
0 siblings, 2 replies; 875+ messages in thread
From: David Edelsohn @ 2003-05-14 17:26 UTC (permalink / raw)
To: Richard Henderson, Matt Kraai, gcc-patches
>>>>> Richard Henderson writes:
Richard> On Wed, May 14, 2003 at 01:03:12PM -0400, David Edelsohn wrote:
>> Richard, would it be better to change g_switch_value to unsigned
>> int or unsigned HOST_WIDE_INT?
Richard> Yes.
I just noticed that this is fairly ugly. Half the time
g_switch_value is tested against SIZE (unsigned HOST_WIDE_INT) and the
other half again int_size_in_bytes (signed HOST_WIDE_INT). It's not going
to be easy to reliably rationalize this either way. Maybe we should just
punt with a cast in sysv4.h -- alpha.c does that already. Comments?
David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: powerpc-unknown-linux-gnu bootstrap fix
2003-05-14 17:26 ` David Edelsohn
@ 2003-05-14 17:52 ` Richard Henderson
2003-05-14 18:58 ` David Edelsohn
2003-05-15 23:22 ` Geoff Keating
1 sibling, 1 reply; 875+ messages in thread
From: Richard Henderson @ 2003-05-14 17:52 UTC (permalink / raw)
To: David Edelsohn; +Cc: Matt Kraai, gcc-patches
On Wed, May 14, 2003 at 01:20:36PM -0400, David Edelsohn wrote:
> I just noticed that this is fairly ugly. Half the time
> g_switch_value is tested against SIZE (unsigned HOST_WIDE_INT) and the
> other half again int_size_in_bytes (signed HOST_WIDE_INT).
Blah. I guess casts are the least invasive change.
r~
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: powerpc-unknown-linux-gnu bootstrap fix
2003-05-14 17:52 ` Richard Henderson
@ 2003-05-14 18:58 ` David Edelsohn
0 siblings, 0 replies; 875+ messages in thread
From: David Edelsohn @ 2003-05-14 18:58 UTC (permalink / raw)
To: Richard Henderson, Matt Kraai, gcc-patches
>>>>> Richard Henderson writes:
Richard> Blah. I guess casts are the least invasive change.
Okay, Matt, just check in your proposed fix with the cast.
Thanks, David
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: powerpc-unknown-linux-gnu bootstrap fix
2003-05-14 17:26 ` David Edelsohn
2003-05-14 17:52 ` Richard Henderson
@ 2003-05-15 23:22 ` Geoff Keating
2003-05-18 23:17 ` Matt Kraai
1 sibling, 1 reply; 875+ messages in thread
From: Geoff Keating @ 2003-05-15 23:22 UTC (permalink / raw)
To: David Edelsohn; +Cc: gcc-patches
David Edelsohn <dje@watson.ibm.com> writes:
> >>>>> Richard Henderson writes:
>
> Richard> On Wed, May 14, 2003 at 01:03:12PM -0400, David Edelsohn wrote:
> >> Richard, would it be better to change g_switch_value to unsigned
> >> int or unsigned HOST_WIDE_INT?
>
> Richard> Yes.
>
> I just noticed that this is fairly ugly. Half the time
> g_switch_value is tested against SIZE (unsigned HOST_WIDE_INT) and the
> other half again int_size_in_bytes (signed HOST_WIDE_INT). It's not going
> to be easy to reliably rationalize this either way. Maybe we should just
> punt with a cast in sysv4.h -- alpha.c does that already. Comments?
I think g_switch_value should be unsigned, because the reason
int_size_in_bytes is signed is that it can return -1 meaning "I
dunno", and that's a special case that the port maintainer should take
care to handle specially.
--
- Geoffrey Keating <geoffk@geoffk.org>
^ permalink raw reply [flat|nested] 875+ messages in thread
* Re: powerpc-unknown-linux-gnu bootstrap fix
2003-05-15 23:22 ` Geoff Keating
@ 2003-05-18 23:17 ` Matt Kraai
2003-05-19 0:16 ` Geoff Keating
0 siblings, 1 reply; 875+ messages in thread
From: Matt Kraai @ 2003-05-18 23:17 UTC (permalink / raw)
To: Geoff Keating; +Cc: David Edelsohn, gcc-patches
On Thu, May 15, 2003 at 03:46:58PM -0700, Geoff Keating wrote:
> David Edelsohn <dje@watson.ibm.com> writes:
>
> > >>>>> Richard Henderson writes:
> >
> > Richard> On Wed, May 14, 2003 at 01:03:12PM -0400, David Edelsohn wrote:
> > >> Richard, would it be better to change g_switch_value to unsigned
> > >> int or unsigned HOST_WIDE_INT?
> >
> > Richard> Yes.
> >
> > I just noticed that this is fairly ugly. Half the time
> > g_switch_value is tested against SIZE (unsigned HOST_WIDE_INT) and the
> > other half again int_size_in_bytes (signed HOST_WIDE_INT). It's not going
> > to be easy to reliably rationalize this either way. Maybe we should just
> > punt with a cast in sysv4.h -- alpha.c does that already. Comments?
>
> I think g_switch_value should be unsigned, because the reason
> int_size_in_bytes is signed is that it can return -1 meaning "I
> dunno", and that's a special case that the port maintainer should take
> care to handle specially.
The following patch makes g_switch_value an unsigned
HOST_WIDE_INT.
Tested by building cc1 for alpha-unknown-linux-gnu, frv-foo-elf,
and m32r-foo-elf, and by bootstrapping and regression testing on
powerpc-unknown-linux-gnu.
OK to commit?
--
Matt Kraai <kraai@alumni.cmu.edu>
Debian GNU/Linux Peon
* flags.h (g_switch_value): Change to an unsigned
HOST_WIDE_INT.
* toplev.c (g_switch_value): Likewise.
* config/alpha/alpha.c (small_symbolic_operand): Remove
g_switch_value cast.
(alpha_in_small_data_p): Cast size to an unsigned
HOST_WIDE_INT.
* config/frv/frv.c (frv_in_small_data_p): Cast size to an
unsigned HOST_WIDE_INT.
* config/frv/frv.h (g_switch_value, g_switch_set): Remove.
(ASM_OUTPUT_ALIGNED_DECL_LOCAL): Declare g_switch_set.
* config/m32r/m32r.c (m32r_in_small_data_p): Cast size to an
unsigned HOST_WIDE_INT.
(m32r_asm_file_start): Use HOST_WIDE_INT_PRINT_UNSIGNED.
* config/m32r/m32r.h (g_switch_value, g_switch_set): Remove.
(ASM_OUTPUT_ALIGNED_COMMON): Declare g_switch_value.
* config/rs6000/rs6000.c (rs6000_file_start): Use
HOST_WIDE_INT_PRINT_UNSIGNED.
(small_data_operand): Cast summand to unsigned HOST_WIDE_INT.
(rs6000_elf_in_small_data_p): Cast size to unsigned
HOST_WIDE_INT.
* config/rs6000/sysv4.h (g_switch_value, g_switch_set):
Remove.
(SUBTARGET_OVERRIDE_OPTIONS): Declare g_switch_value and
g_switch_set.
(ASM_OUTPUT_ALIGNED_LOCAL): Declare g_switch_value and remove
g_switch_value cast.
Index: gcc/flags.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flags.h,v
retrieving revision 1.107
diff -c -3 -p -r1.107 flags.h
*** gcc/flags.h 7 May 2003 22:11:33 -0000 1.107
--- gcc/flags.h 18 May 2003 21:19:28 -0000
*************** extern int frame_pointer_needed;
*** 586,592 ****
extern int flag_trapv;
/* Value of the -G xx switch, and whether it was passed or not. */
! extern int g_switch_value;
extern int g_switch_set;
/* Values of the -falign-* flags: how much to align labels in code.
--- 586,592 ----
extern int flag_trapv;
/* Value of the -G xx switch, and whether it was passed or not. */
! extern unsigned HOST_WIDE_INT g_switch_value;
extern int g_switch_set;
/* Values of the -falign-* flags: how much to align labels in code.
Index: gcc/toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.757
diff -c -3 -p -r1.757 toplev.c
*** gcc/toplev.c 14 May 2003 07:29:41 -0000 1.757
--- gcc/toplev.c 18 May 2003 21:19:48 -0000
*************** enum graph_dump_types graph_dump_format;
*** 329,335 ****
char *asm_file_name;
/* Value of the -G xx switch, and whether it was passed or not. */
! int g_switch_value;
int g_switch_set;
/* Type(s) of debugging information we are producing (if any).
--- 329,335 ----
char *asm_file_name;
/* Value of the -G xx switch, and whether it was passed or not. */
! unsigned HOST_WIDE_INT g_switch_value;
int g_switch_set;
/* Type(s) of debugging information we are producing (if any).
Index: gcc/config/alpha/alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.306
diff -c -3 -p -r1.306 alpha.c
*** gcc/config/alpha/alpha.c 16 May 2003 18:57:37 -0000 1.306
--- gcc/config/alpha/alpha.c 18 May 2003 21:20:19 -0000
*************** small_symbolic_operand (op, mode)
*** 1166,1172 ****
/* ??? There's no encode_section_info equivalent for the rtl
constant pool, so SYMBOL_FLAG_SMALL never gets set. */
if (CONSTANT_POOL_ADDRESS_P (op))
! return GET_MODE_SIZE (get_pool_mode (op)) <= (unsigned) g_switch_value;
return (SYMBOL_REF_LOCAL_P (op)
&& SYMBOL_REF_SMALL_P (op)
--- 1166,1172 ----
/* ??? There's no encode_section_info equivalent for the rtl
constant pool, so SYMBOL_FLAG_SMALL never gets set. */
if (CONSTANT_POOL_ADDRESS_P (op))
! return GET_MODE_SIZE (get_pool_mode (op)) <= g_switch_value;
return (SYMBOL_REF_LOCAL_P (op)
&& SYMBOL_REF_SMALL_P (op)
*************** alpha_in_small_data_p (exp)
*** 1891,1897 ****
/* If this is an incomplete type with size 0, then we can't put it
in sdata because it might be too big when completed. */
! if (size > 0 && size <= g_switch_value)
return true;
}
--- 1891,1897 ----
/* If this is an incomplete type with size 0, then we can't put it
in sdata because it might be too big when completed. */
! if (size > 0 && (unsigned HOST_WIDE_INT) size <= g_switch_value)
return true;
}
Index: gcc/config/frv/frv.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/frv/frv.c,v
retrieving revision 1.23
diff -c -3 -p -r1.23 frv.c
*** gcc/config/frv/frv.c 16 May 2003 18:57:40 -0000 1.23
--- gcc/config/frv/frv.c 18 May 2003 21:20:42 -0000
*************** frv_in_small_data_p (decl)
*** 9714,9720 ****
return false;
size = int_size_in_bytes (TREE_TYPE (decl));
! if (size > 0 && size <= g_switch_value)
return true;
/* If we already know which section the decl should be in, see if
--- 9714,9720 ----
return false;
size = int_size_in_bytes (TREE_TYPE (decl));
! if (size > 0 && (unsigned HOST_WIDE_INT) size <= g_switch_value)
return true;
/* If we already know which section the decl should be in, see if
Index: gcc/config/frv/frv.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/frv/frv.h,v
retrieving revision 1.22
diff -c -3 -p -r1.22 frv.h
*** gcc/config/frv/frv.h 12 May 2003 09:51:24 -0000 1.22
--- gcc/config/frv/frv.h 18 May 2003 21:20:59 -0000
*************** extern int target_flags;
*** 554,562 ****
#define SDATA_DEFAULT_SIZE 8
#endif
- extern int g_switch_value; /* value of the -G xx switch */
- extern int g_switch_set; /* whether -G xx was passed. */
-
/* Storage Layout */
--- 554,559 ----
*************** extern int size_directive_output;
*** 2783,2788 ****
--- 2780,2787 ----
#undef ASM_OUTPUT_ALIGNED_DECL_LOCAL
#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGN) \
do { \
+ extern unsigned HOST_WIDE_INT g_switch_value; \
+ \
if ((SIZE) > 0 && (SIZE) <= g_switch_value) \
sbss_section (); \
else \
Index: gcc/config/m32r/m32r.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m32r/m32r.c,v
retrieving revision 1.64
diff -c -3 -p -r1.64 m32r.c
*** gcc/config/m32r/m32r.c 9 May 2003 06:37:20 -0000 1.64
--- gcc/config/m32r/m32r.c 18 May 2003 21:21:09 -0000
*************** m32r_in_small_data_p (decl)
*** 433,439 ****
{
int size = int_size_in_bytes (TREE_TYPE (decl));
! if (size > 0 && size <= g_switch_value)
return true;
}
}
--- 433,439 ----
{
int size = int_size_in_bytes (TREE_TYPE (decl));
! if (size > 0 && (unsigned HOST_WIDE_INT) size <= g_switch_value)
return true;
}
}
*************** m32r_asm_file_start (file)
*** 2208,2214 ****
FILE * file;
{
if (flag_verbose_asm)
! fprintf (file, "%s M32R/D special options: -G %d\n",
ASM_COMMENT_START, g_switch_value);
}
\f
--- 2208,2215 ----
FILE * file;
{
if (flag_verbose_asm)
! fprintf (file,
! "%s M32R/D special options: -G " HOST_WIDE_INT_PRINT_UNSIGNED "\n",
ASM_COMMENT_START, g_switch_value);
}
\f
Index: gcc/config/m32r/m32r.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m32r/m32r.h,v
retrieving revision 1.82
diff -c -3 -p -r1.82 m32r.h
*** gcc/config/m32r/m32r.h 12 May 2003 09:51:29 -0000 1.82
--- gcc/config/m32r/m32r.h 18 May 2003 21:21:16 -0000
*************** extern enum m32r_model m32r_model;
*** 350,358 ****
#define SDATA_DEFAULT_SIZE 8
#endif
- extern int g_switch_value; /* value of the -G xx switch */
- extern int g_switch_set; /* whether -G xx was passed. */
-
enum m32r_sdata { M32R_SDATA_NONE, M32R_SDATA_SDATA, M32R_SDATA_USE };
extern enum m32r_sdata m32r_sdata;
--- 350,355 ----
*************** extern char m32r_punct_chars[256];
*** 1690,1695 ****
--- 1687,1694 ----
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
do \
{ \
+ extern unsigned HOST_WIDE_INT g_switch_value; \
+ \
if (! TARGET_SDATA_NONE \
&& (SIZE) > 0 && (SIZE) <= g_switch_value) \
fprintf ((FILE), "%s", SCOMMON_ASM_OP); \
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.478
diff -c -3 -p -r1.478 rs6000.c
*** gcc/config/rs6000/rs6000.c 17 May 2003 16:57:17 -0000 1.478
--- gcc/config/rs6000/rs6000.c 18 May 2003 21:21:54 -0000
*************** rs6000_file_start (file, default_cpu)
*** 950,956 ****
if (rs6000_sdata && g_switch_value)
{
! fprintf (file, "%s -G %d", start, g_switch_value);
start = "";
}
#endif
--- 950,957 ----
if (rs6000_sdata && g_switch_value)
{
! fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
! g_switch_value);
start = "";
}
#endif
*************** small_data_operand (op, mode)
*** 2254,2260 ****
/* We have to be careful here, because it is the referenced address
that must be 32k from _SDA_BASE_, not just the symbol. */
summand = INTVAL (XEXP (sum, 1));
! if (summand < 0 || summand > g_switch_value)
return 0;
sym_ref = XEXP (sum, 0);
--- 2255,2261 ----
/* We have to be careful here, because it is the referenced address
that