aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meissner <michael.meissner@amd.com>2007-12-10 23:39:31 +0000
committerMichael Meissner <michael.meissner@amd.com>2007-12-10 23:39:31 +0000
commitf21b5e210f61f94fac714f78a2aeb21cce282f7c (patch)
treed6f8bb83944901f02e4ea6bea604efcb5ea0a838
parent3b4f67c0aef762937b12ddff85c9e3c0b5a5f446 (diff)
Merge up to revision 130757ix86/gcc-4_2-branch
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ix86/gcc-4_2-branch@130759 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog37
-rw-r--r--gcc/ChangeLog-ix864
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog6
-rw-r--r--gcc/ada/env.c6
-rw-r--r--gcc/config/fr30/fr30.c48
-rw-r--r--gcc/config/pa/pa-64.h14
-rw-r--r--gcc/config/pa/pa-protos.h3
-rw-r--r--gcc/config/pa/pa.c114
-rw-r--r--gcc/config/pa/pa.h74
-rw-r--r--gcc/config/pa/pa.md102
-rw-r--r--gcc/config/pa/pa32-regs.h8
-rw-r--r--gcc/config/pa/pa64-regs.h16
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/typeck.c2
-rw-r--r--gcc/testsuite/ChangeLog13
-rw-r--r--gcc/testsuite/g++.dg/parse/crash40.C42
-rw-r--r--gcc/testsuite/gcc.dg/pr34174-1.c45
-rw-r--r--libstdc++-v3/ChangeLog8
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc4
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_put/put/char/12.cc64
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/12.cc64
-rw-r--r--svn-mergepoint2
23 files changed, 478 insertions, 206 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6f8ce0e54a4..189371ddb0a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,40 @@
+2007-12-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR middle-end/32889
+ PR target/34091
+ * pa.md: Consolidate HImode and QImode move patterns into one pattern
+ each, eliminating floating-point alternatives.
+ * pa-protos.h (pa_cannot_change_mode_class, pa_modes_tieable_p):
+ Declare functions.
+ * pa-64.h (SECONDARY_MEMORY_NEEDED): Define here.
+ * pa.c (pa_secondary_reload): Use an intermediate general register
+ for copies to/from floating-point register classes. Simplify code
+ SHIFT_REGS class. Provide additional comments.
+ (pa_cannot_change_mode_class, pa_modes_tieable_p): New functions.
+ * pa.h (MODES_TIEABLE_P): Use pa_modes_tieable_p.
+ (SECONDARY_MEMORY_NEEDED): Delete define.
+ (INT14_OK_STRICT): Define.
+ (MODE_OK_FOR_SCALED_INDEXING_P): Allow SFmode and DFmode when using
+ soft float.
+ (MODE_OK_FOR_UNSCALED_INDEXING_P): Likewise.
+ (GO_IF_LEGITIMATE_ADDRESS): Use INT14_OK_STRICT in REG+D case for
+ SFmode and DFmode.
+ (LEGITIMIZE_RELOAD_ADDRESS): Use INT14_OK_STRICT in mask selection.
+ Align DImode offsets when generating 64-bit code.
+ * pa32-regs.h (VALID_FP_MODE_P): Remove QImode and HImode.
+ (CANNOT_CHANGE_MODE_CLASS): Define.
+ * pa64-regs.h (VALID_FP_MODE_P): Remove QImode and HImode.
+ (CANNOT_CHANGE_MODE_CLASS): Define using pa_cannot_change_mode_class.
+
+2007-11-28 Rask Ingemann Lambertsen <rask@sygehus.dk>
+
+ Backport from mainline:
+ 2007-11-26 Rask Ingemann Lambertsen <rask@sygehus.dk>
+
+ PR target/34174
+ * config/fr30/fr30.c (fr30_move_double): Sanitize mem->reg case. Copy
+ the address before it is clobbered.
+
2007-11-26 Uros Bizjak <ubizjak@gmail.com>
PR target/34215
diff --git a/gcc/ChangeLog-ix86 b/gcc/ChangeLog-ix86
index a945e28d251..7158c7e9f62 100644
--- a/gcc/ChangeLog-ix86
+++ b/gcc/ChangeLog-ix86
@@ -1,3 +1,7 @@
+2007-12-10 Michael Meissner <michael.meissner@amd.com>
+
+ * merge up to revision 130757.
+
2007-11-26 Michael Meissner <michael.meissner@amd.com>
* merge up to revision 130447.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index edb838c94c6..30a98ca3ef0 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20071126
+20071210
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 0a3fc7e1054..6474e291756 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,9 @@
+2007-12-01 Kostik Belousov <kostikbel@ukr.net>
+
+ PR ada/33722
+ * env.c (__gnat_setenv): FreeBSD 7 has a POSIX conformant putenv()
+ and its argument must not be free()ed.
+
2007-10-07 Release Manager
* GCC 4.2.2 released.
diff --git a/gcc/ada/env.c b/gcc/ada/env.c
index 30b5fb6dc2a..178c2ac3246 100644
--- a/gcc/ada/env.c
+++ b/gcc/ada/env.c
@@ -177,9 +177,9 @@ __gnat_setenv (char *name, char *value)
sprintf (expression, "%s=%s", name, value);
putenv (expression);
-#if defined (__FreeBSD__) || defined (__APPLE__) || defined (__MINGW32__) \
- ||(defined (__vxworks) && ! defined (__RTP__))
- /* On some systems like FreeBSD, MacOS X and Windows, putenv is making
+#if (defined (__FreeBSD__) && (__FreeBSD__ < 7)) || defined (__APPLE__) \
+ || defined (__MINGW32__) ||(defined (__vxworks) && ! defined (__RTP__))
+ /* On some systems like pre-7 FreeBSD, MacOS X and Windows, putenv is making
a copy of the expression string so we can free it after the call to
putenv */
free (expression);
diff --git a/gcc/config/fr30/fr30.c b/gcc/config/fr30/fr30.c
index c910ab83ced..3d01d3e4f66 100644
--- a/gcc/config/fr30/fr30.c
+++ b/gcc/config/fr30/fr30.c
@@ -827,47 +827,23 @@ fr30_move_double (rtx * operands)
{
rtx addr = XEXP (src, 0);
int dregno = REGNO (dest);
- rtx dest0;
- rtx dest1;
+ rtx dest0 = operand_subword (dest, 0, TRUE, mode);;
+ rtx dest1 = operand_subword (dest, 1, TRUE, mode);;
rtx new_mem;
- /* If the high-address word is used in the address, we
- must load it last. Otherwise, load it first. */
- int reverse = (refers_to_regno_p (dregno, dregno + 1, addr, 0) != 0);
-
gcc_assert (GET_CODE (addr) == REG);
- dest0 = operand_subword (dest, reverse, TRUE, mode);
- dest1 = operand_subword (dest, !reverse, TRUE, mode);
-
- if (reverse)
- {
- emit_insn (gen_rtx_SET (VOIDmode, dest1,
- adjust_address (src, SImode, 0)));
- emit_insn (gen_rtx_SET (SImode, dest0,
- gen_rtx_REG (SImode, REGNO (addr))));
- emit_insn (gen_rtx_SET (SImode, dest0,
- plus_constant (dest0, UNITS_PER_WORD)));
-
- new_mem = gen_rtx_MEM (SImode, dest0);
- MEM_COPY_ATTRIBUTES (new_mem, src);
-
- emit_insn (gen_rtx_SET (VOIDmode, dest0, new_mem));
- }
- else
- {
- emit_insn (gen_rtx_SET (VOIDmode, dest0,
- adjust_address (src, SImode, 0)));
- emit_insn (gen_rtx_SET (SImode, dest1,
- gen_rtx_REG (SImode, REGNO (addr))));
- emit_insn (gen_rtx_SET (SImode, dest1,
- plus_constant (dest1, UNITS_PER_WORD)));
-
- new_mem = gen_rtx_MEM (SImode, dest1);
- MEM_COPY_ATTRIBUTES (new_mem, src);
+ /* Copy the address before clobbering it. See PR 34174. */
+ emit_insn (gen_rtx_SET (SImode, dest1, addr));
+ emit_insn (gen_rtx_SET (VOIDmode, dest0,
+ adjust_address (src, SImode, 0)));
+ emit_insn (gen_rtx_SET (SImode, dest1,
+ plus_constant (dest1, UNITS_PER_WORD)));
+
+ new_mem = gen_rtx_MEM (SImode, dest1);
+ MEM_COPY_ATTRIBUTES (new_mem, src);
- emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));
- }
+ emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));
}
else if (src_code == CONST_INT || src_code == CONST_DOUBLE)
{
diff --git a/gcc/config/pa/pa-64.h b/gcc/config/pa/pa-64.h
index e3adcf3ec28..67c8179c573 100644
--- a/gcc/config/pa/pa-64.h
+++ b/gcc/config/pa/pa-64.h
@@ -84,3 +84,17 @@ along with GCC; see the file COPYING3. If not see
want aggregates padded down. */
#define PAD_VARARGS_DOWN (!AGGREGATE_TYPE_P (type))
+
+/* In the PA architecture, it is not possible to directly move data
+ between GENERAL_REGS and FP_REGS. On the 32-bit port, we use the
+ location at SP-16 because PA 1.X only supports 5-bit immediates for
+ floating-point loads and stores. We don't expose this location in
+ the RTL to avoid scheduling related problems. For example, the
+ store and load could be separated by a call to a pure or const
+ function which has no frame and this function might also use SP-16.
+ We have 14-bit immediates on the 64-bit port, so we use secondary
+ memory for the copies. */
+#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
+ (MAYBE_FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2) \
+ || MAYBE_FP_REG_CLASS_P (CLASS2) != FP_REG_CLASS_P (CLASS1))
+
diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h
index 0f0b960e40e..14386436c57 100644
--- a/gcc/config/pa/pa-protos.h
+++ b/gcc/config/pa/pa-protos.h
@@ -174,6 +174,9 @@ extern void pa_asm_output_aligned_local (FILE *, const char *,
unsigned HOST_WIDE_INT,
unsigned int);
extern void pa_hpux_asm_output_external (FILE *, tree, const char *);
+extern bool pa_cannot_change_mode_class (enum machine_mode, enum machine_mode,
+ enum reg_class);
+extern bool pa_modes_tieable_p (enum machine_mode, enum machine_mode);
extern const int magic_milli[];
extern int shadd_constant_p (int);
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 4b5efb50c51..368dcca767a 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -5652,12 +5652,49 @@ pa_secondary_reload (bool in_p, rtx x, enum reg_class class,
if (regno >= FIRST_PSEUDO_REGISTER || GET_CODE (x) == SUBREG)
regno = true_regnum (x);
- /* Handle out of range displacement for integer mode loads/stores of
- FP registers. */
- if (((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
- && GET_MODE_CLASS (mode) == MODE_INT
- && FP_REG_CLASS_P (class))
- || (class == SHIFT_REGS && (regno <= 0 || regno >= 32)))
+ /* In order to allow 14-bit displacements in integer loads and stores,
+ we need to prevent reload from generating out of range integer mode
+ loads and stores to the floating point registers. Previously, we
+ used to call for a secondary reload and have emit_move_sequence()
+ fix the instruction sequence. However, reload occasionally wouldn't
+ generate the reload and we would end up with an invalid REG+D memory
+ address. So, now we use an intermediate general register for most
+ memory loads and stores. */
+ if ((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
+ && GET_MODE_CLASS (mode) == MODE_INT
+ && FP_REG_CLASS_P (class))
+ {
+ /* Reload passes (mem:SI (reg/f:DI 30 %r30) when it wants to check
+ the secondary reload needed for a pseudo. It never passes a
+ REG+D address. */
+ if (GET_CODE (x) == MEM)
+ {
+ x = XEXP (x, 0);
+
+ /* We don't need an intermediate for indexed and LO_SUM DLT
+ memory addresses. When INT14_OK_STRICT is true, it might
+ appear that we could directly allow register indirect
+ memory addresses. However, this doesn't work because we
+ don't support SUBREGs in floating-point register copies
+ and reload doesn't tell us when it's going to use a SUBREG. */
+ if (IS_INDEX_ADDR_P (x)
+ || IS_LO_SUM_DLT_ADDR_P (x))
+ return NO_REGS;
+
+ /* Otherwise, we need an intermediate general register. */
+ return GENERAL_REGS;
+ }
+
+ /* Request a secondary reload with a general scratch register
+ for everthing else. ??? Could symbolic operands be handled
+ directly when generating non-pic PA 2.0 code? */
+ sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode];
+ return NO_REGS;
+ }
+
+ /* We need a secondary register (GPR) for copies between the SAR
+ and anything other than a general register. */
+ if (class == SHIFT_REGS && (regno <= 0 || regno >= 32))
{
sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode];
return NO_REGS;
@@ -5666,16 +5703,15 @@ pa_secondary_reload (bool in_p, rtx x, enum reg_class class,
/* A SAR<->FP register copy requires a secondary register (GPR) as
well as secondary memory. */
if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER
- && ((REGNO_REG_CLASS (regno) == SHIFT_REGS && FP_REG_CLASS_P (class))
- || (class == SHIFT_REGS
- && FP_REG_CLASS_P (REGNO_REG_CLASS (regno)))))
+ && (REGNO_REG_CLASS (regno) == SHIFT_REGS
+ && FP_REG_CLASS_P (class)))
{
sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode];
return NO_REGS;
}
/* Secondary reloads of symbolic operands require %r1 as a scratch
- register when we're generating PIC code and the operand isn't
+ register when we're generating PIC code and when the operand isn't
readonly. */
if (GET_CODE (x) == HIGH)
x = XEXP (x, 0);
@@ -9519,4 +9555,62 @@ pa_hpux_file_end (void)
}
#endif
+/* Return true if a change from mode FROM to mode TO for a register
+ in register class CLASS is invalid. */
+
+bool
+pa_cannot_change_mode_class (enum machine_mode from, enum machine_mode to,
+ enum reg_class class)
+{
+ if (from == to)
+ return false;
+
+ /* Reject changes to/from complex and vector modes. */
+ if (COMPLEX_MODE_P (from) || VECTOR_MODE_P (from)
+ || COMPLEX_MODE_P (to) || VECTOR_MODE_P (to))
+ return true;
+
+ if (GET_MODE_SIZE (from) == GET_MODE_SIZE (to))
+ return false;
+
+ /* There is no way to load QImode or HImode values directly from
+ memory. SImode loads to the FP registers are not zero extended.
+ On the 64-bit target, this conflicts with the definition of
+ LOAD_EXTEND_OP. Thus, we can't allow changing between modes
+ with different sizes in the floating-point registers. */
+ if (MAYBE_FP_REG_CLASS_P (class))
+ return true;
+
+ /* HARD_REGNO_MODE_OK places modes with sizes larger than a word
+ in specific sets of registers. Thus, we cannot allow changing
+ to a larger mode when it's larger than a word. */
+ if (GET_MODE_SIZE (to) > UNITS_PER_WORD
+ && GET_MODE_SIZE (to) > GET_MODE_SIZE (from))
+ return true;
+
+ return false;
+}
+
+/* Returns TRUE if it is a good idea to tie two pseudo registers
+ when one has mode MODE1 and one has mode MODE2.
+ If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
+ for any hard reg, then this must be FALSE for correct output.
+
+ We should return FALSE for QImode and HImode because these modes
+ are not ok in the floating-point registers. However, this prevents
+ tieing these modes to SImode and DImode in the general registers.
+ So, this isn't a good idea. We rely on HARD_REGNO_MODE_OK and
+ CANNOT_CHANGE_MODE_CLASS to prevent these modes from being used
+ in the floating-point registers. */
+
+bool
+pa_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
+{
+ /* Don't tie modes in different classes. */
+ if (GET_MODE_CLASS (mode1) != GET_MODE_CLASS (mode2))
+ return false;
+
+ return true;
+}
+
#include "gt-pa.h"
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 3a305e54903..889a65e0631 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -344,7 +344,7 @@ typedef struct machine_function GTY(())
If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
for any hard reg, then this must be 0 for correct output. */
#define MODES_TIEABLE_P(MODE1, MODE2) \
- (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))
+ pa_modes_tieable_p (MODE1, MODE2)
/* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */
@@ -534,17 +534,6 @@ extern struct rtx_def *hppa_pic_save_rtx (void);
#define MAYBE_FP_REG_CLASS_P(CLASS) \
reg_classes_intersect_p ((CLASS), FP_REGS)
-/* On the PA it is not possible to directly move data between
- GENERAL_REGS and FP_REGS. On the 32-bit port, we use the
- location at SP-16. We don't expose this location in the RTL to
- avoid scheduling related problems. For example, the store and
- load could be separated by a call to a pure or const function
- which has no frame and uses SP-16. */
-#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
- (TARGET_64BIT \
- && (MAYBE_FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2) \
- || MAYBE_FP_REG_CLASS_P (CLASS2) != FP_REG_CLASS_P (CLASS1)))
-
/* Stack layout; function entry, exit and calling. */
@@ -1229,6 +1218,24 @@ extern int may_call_alloca;
(GET_CODE (OP) == CONST_INT && INTVAL (OP) == 63) : 0)))))))
+/* Nonzero if 14-bit offsets can be used for all loads and stores.
+ This is not possible when generating PA 1.x code as floating point
+ loads and stores only support 5-bit offsets. Note that we do not
+ forbid the use of 14-bit offsets in GO_IF_LEGITIMATE_ADDRESS.
+ Instead, we use pa_secondary_reload() to reload integer mode
+ REG+D memory addresses used in floating point loads and stores.
+
+ FIXME: the ELF32 linker clobbers the LSB of the FP register number
+ in PA 2.0 floating-point insns with long displacements. This is
+ because R_PARISC_DPREL14WR and other relocations like it are not
+ yet supported by GNU ld. For now, we reject long displacements
+ on this target. */
+
+#define INT14_OK_STRICT \
+ (TARGET_SOFT_FLOAT \
+ || TARGET_DISABLE_FPREGS \
+ || (TARGET_PA_20 && !TARGET_ELF32))
+
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
We have two alternate definitions for each of them.
@@ -1247,16 +1254,18 @@ extern int may_call_alloca;
/* Nonzero if X is a hard reg that can be used as an index
or if it is a pseudo reg. */
#define REG_OK_FOR_INDEX_P(X) \
-(REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
+ (REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
+
/* Nonzero if X is a hard reg that can be used as a base reg
or if it is a pseudo reg. */
#define REG_OK_FOR_BASE_P(X) \
-(REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
+ (REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
#else
/* Nonzero if X is a hard reg that can be used as an index. */
#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+
/* Nonzero if X is a hard reg that can be used as a base reg. */
#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
@@ -1308,11 +1317,7 @@ extern int may_call_alloca;
We treat a SYMBOL_REF as legitimate if it is part of the current
function's constant-pool, because such addresses can actually be
- output as REG+SMALLINT.
-
- Note we only allow 5 bit immediates for access to a constant address;
- doing so avoids losing for loading/storing a FP register at an address
- which will not fit in 5 bits. */
+ output as REG+SMALLINT. */
#define VAL_5_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) + 0x10 < 0x20)
#define INT_5_BITS(X) VAL_5_BITS_P (INTVAL (X))
@@ -1340,7 +1345,8 @@ extern int may_call_alloca;
((TARGET_64BIT && (MODE) == DImode) \
|| (MODE) == SImode \
|| (MODE) == HImode \
- || (!TARGET_SOFT_FLOAT && ((MODE) == DFmode || (MODE) == SFmode)))
+ || (MODE) == SFmode \
+ || (MODE) == DFmode)
/* These are the modes that we allow for unscaled indexing. */
#define MODE_OK_FOR_UNSCALED_INDEXING_P(MODE) \
@@ -1348,7 +1354,8 @@ extern int may_call_alloca;
|| (MODE) == SImode \
|| (MODE) == HImode \
|| (MODE) == QImode \
- || (!TARGET_SOFT_FLOAT && ((MODE) == DFmode || (MODE) == SFmode)))
+ || (MODE) == SFmode \
+ || (MODE) == DFmode)
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ \
@@ -1382,20 +1389,10 @@ extern int may_call_alloca;
|| (INTVAL (index) % 8) == 0)) \
/* Similarly, the base register for SFmode/DFmode \
loads and stores with long displacements must \
- be aligned. \
- \
- FIXME: the ELF32 linker clobbers the LSB of \
- the FP register number in PA 2.0 floating-point \
- insns with long displacements. This is because \
- R_PARISC_DPREL14WR and other relocations like \
- it are not supported. For now, we reject long \
- displacements on this target. */ \
+ be aligned. */ \
|| (((MODE) == SFmode || (MODE) == DFmode) \
- && (TARGET_SOFT_FLOAT \
- || (TARGET_PA_20 \
- && !TARGET_ELF32 \
- && (INTVAL (index) \
- % GET_MODE_SIZE (MODE)) == 0))))) \
+ && INT14_OK_STRICT \
+ && (INTVAL (index) % GET_MODE_SIZE (MODE)) == 0))) \
|| INT_5_BITS (index))) \
goto ADDR; \
if (!TARGET_DISABLE_INDEXING \
@@ -1495,7 +1492,7 @@ do { \
rtx new, temp = NULL_RTX; \
\
mask = (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- ? (TARGET_PA_20 && !TARGET_ELF32 ? 0x3fff : 0x1f) : 0x3fff); \
+ ? (INT14_OK_STRICT ? 0x3fff : 0x1f) : 0x3fff); \
\
if (optimize && GET_CODE (AD) == PLUS) \
temp = simplify_binary_operation (PLUS, Pmode, \
@@ -1517,9 +1514,10 @@ do { \
newoffset = offset & ~mask; \
\
/* Ensure that long displacements are aligned. */ \
- if (!VAL_5_BITS_P (newoffset) \
- && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
- newoffset &= ~(GET_MODE_SIZE (MODE) -1); \
+ if (mask == 0x3fff \
+ && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ || (TARGET_64BIT && (MODE) == DImode))) \
+ newoffset &= ~(GET_MODE_SIZE (MODE) - 1); \
\
if (newoffset != 0 && VAL_14_BITS_P (newoffset)) \
{ \
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 2fca3e69dc8..e1004d04ae4 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -3125,60 +3125,11 @@
(define_insn ""
[(set (match_operand:HI 0 "move_dest_operand"
- "=r,r,r,r,r,Q,!*q,!r,!*f,?r,?*f")
- (match_operand:HI 1 "move_src_operand"
- "r,J,N,K,RQ,rM,!rM,!*q,!*fM,*f,r"))]
- "(register_operand (operands[0], HImode)
- || reg_or_0_operand (operands[1], HImode))
- && !TARGET_SOFT_FLOAT
- && !TARGET_64BIT"
- "@
- copy %1,%0
- ldi %1,%0
- ldil L'%1,%0
- {zdepi|depwi,z} %Z1,%0
- ldh%M1 %1,%0
- sth%M0 %r1,%0
- mtsar %r1
- {mfctl|mfctl,w} %sar,%0
- fcpy,sgl %f1,%0
- {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
- {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,move,move,move,move")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "move_dest_operand"
- "=r,r,r,r,r,Q,!*q,!r,!*f")
- (match_operand:HI 1 "move_src_operand"
- "r,J,N,K,RQ,rM,!rM,!*q,!*fM"))]
- "(register_operand (operands[0], HImode)
- || reg_or_0_operand (operands[1], HImode))
- && !TARGET_SOFT_FLOAT
- && TARGET_64BIT"
- "@
- copy %1,%0
- ldi %1,%0
- ldil L'%1,%0
- {zdepi|depwi,z} %Z1,%0
- ldh%M1 %1,%0
- sth%M0 %r1,%0
- mtsar %r1
- {mfctl|mfctl,w} %sar,%0
- fcpy,sgl %f1,%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,move,move")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "move_dest_operand"
"=r,r,r,r,r,Q,!*q,!r")
(match_operand:HI 1 "move_src_operand"
"r,J,N,K,RQ,rM,!rM,!*q"))]
"(register_operand (operands[0], HImode)
- || reg_or_0_operand (operands[1], HImode))
- && TARGET_SOFT_FLOAT"
+ || reg_or_0_operand (operands[1], HImode))"
"@
copy %1,%0
ldi %1,%0
@@ -3298,60 +3249,11 @@
(define_insn ""
[(set (match_operand:QI 0 "move_dest_operand"
- "=r,r,r,r,r,Q,!*q,!r,!*f,?r,?*f")
- (match_operand:QI 1 "move_src_operand"
- "r,J,N,K,RQ,rM,!rM,!*q,!*fM,*f,r"))]
- "(register_operand (operands[0], QImode)
- || reg_or_0_operand (operands[1], QImode))
- && !TARGET_SOFT_FLOAT
- && !TARGET_64BIT"
- "@
- copy %1,%0
- ldi %1,%0
- ldil L'%1,%0
- {zdepi|depwi,z} %Z1,%0
- ldb%M1 %1,%0
- stb%M0 %r1,%0
- mtsar %r1
- {mfctl|mfctl,w} %%sar,%0
- fcpy,sgl %f1,%0
- {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
- {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,move,move,move,move")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8")])
-
-(define_insn ""
- [(set (match_operand:QI 0 "move_dest_operand"
- "=r,r,r,r,r,Q,!*q,!r,!*f")
- (match_operand:QI 1 "move_src_operand"
- "r,J,N,K,RQ,rM,!rM,!*q,!*fM"))]
- "(register_operand (operands[0], QImode)
- || reg_or_0_operand (operands[1], QImode))
- && !TARGET_SOFT_FLOAT
- && TARGET_64BIT"
- "@
- copy %1,%0
- ldi %1,%0
- ldil L'%1,%0
- {zdepi|depwi,z} %Z1,%0
- ldb%M1 %1,%0
- stb%M0 %r1,%0
- mtsar %r1
- {mfctl|mfctl,w} %%sar,%0
- fcpy,sgl %f1,%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,move,move")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4")])
-
-(define_insn ""
- [(set (match_operand:QI 0 "move_dest_operand"
"=r,r,r,r,r,Q,!*q,!r")
(match_operand:QI 1 "move_src_operand"
"r,J,N,K,RQ,rM,!rM,!*q"))]
"(register_operand (operands[0], QImode)
- || reg_or_0_operand (operands[1], QImode))
- && TARGET_SOFT_FLOAT"
+ || reg_or_0_operand (operands[1], QImode))"
"@
copy %1,%0
ldi %1,%0
diff --git a/gcc/config/pa/pa32-regs.h b/gcc/config/pa/pa32-regs.h
index a17c117726a..97f48c768b6 100644
--- a/gcc/config/pa/pa32-regs.h
+++ b/gcc/config/pa/pa32-regs.h
@@ -172,8 +172,7 @@
#define VALID_FP_MODE_P(MODE) \
((MODE) == SFmode || (MODE) == DFmode \
|| (MODE) == SCmode || (MODE) == DCmode \
- || (MODE) == QImode || (MODE) == HImode || (MODE) == SImode \
- || (TARGET_PA_11 && (MODE) == DImode))
+ || (MODE) == SImode || (TARGET_PA_11 && (MODE) == DImode))
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
@@ -288,6 +287,11 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
{0x00000000, 0x00000000, 0x01000000}, /* SHIFT_REGS */ \
{0xfffffffe, 0xffffffff, 0x01ffffff}} /* ALL_REGS */
+/* Defines invalid mode changes. */
+
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ pa_cannot_change_mode_class (FROM, TO, CLASS)
+
/* Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
or could index an array. */
diff --git a/gcc/config/pa/pa64-regs.h b/gcc/config/pa/pa64-regs.h
index a9ad8b60e8f..b79dbc98e42 100644
--- a/gcc/config/pa/pa64-regs.h
+++ b/gcc/config/pa/pa64-regs.h
@@ -156,8 +156,7 @@ along with GCC; see the file COPYING3. If not see
#define VALID_FP_MODE_P(MODE) \
((MODE) == SFmode || (MODE) == DFmode \
|| (MODE) == SCmode || (MODE) == DCmode \
- || (MODE) == QImode || (MODE) == HImode || (MODE) == SImode \
- || (MODE) == DImode)
+ || (MODE) == SImode || (MODE) == DImode)
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
On the HP-PA, the cpu registers can hold any mode. We
@@ -242,17 +241,10 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
{0x00000000, 0x10000000}, /* SHIFT_REGS */ \
{0xfffffffe, 0x1fffffff}} /* ALL_REGS */
-/* Defines invalid mode changes.
+/* Defines invalid mode changes. */
- SImode loads to floating-point registers are not zero-extended.
- The definition for LOAD_EXTEND_OP specifies that integer loads
- narrower than BITS_PER_WORD will be zero-extended. As a result,
- we inhibit changes from SImode unless they are to a mode that is
- identical in size. */
-
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
- ((FROM) == SImode && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
- ? reg_classes_intersect_p (CLASS, FP_REGS) : 0)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ pa_cannot_change_mode_class (FROM, TO, CLASS)
/* Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d42dfe0c3d7..08525af7046 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2007-12-10 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/34059
+ * typeck.c (build_class_member_access_expr): Compute MEMBER_SCOPE from
+ MEMBER's BASELINK_ACCESS_BINFO instead of its BASELINK_BINFO.
+
2007-10-26 Jakub Jelinek <jakub@redhat.com>
PR c++/33744
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index c98775eeff8..9e8ca6eabe1 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1795,7 +1795,7 @@ build_class_member_access_expr (tree object, tree member,
warn_deprecated_use (member);
}
else
- member_scope = BINFO_TYPE (BASELINK_BINFO (member));
+ member_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (member));
/* If MEMBER is from an anonymous aggregate, MEMBER_SCOPE will
presently be the anonymous union. Go outwards until we find a
type related to OBJECT_TYPE. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 85789e97743..f8a31aae8a9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,16 @@
+2007-12-10 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/34059
+ * g++.dg/parse/crash40.C: New test.
+
+2007-11-28 Rask Ingemann Lambertsen <rask@sygehus.dk>
+
+ Backport from mainline:
+ 2007-11-26 Rask Ingemann Lambertsen <rask@sygehus.dk>
+
+ PR target/34174
+ * gcc.dg/pr34174-1.c: New.
+
2007-11-26 Uros Bizjak <ubizjak@gmail.com>
PR target/34215
diff --git a/gcc/testsuite/g++.dg/parse/crash40.C b/gcc/testsuite/g++.dg/parse/crash40.C
new file mode 100644
index 00000000000..af44fdb695c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash40.C
@@ -0,0 +1,42 @@
+/* PR c++/34059 */
+/* { dg-do "compile" } */
+
+struct A
+{
+ template<int> void foo();
+};
+struct B : A {};
+struct C : A {};
+
+class AA
+{
+ template<int> void foo(); /* { dg-error "is private" } */
+};
+struct BB : AA {};
+
+class AAA {
+ int get() const {}
+};
+struct BBB {
+ static BBB *foo();
+private:
+ int get() const {} /* { dg-error "is private" } */
+};
+template<bool> struct S {
+ S(unsigned int = BBB::foo()->AAA::get()); /* { dg-error "is not a base of" } */
+};
+template<bool> struct SS {
+ SS(unsigned int = BBB::foo()->get());
+};
+
+void bar()
+{
+ B().C::foo<0>(); /* { dg-error "is not a member of" } */
+ BB().AA::foo<0>(); /* { dg-error "within this context" } */
+
+ int i;
+ i.C::foo<0>(); /* { dg-error "which is of non-class type" } */
+
+ S<false> s;
+ SS<false> ss; /* { dg-error "within this context" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr34174-1.c b/gcc/testsuite/gcc.dg/pr34174-1.c
new file mode 100644
index 00000000000..b5eef148c85
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr34174-1.c
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+/* { dg-options "-std=gnu89" } */
+/* Based on PR target/27386 testcase by Joerg Wunsch. */
+
+extern void abort (void);
+extern void exit (int);
+
+#if __INT_MAX__ >= 9223372036854775807LL
+typedef unsigned int uint64_t;
+#elif __LONG_MAX__ >= 9223372036854775807LL
+typedef unsigned long int uint64_t;
+#elif __LONG_LONG_MAX__ >= 9223372036854775807LL
+typedef unsigned long long int uint64_t;
+#else
+int
+main (void)
+{
+ exit (0);
+}
+#endif
+
+uint64_t a, b, c;
+
+int
+foo (uint64_t x, uint64_t y, uint64_t z, int i)
+{
+ a = x;
+ b = y;
+ c = z;
+ return 2 * i;
+}
+
+int
+main (void)
+{
+ if (foo (1234512345123ull, 3456734567345ull, 7897897897897ull, 42) != 84)
+ abort ();
+ if (a != 1234512345123ull)
+ abort ();
+ if (b != 3456734567345ull)
+ abort ();
+ if (c != 7897897897897ull)
+ abort ();
+ exit (0);
+}
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index f61cb2feeda..17f0f651b59 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,11 @@
+2007-11-26 Paolo Carlini <pcarlini@suse.de>
+
+ * include/bits/locale_facets.tcc (num_put<>::_M_insert_int): When
+ ios_base::showpos and the type is signed and the value is zero,
+ prepend +.
+ * testsuite/22_locale/num_put/put/char/12.cc: New.
+ * testsuite/22_locale/num_put/put/wchar_t/12.cc: Likewise.
+
2007-10-20 Paolo Carlini <pcarlini@suse.de>
* include/tr1/random
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index d3c47ff9b7f..2e4e37c51c3 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -1015,13 +1015,13 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
if (__builtin_expect(__dec, true))
{
// Decimal.
- if (__v > 0)
+ if (__v >= 0)
{
if (__flags & ios_base::showpos
&& numeric_limits<_ValueT>::is_signed)
*--__cs = __lit[__num_base::_S_oplus], ++__len;
}
- else if (__v)
+ else
*--__cs = __lit[__num_base::_S_ominus], ++__len;
}
else if (__flags & ios_base::showbase && __v)
diff --git a/libstdc++-v3/testsuite/22_locale/num_put/put/char/12.cc b/libstdc++-v3/testsuite/22_locale/num_put/put/char/12.cc
new file mode 100644
index 00000000000..c17ecec8171
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/num_put/put/char/12.cc
@@ -0,0 +1,64 @@
+// 2007-11-26 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+
+// This library 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 library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 22.2.2.2.1 num_put members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// http://gcc.gnu.org/ml/libstdc++/2007-11/msg00074.html
+void test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ ostringstream oss1, oss2, oss3;
+ const num_put<char>& np1 = use_facet<num_put<char> >(oss1.getloc());
+ const num_put<char>& np2 = use_facet<num_put<char> >(oss2.getloc());
+ const num_put<char>& np3 = use_facet<num_put<char> >(oss3.getloc());
+
+ string result1, result2, result3;
+
+ long int li1 = 0;
+ long int li2 = 5;
+ double d1 = 0.0;
+
+ oss1.setf(ios_base::showpos);
+ np1.put(oss1.rdbuf(), oss1, '*', li1);
+ result1 = oss1.str();
+ VERIFY( result1 == "+0" );
+
+ oss2.setf(ios_base::showpos);
+ np2.put(oss2.rdbuf(), oss2, '*', li2);
+ result2 = oss2.str();
+ VERIFY( result2 == "+5" );
+
+ oss3.setf(ios_base::showpos);
+ np3.put(oss3.rdbuf(), oss3, '*', d1);
+ result3 = oss3.str();
+ VERIFY( result3 == "+0" );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/12.cc b/libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/12.cc
new file mode 100644
index 00000000000..1467aa3d4a6
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/12.cc
@@ -0,0 +1,64 @@
+// 2007-11-26 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2007 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library 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, or (at your option)
+// any later version.
+
+// This library 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 library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 22.2.2.2.1 num_put members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// http://gcc.gnu.org/ml/libstdc++/2007-11/msg00074.html
+void test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ wostringstream oss1, oss2, oss3;
+ const num_put<wchar_t>& np1 = use_facet<num_put<wchar_t> >(oss1.getloc());
+ const num_put<wchar_t>& np2 = use_facet<num_put<wchar_t> >(oss2.getloc());
+ const num_put<wchar_t>& np3 = use_facet<num_put<wchar_t> >(oss3.getloc());
+
+ wstring result1, result2, result3;
+
+ long int li1 = 0;
+ long int li2 = 5;
+ double d1 = 0.0;
+
+ oss1.setf(ios_base::showpos);
+ np1.put(oss1.rdbuf(), oss1, L'*', li1);
+ result1 = oss1.str();
+ VERIFY( result1 == L"+0" );
+
+ oss2.setf(ios_base::showpos);
+ np2.put(oss2.rdbuf(), oss2, L'*', li2);
+ result2 = oss2.str();
+ VERIFY( result2 == L"+5" );
+
+ oss3.setf(ios_base::showpos);
+ np3.put(oss3.rdbuf(), oss3, L'*', d1);
+ result3 = oss3.str();
+ VERIFY( result3 == L"+0" );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/svn-mergepoint b/svn-mergepoint
index 0acdf81230d..c95b85b1d5c 100644
--- a/svn-mergepoint
+++ b/svn-mergepoint
@@ -1 +1 @@
-130447
+130757