summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arm/arm-protos.h3
-rw-r--r--gcc/config/arm/arm.c252
-rw-r--r--gcc/config/arm/arm.md104
-rw-r--r--gcc/config/i386/driver-i386.c9
-rw-r--r--gcc/config/i386/i386.md3
-rw-r--r--gcc/config/m68k/m68k-devices.def6
-rw-r--r--gcc/config/m68k/m68k-tables.opt18
-rw-r--r--gcc/config/pa/pa.md120
-rw-r--r--gcc/config/rs6000/8540.md50
-rw-r--r--gcc/config/rs6000/e500-double.h24
-rw-r--r--gcc/config/rs6000/e500.h10
-rw-r--r--gcc/config/rs6000/eabispe.h17
-rw-r--r--gcc/config/rs6000/linuxspe.h16
-rw-r--r--gcc/config/rs6000/predicates.md30
-rw-r--r--gcc/config/rs6000/rs6000-cpus.def3
-rw-r--r--gcc/config/rs6000/rs6000-opts.h1
-rw-r--r--gcc/config/rs6000/rs6000-protos.h4
-rw-r--r--gcc/config/rs6000/rs6000.c503
-rw-r--r--gcc/config/rs6000/rs6000.h7
-rw-r--r--gcc/config/rs6000/rs6000.md164
-rw-r--r--gcc/config/rs6000/rtems.h14
-rw-r--r--gcc/config/rs6000/vxworks.h11
22 files changed, 814 insertions, 555 deletions
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index cb74d707c21..b3384701f0b 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -245,6 +245,9 @@ struct tune_params
extern const struct tune_params *current_tune;
extern int vfp3_const_double_for_fract_bits (rtx);
+
+extern void arm_emit_coreregs_64bit_shift (enum rtx_code, rtx, rtx, rtx, rtx,
+ rtx);
#endif /* RTX_CODE */
extern void arm_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 2c62c518e67..3ad4c752ac8 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -25933,4 +25933,256 @@ arm_autoinc_modes_ok_p (enum machine_mode mode, enum arm_auto_incmodes code)
return false;
}
+/* The default expansion of general 64-bit shifts in core-regs is suboptimal,
+ on ARM, since we know that shifts by negative amounts are no-ops.
+ Additionally, the default expansion code is not available or suitable
+ for post-reload insn splits (this can occur when the register allocator
+ chooses not to do a shift in NEON).
+
+ This function is used in both initial expand and post-reload splits, and
+ handles all kinds of 64-bit shifts.
+
+ Input requirements:
+ - It is safe for the input and output to be the same register, but
+ early-clobber rules apply for the shift amount and scratch registers.
+ - Shift by register requires both scratch registers. Shift by a constant
+ less than 32 in Thumb2 mode requires SCRATCH1 only. In all other cases
+ the scratch registers may be NULL.
+ - Ashiftrt by a register also clobbers the CC register. */
+void
+arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx out, rtx in,
+ rtx amount, rtx scratch1, rtx scratch2)
+{
+ rtx out_high = gen_highpart (SImode, out);
+ rtx out_low = gen_lowpart (SImode, out);
+ rtx in_high = gen_highpart (SImode, in);
+ rtx in_low = gen_lowpart (SImode, in);
+
+ /* Terminology:
+ in = the register pair containing the input value.
+ out = the destination register pair.
+ up = the high- or low-part of each pair.
+ down = the opposite part to "up".
+ In a shift, we can consider bits to shift from "up"-stream to
+ "down"-stream, so in a left-shift "up" is the low-part and "down"
+ is the high-part of each register pair. */
+
+ rtx out_up = code == ASHIFT ? out_low : out_high;
+ rtx out_down = code == ASHIFT ? out_high : out_low;
+ rtx in_up = code == ASHIFT ? in_low : in_high;
+ rtx in_down = code == ASHIFT ? in_high : in_low;
+
+ gcc_assert (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT);
+ gcc_assert (out
+ && (REG_P (out) || GET_CODE (out) == SUBREG)
+ && GET_MODE (out) == DImode);
+ gcc_assert (in
+ && (REG_P (in) || GET_CODE (in) == SUBREG)
+ && GET_MODE (in) == DImode);
+ gcc_assert (amount
+ && (((REG_P (amount) || GET_CODE (amount) == SUBREG)
+ && GET_MODE (amount) == SImode)
+ || CONST_INT_P (amount)));
+ gcc_assert (scratch1 == NULL
+ || (GET_CODE (scratch1) == SCRATCH)
+ || (GET_MODE (scratch1) == SImode
+ && REG_P (scratch1)));
+ gcc_assert (scratch2 == NULL
+ || (GET_CODE (scratch2) == SCRATCH)
+ || (GET_MODE (scratch2) == SImode
+ && REG_P (scratch2)));
+ gcc_assert (!REG_P (out) || !REG_P (amount)
+ || !HARD_REGISTER_P (out)
+ || (REGNO (out) != REGNO (amount)
+ && REGNO (out) + 1 != REGNO (amount)));
+
+ /* Macros to make following code more readable. */
+ #define SUB_32(DEST,SRC) \
+ gen_addsi3 ((DEST), (SRC), gen_rtx_CONST_INT (VOIDmode, -32))
+ #define RSB_32(DEST,SRC) \
+ gen_subsi3 ((DEST), gen_rtx_CONST_INT (VOIDmode, 32), (SRC))
+ #define SUB_S_32(DEST,SRC) \
+ gen_addsi3_compare0 ((DEST), (SRC), \
+ gen_rtx_CONST_INT (VOIDmode, -32))
+ #define SET(DEST,SRC) \
+ gen_rtx_SET (SImode, (DEST), (SRC))
+ #define SHIFT(CODE,SRC,AMOUNT) \
+ gen_rtx_fmt_ee ((CODE), SImode, (SRC), (AMOUNT))
+ #define LSHIFT(CODE,SRC,AMOUNT) \
+ gen_rtx_fmt_ee ((CODE) == ASHIFT ? ASHIFT : LSHIFTRT, \
+ SImode, (SRC), (AMOUNT))
+ #define REV_LSHIFT(CODE,SRC,AMOUNT) \
+ gen_rtx_fmt_ee ((CODE) == ASHIFT ? LSHIFTRT : ASHIFT, \
+ SImode, (SRC), (AMOUNT))
+ #define ORR(A,B) \
+ gen_rtx_IOR (SImode, (A), (B))
+ #define BRANCH(COND,LABEL) \
+ gen_arm_cond_branch ((LABEL), \
+ gen_rtx_ ## COND (CCmode, cc_reg, \
+ const0_rtx), \
+ cc_reg)
+
+ /* Shifts by register and shifts by constant are handled separately. */
+ if (CONST_INT_P (amount))
+ {
+ /* We have a shift-by-constant. */
+
+ /* First, handle out-of-range shift amounts.
+ In both cases we try to match the result an ARM instruction in a
+ shift-by-register would give. This helps reduce execution
+ differences between optimization levels, but it won't stop other
+ parts of the compiler doing different things. This is "undefined
+ behaviour, in any case. */
+ if (INTVAL (amount) <= 0)
+ emit_insn (gen_movdi (out, in));
+ else if (INTVAL (amount) >= 64)
+ {
+ if (code == ASHIFTRT)
+ {
+ rtx const31_rtx = gen_rtx_CONST_INT (VOIDmode, 31);
+ emit_insn (SET (out_down, SHIFT (code, in_up, const31_rtx)));
+ emit_insn (SET (out_up, SHIFT (code, in_up, const31_rtx)));
+ }
+ else
+ emit_insn (gen_movdi (out, const0_rtx));
+ }
+
+ /* Now handle valid shifts. */
+ else if (INTVAL (amount) < 32)
+ {
+ /* Shifts by a constant less than 32. */
+ rtx reverse_amount = gen_rtx_CONST_INT (VOIDmode,
+ 32 - INTVAL (amount));
+
+ emit_insn (SET (out_down, LSHIFT (code, in_down, amount)));
+ emit_insn (SET (out_down,
+ ORR (REV_LSHIFT (code, in_up, reverse_amount),
+ out_down)));
+ emit_insn (SET (out_up, SHIFT (code, in_up, amount)));
+ }
+ else
+ {
+ /* Shifts by a constant greater than 31. */
+ rtx adj_amount = gen_rtx_CONST_INT (VOIDmode, INTVAL (amount) - 32);
+
+ emit_insn (SET (out_down, SHIFT (code, in_up, adj_amount)));
+ if (code == ASHIFTRT)
+ emit_insn (gen_ashrsi3 (out_up, in_up,
+ gen_rtx_CONST_INT (VOIDmode, 31)));
+ else
+ emit_insn (SET (out_up, const0_rtx));
+ }
+ }
+ else
+ {
+ /* We have a shift-by-register. */
+ rtx cc_reg = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
+
+ /* This alternative requires the scratch registers. */
+ gcc_assert (scratch1 && REG_P (scratch1));
+ gcc_assert (scratch2 && REG_P (scratch2));
+
+ /* We will need the values "amount-32" and "32-amount" later.
+ Swapping them around now allows the later code to be more general. */
+ switch (code)
+ {
+ case ASHIFT:
+ emit_insn (SUB_32 (scratch1, amount));
+ emit_insn (RSB_32 (scratch2, amount));
+ break;
+ case ASHIFTRT:
+ emit_insn (RSB_32 (scratch1, amount));
+ /* Also set CC = amount > 32. */
+ emit_insn (SUB_S_32 (scratch2, amount));
+ break;
+ case LSHIFTRT:
+ emit_insn (RSB_32 (scratch1, amount));
+ emit_insn (SUB_32 (scratch2, amount));
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ /* Emit code like this:
+
+ arithmetic-left:
+ out_down = in_down << amount;
+ out_down = (in_up << (amount - 32)) | out_down;
+ out_down = ((unsigned)in_up >> (32 - amount)) | out_down;
+ out_up = in_up << amount;
+
+ arithmetic-right:
+ out_down = in_down >> amount;
+ out_down = (in_up << (32 - amount)) | out_down;
+ if (amount < 32)
+ out_down = ((signed)in_up >> (amount - 32)) | out_down;
+ out_up = in_up << amount;
+
+ logical-right:
+ out_down = in_down >> amount;
+ out_down = (in_up << (32 - amount)) | out_down;
+ if (amount < 32)
+ out_down = ((unsigned)in_up >> (amount - 32)) | out_down;
+ out_up = in_up << amount;
+
+ The ARM and Thumb2 variants are the same but implemented slightly
+ differently. If this were only called during expand we could just
+ use the Thumb2 case and let combine do the right thing, but this
+ can also be called from post-reload splitters. */
+
+ emit_insn (SET (out_down, LSHIFT (code, in_down, amount)));
+
+ if (!TARGET_THUMB2)
+ {
+ /* Emit code for ARM mode. */
+ emit_insn (SET (out_down,
+ ORR (SHIFT (ASHIFT, in_up, scratch1), out_down)));
+ if (code == ASHIFTRT)
+ {
+ rtx done_label = gen_label_rtx ();
+ emit_jump_insn (BRANCH (LT, done_label));
+ emit_insn (SET (out_down, ORR (SHIFT (ASHIFTRT, in_up, scratch2),
+ out_down)));
+ emit_label (done_label);
+ }
+ else
+ emit_insn (SET (out_down, ORR (SHIFT (LSHIFTRT, in_up, scratch2),
+ out_down)));
+ }
+ else
+ {
+ /* Emit code for Thumb2 mode.
+ Thumb2 can't do shift and or in one insn. */
+ emit_insn (SET (scratch1, SHIFT (ASHIFT, in_up, scratch1)));
+ emit_insn (gen_iorsi3 (out_down, out_down, scratch1));
+
+ if (code == ASHIFTRT)
+ {
+ rtx done_label = gen_label_rtx ();
+ emit_jump_insn (BRANCH (LT, done_label));
+ emit_insn (SET (scratch2, SHIFT (ASHIFTRT, in_up, scratch2)));
+ emit_insn (SET (out_down, ORR (out_down, scratch2)));
+ emit_label (done_label);
+ }
+ else
+ {
+ emit_insn (SET (scratch2, SHIFT (LSHIFTRT, in_up, scratch2)));
+ emit_insn (gen_iorsi3 (out_down, out_down, scratch2));
+ }
+ }
+
+ emit_insn (SET (out_up, SHIFT (code, in_up, amount)));
+ }
+
+ #undef SUB_32
+ #undef RSB_32
+ #undef SUB_S_32
+ #undef SET
+ #undef SHIFT
+ #undef LSHIFT
+ #undef REV_LSHIFT
+ #undef ORR
+ #undef BRANCH
+}
+
#include "gt-arm.h"
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index b1ad3bf34eb..bc97a4a3f78 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -3520,21 +3520,37 @@
(match_operand:SI 2 "reg_or_int_operand" "")))]
"TARGET_32BIT"
"
- if (GET_CODE (operands[2]) == CONST_INT)
+ if (!CONST_INT_P (operands[2])
+ && (TARGET_REALLY_IWMMXT || (TARGET_HARD_FLOAT && TARGET_MAVERICK)))
+ ; /* No special preparation statements; expand pattern as above. */
+ else
{
- if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
+ rtx scratch1, scratch2;
+
+ if (CONST_INT_P (operands[2])
+ && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
{
emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
DONE;
}
- /* Ideally we shouldn't fail here if we could know that operands[1]
- ends up already living in an iwmmxt register. Otherwise it's
- cheaper to have the alternate code being generated than moving
- values to iwmmxt regs and back. */
- FAIL;
+
+ /* Ideally we should use iwmmxt here if we could know that operands[1]
+ ends up already living in an iwmmxt register. Otherwise it's
+ cheaper to have the alternate code being generated than moving
+ values to iwmmxt regs and back. */
+
+ /* If we're optimizing for size, we prefer the libgcc calls. */
+ if (optimize_function_for_size_p (cfun))
+ FAIL;
+
+ /* Expand operation using core-registers.
+ 'FAIL' would achieve the same thing, but this is a bit smarter. */
+ scratch1 = gen_reg_rtx (SImode);
+ scratch2 = gen_reg_rtx (SImode);
+ arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
+ operands[2], scratch1, scratch2);
+ DONE;
}
- else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK))
- FAIL;
"
)
@@ -3579,21 +3595,37 @@
(match_operand:SI 2 "reg_or_int_operand" "")))]
"TARGET_32BIT"
"
- if (GET_CODE (operands[2]) == CONST_INT)
+ if (!CONST_INT_P (operands[2])
+ && (TARGET_REALLY_IWMMXT || (TARGET_HARD_FLOAT && TARGET_MAVERICK)))
+ ; /* No special preparation statements; expand pattern as above. */
+ else
{
- if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
+ rtx scratch1, scratch2;
+
+ if (CONST_INT_P (operands[2])
+ && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
{
emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
DONE;
}
- /* Ideally we shouldn't fail here if we could know that operands[1]
- ends up already living in an iwmmxt register. Otherwise it's
- cheaper to have the alternate code being generated than moving
- values to iwmmxt regs and back. */
- FAIL;
+
+ /* Ideally we should use iwmmxt here if we could know that operands[1]
+ ends up already living in an iwmmxt register. Otherwise it's
+ cheaper to have the alternate code being generated than moving
+ values to iwmmxt regs and back. */
+
+ /* If we're optimizing for size, we prefer the libgcc calls. */
+ if (optimize_function_for_size_p (cfun))
+ FAIL;
+
+ /* Expand operation using core-registers.
+ 'FAIL' would achieve the same thing, but this is a bit smarter. */
+ scratch1 = gen_reg_rtx (SImode);
+ scratch2 = gen_reg_rtx (SImode);
+ arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
+ operands[2], scratch1, scratch2);
+ DONE;
}
- else if (!TARGET_REALLY_IWMMXT)
- FAIL;
"
)
@@ -3636,21 +3668,37 @@
(match_operand:SI 2 "reg_or_int_operand" "")))]
"TARGET_32BIT"
"
- if (GET_CODE (operands[2]) == CONST_INT)
+ if (!CONST_INT_P (operands[2])
+ && (TARGET_REALLY_IWMMXT || (TARGET_HARD_FLOAT && TARGET_MAVERICK)))
+ ; /* No special preparation statements; expand pattern as above. */
+ else
{
- if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
+ rtx scratch1, scratch2;
+
+ if (CONST_INT_P (operands[2])
+ && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
{
emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
DONE;
}
- /* Ideally we shouldn't fail here if we could know that operands[1]
- ends up already living in an iwmmxt register. Otherwise it's
- cheaper to have the alternate code being generated than moving
- values to iwmmxt regs and back. */
- FAIL;
+
+ /* Ideally we should use iwmmxt here if we could know that operands[1]
+ ends up already living in an iwmmxt register. Otherwise it's
+ cheaper to have the alternate code being generated than moving
+ values to iwmmxt regs and back. */
+
+ /* If we're optimizing for size, we prefer the libgcc calls. */
+ if (optimize_function_for_size_p (cfun))
+ FAIL;
+
+ /* Expand operation using core-registers.
+ 'FAIL' would achieve the same thing, but this is a bit smarter. */
+ scratch1 = gen_reg_rtx (SImode);
+ scratch2 = gen_reg_rtx (SImode);
+ arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
+ operands[2], scratch1, scratch2);
+ DONE;
}
- else if (!TARGET_REALLY_IWMMXT)
- FAIL;
"
)
@@ -7755,7 +7803,7 @@
;; Patterns to match conditional branch insns.
;;
-(define_insn "*arm_cond_branch"
+(define_insn "arm_cond_branch"
[(set (pc)
(if_then_else (match_operator 1 "arm_comparison_operator"
[(match_operand 2 "cc_register" "") (const_int 0)])
diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c
index e93e8d9e5e7..94f38199f10 100644
--- a/gcc/config/i386/driver-i386.c
+++ b/gcc/config/i386/driver-i386.c
@@ -398,6 +398,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
unsigned int has_fma = 0, has_fma4 = 0, has_xop = 0;
unsigned int has_bmi = 0, has_bmi2 = 0, has_tbm = 0, has_lzcnt = 0;
unsigned int has_hle = 0, has_rtm = 0;
+ unsigned int has_rdrnd = 0, has_f16c = 0, has_fsgsbase = 0;
bool arch;
@@ -445,6 +446,8 @@ const char *host_detect_local_cpu (int argc, const char **argv)
has_aes = ecx & bit_AES;
has_pclmul = ecx & bit_PCLMUL;
has_fma = ecx & bit_FMA;
+ has_f16c = ecx & bit_F16C;
+ has_rdrnd = ecx & bit_RDRND;
has_cmpxchg8b = edx & bit_CMPXCHG8B;
has_cmov = edx & bit_CMOV;
@@ -461,6 +464,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
has_rtm = ebx & bit_RTM;
has_avx2 = ebx & bit_AVX2;
has_bmi2 = ebx & bit_BMI2;
+ has_fsgsbase = ebx & bit_FSGSBASE;
}
/* Check cpuid level of extended features. */
@@ -733,11 +737,14 @@ const char *host_detect_local_cpu (int argc, const char **argv)
const char *lzcnt = has_lzcnt ? " -mlzcnt" : " -mno-lzcnt";
const char *hle = has_hle ? " -mhle" : " -mno-hle";
const char *rtm = has_rtm ? " -mrtm" : " -mno-rtm";
+ const char *rdrnd = has_rdrnd ? " -mrdrnd" : " -mno-rdrnd";
+ const char *f16c = has_f16c ? " -mf16c" : " -mno-f16c";
+ const char *fsgsbase = has_fsgsbase ? " -mfsgsbase" : " -mno-fsgsbase";
options = concat (options, cx16, sahf, movbe, ase, pclmul,
popcnt, abm, lwp, fma, fma4, xop, bmi, bmi2,
tbm, avx, avx2, sse4_2, sse4_1, lzcnt, rtm,
- hle, NULL);
+ hle, rdrnd, f16c, fsgsbase, NULL);
}
done:
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 01e2421de7d..67281d84bca 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -17465,6 +17465,9 @@
"(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
&& peep2_reg_dead_p (4, operands[0])
&& !reg_overlap_mentioned_p (operands[0], operands[1])
+ && (<MODE>mode != QImode
+ || immediate_operand (operands[2], QImode)
+ || q_regs_operand (operands[2], QImode))
&& ix86_match_ccmode (peep2_next_insn (3),
(GET_CODE (operands[3]) == PLUS
|| GET_CODE (operands[3]) == MINUS)
diff --git a/gcc/config/m68k/m68k-devices.def b/gcc/config/m68k/m68k-devices.def
index 4838fb06296..41e11c88bd2 100644
--- a/gcc/config/m68k/m68k-devices.def
+++ b/gcc/config/m68k/m68k-devices.def
@@ -84,10 +84,16 @@ M68K_DEVICE ("cpu32", cpu32, "cpu32", "cpu32", cpu32, isa_cpu32, FL_MMU)
/* For historical reasons, the 51 multilib is named 51qe. */
M68K_DEVICE ("51", mcf51, "51", "51qe", cfv1, isa_c, FL_CF_USP)
M68K_DEVICE ("51ac", mcf51ac, "51", "51qe", cfv1, isa_c, FL_CF_USP)
+M68K_DEVICE ("51ag", mcf51ag, "51", "51qe", cfv1, isa_c, FL_CF_USP)
M68K_DEVICE ("51cn", mcf51cn, "51", "51qe", cfv1, isa_c, FL_CF_USP)
M68K_DEVICE ("51em", mcf51em, "51", "51qe", cfv1, isa_c, FL_CF_USP | FL_CF_MAC)
+M68K_DEVICE ("51je", mcf51je, "51", "51qe", cfv1, isa_c, FL_CF_USP | FL_CF_MAC)
+M68K_DEVICE ("51jf", mcf51jf, "51", "51qe", cfv1, isa_c, FL_CF_USP | FL_CF_EMAC)
+M68K_DEVICE ("51jg", mcf51jg, "51", "51qe", cfv1, isa_c, FL_CF_USP | FL_CF_EMAC)
M68K_DEVICE ("51jm", mcf51jm, "51", "51qe", cfv1, isa_c, FL_CF_USP)
+M68K_DEVICE ("51mm", mcf51mm, "51", "51qe", cfv1, isa_c, FL_CF_USP | FL_CF_MAC)
M68K_DEVICE ("51qe", mcf51qe, "51", "51qe", cfv1, isa_c, FL_CF_USP)
+M68K_DEVICE ("51qm", mcf51qm, "51", "51qe", cfv1, isa_c, FL_CF_USP | FL_CF_EMAC)
/* ColdFire CFV2 processors. */
M68K_DEVICE ("5202", mcf5202, "5206", "5206", cfv2, isa_a, 0)
diff --git a/gcc/config/m68k/m68k-tables.opt b/gcc/config/m68k/m68k-tables.opt
index 96eabc7f262..6cac87535ac 100644
--- a/gcc/config/m68k/m68k-tables.opt
+++ b/gcc/config/m68k/m68k-tables.opt
@@ -58,18 +58,36 @@ EnumValue
Enum(target_device) String(51ac) Value(mcf51ac)
EnumValue
+Enum(target_device) String(51ag) Value(mcf51ag)
+
+EnumValue
Enum(target_device) String(51cn) Value(mcf51cn)
EnumValue
Enum(target_device) String(51em) Value(mcf51em)
EnumValue
+Enum(target_device) String(51je) Value(mcf51je)
+
+EnumValue
+Enum(target_device) String(51jf) Value(mcf51jf)
+
+EnumValue
+Enum(target_device) String(51jg) Value(mcf51jg)
+
+EnumValue
Enum(target_device) String(51jm) Value(mcf51jm)
EnumValue
+Enum(target_device) String(51mm) Value(mcf51mm)
+
+EnumValue
Enum(target_device) String(51qe) Value(mcf51qe)
EnumValue
+Enum(target_device) String(51qm) Value(mcf51qm)
+
+EnumValue
Enum(target_device) String(5202) Value(mcf5202)
EnumValue
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index a7ad6268bdd..8a7e6858c11 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -7190,12 +7190,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(set (attr "length") (symbol_ref "pa_attr_length_call (insn, 0)"))])
(define_insn "call_symref_pic"
- [(set (match_operand:SI 2 "register_operand" "=&r") (reg:SI 19))
- (call (mem:SI (match_operand 0 "call_operand_address" ""))
+ [(call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" "i"))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (use (match_dup 2))
+ (clobber (match_operand 2))
(use (reg:SI 19))
(use (const_int 0))]
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
@@ -7211,12 +7210,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; terminate the basic block. The split has to contain more than one
;; insn.
(define_split
- [(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
- (call (mem:SI (match_operand 0 "call_operand_address" ""))
+ [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" ""))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (use (match_dup 2))
+ (clobber (match_operand 2))
(use (reg:SI 19))
(use (const_int 0))])]
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
@@ -7231,12 +7229,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
"")
(define_split
- [(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
- (call (mem:SI (match_operand 0 "call_operand_address" ""))
+ [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" ""))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (use (match_dup 2))
+ (clobber (match_operand 2))
(use (reg:SI 19))
(use (const_int 0))])]
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
@@ -7269,12 +7266,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; This pattern is split if it is necessary to save and restore the
;; PIC register.
(define_insn "call_symref_64bit"
- [(set (match_operand:DI 2 "register_operand" "=&r") (reg:DI 27))
- (call (mem:SI (match_operand 0 "call_operand_address" ""))
+ [(call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" "i"))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (use (match_dup 2))
+ (clobber (match_operand 2))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))]
@@ -7291,12 +7287,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; terminate the basic block. The split has to contain more than one
;; insn.
(define_split
- [(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
- (call (mem:SI (match_operand 0 "call_operand_address" ""))
+ [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" ""))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (use (match_dup 2))
+ (clobber (match_operand 2))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))])]
@@ -7313,12 +7308,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
"")
(define_split
- [(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
- (call (mem:SI (match_operand 0 "call_operand_address" ""))
+ [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" ""))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (use (match_dup 2))
+ (clobber (match_operand 2))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))])]
@@ -7368,12 +7362,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; This pattern is split if it is necessary to save and restore the
;; PIC register.
(define_insn "call_reg_pic"
- [(set (match_operand:SI 1 "register_operand" "=&r") (reg:SI 19))
- (call (mem:SI (reg:SI 22))
+ [(call (mem:SI (reg:SI 22))
(match_operand 0 "" "i"))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (use (match_dup 1))
+ (clobber (match_operand 1))
(use (reg:SI 19))
(use (const_int 1))]
"!TARGET_64BIT"
@@ -7389,12 +7382,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; terminate the basic block. The split has to contain more than one
;; insn.
(define_split
- [(parallel [(set (match_operand:SI 1 "register_operand" "") (reg:SI 19))
- (call (mem:SI (reg:SI 22))
+ [(parallel [(call (mem:SI (reg:SI 22))
(match_operand 0 "" ""))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (use (match_dup 1))
+ (clobber (match_operand 1))
(use (reg:SI 19))
(use (const_int 1))])]
"!TARGET_64BIT && reload_completed
@@ -7409,12 +7401,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
"")
(define_split
- [(parallel [(set (match_operand:SI 1 "register_operand" "") (reg:SI 19))
- (call (mem:SI (reg:SI 22))
+ [(parallel [(call (mem:SI (reg:SI 22))
(match_operand 0 "" ""))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (use (match_dup 1))
+ (clobber (match_operand 1))
(use (reg:SI 19))
(use (const_int 1))])]
"!TARGET_64BIT && reload_completed"
@@ -7446,12 +7437,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; This pattern is split if it is necessary to save and restore the
;; PIC register.
(define_insn "call_reg_64bit"
- [(set (match_operand:DI 2 "register_operand" "=&r") (reg:DI 27))
- (call (mem:SI (match_operand:DI 0 "register_operand" "r"))
+ [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
(match_operand 1 "" "i"))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (use (match_dup 2))
+ (clobber (match_operand 2))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 1))]
@@ -7468,12 +7458,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; terminate the basic block. The split has to contain more than one
;; insn.
(define_split
- [(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
- (call (mem:SI (match_operand 0 "register_operand" ""))
+ [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
(match_operand 1 "" ""))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (use (match_dup 2))
+ (clobber (match_operand 2))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 1))])]
@@ -7490,12 +7479,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
"")
(define_split
- [(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
- (call (mem:SI (match_operand 0 "register_operand" ""))
+ [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
(match_operand 1 "" ""))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (use (match_dup 2))
+ (clobber (match_operand 2))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 1))])]
@@ -7654,13 +7642,12 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(set (attr "length") (symbol_ref "pa_attr_length_call (insn, 0)"))])
(define_insn "call_val_symref_pic"
- [(set (match_operand:SI 3 "register_operand" "=&r") (reg:SI 19))
- (set (match_operand 0 "" "")
+ [(set (match_operand 0 "" "")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "i")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (use (match_dup 3))
+ (clobber (match_operand 3))
(use (reg:SI 19))
(use (const_int 0))]
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
@@ -7676,13 +7663,12 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; terminate the basic block. The split has to contain more than one
;; insn.
(define_split
- [(parallel [(set (match_operand:SI 3 "register_operand" "") (reg:SI 19))
- (set (match_operand 0 "" "")
+ [(parallel [(set (match_operand 0 "" "")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (use (match_dup 3))
+ (clobber (match_operand 3))
(use (reg:SI 19))
(use (const_int 0))])]
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
@@ -7698,13 +7684,12 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
"")
(define_split
- [(parallel [(set (match_operand:SI 3 "register_operand" "") (reg:SI 19))
- (set (match_operand 0 "" "")
+ [(parallel [(set (match_operand 0 "" "")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (use (match_dup 3))
+ (clobber (match_operand 3))
(use (reg:SI 19))
(use (const_int 0))])]
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
@@ -7739,13 +7724,12 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; This pattern is split if it is necessary to save and restore the
;; PIC register.
(define_insn "call_val_symref_64bit"
- [(set (match_operand:DI 3 "register_operand" "=&r") (reg:DI 27))
- (set (match_operand 0 "" "")
+ [(set (match_operand 0 "" "")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "i")))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (use (match_dup 3))
+ (clobber (match_operand 3))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))]
@@ -7762,13 +7746,12 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; terminate the basic block. The split has to contain more than one
;; insn.
(define_split
- [(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
- (set (match_operand 0 "" "")
+ [(parallel [(set (match_operand 0 "" "")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "")))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (use (match_dup 3))
+ (clobber (match_operand 3))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))])]
@@ -7786,13 +7769,12 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
"")
(define_split
- [(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
- (set (match_operand 0 "" "")
+ [(parallel [(set (match_operand 0 "" "")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "")))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (use (match_dup 3))
+ (clobber (match_operand 3))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))])]
@@ -7845,13 +7827,12 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; This pattern is split if it is necessary to save and restore the
;; PIC register.
(define_insn "call_val_reg_pic"
- [(set (match_operand:SI 2 "register_operand" "=&r") (reg:SI 19))
- (set (match_operand 0 "" "")
+ [(set (match_operand 0 "" "")
(call (mem:SI (reg:SI 22))
(match_operand 1 "" "i")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (use (match_dup 2))
+ (clobber (match_operand 2))
(use (reg:SI 19))
(use (const_int 1))]
"!TARGET_64BIT"
@@ -7867,13 +7848,12 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; terminate the basic block. The split has to contain more than one
;; insn.
(define_split
- [(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
- (set (match_operand 0 "" "")
+ [(parallel [(set (match_operand 0 "" "")
(call (mem:SI (reg:SI 22))
(match_operand 1 "" "")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (use (match_dup 2))
+ (clobber (match_operand 2))
(use (reg:SI 19))
(use (const_int 1))])]
"!TARGET_64BIT && reload_completed
@@ -7889,13 +7869,12 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
"")
(define_split
- [(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
- (set (match_operand 0 "" "")
+ [(parallel [(set (match_operand 0 "" "")
(call (mem:SI (reg:SI 22))
(match_operand 1 "" "")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (use (match_dup 2))
+ (clobber (match_operand 2))
(use (reg:SI 19))
(use (const_int 1))])]
"!TARGET_64BIT && reload_completed"
@@ -7929,13 +7908,12 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; This pattern is split if it is necessary to save and restore the
;; PIC register.
(define_insn "call_val_reg_64bit"
- [(set (match_operand:DI 3 "register_operand" "=&r") (reg:DI 27))
- (set (match_operand 0 "" "")
+ [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
(match_operand 2 "" "i")))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (use (match_dup 3))
+ (clobber (match_operand 3))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 1))]
@@ -7952,13 +7930,12 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; terminate the basic block. The split has to contain more than one
;; insn.
(define_split
- [(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
- (set (match_operand 0 "" "")
+ [(parallel [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:DI 1 "register_operand" ""))
(match_operand 2 "" "")))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (use (match_dup 3))
+ (clobber (match_operand 3))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 1))])]
@@ -7976,13 +7953,12 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
"")
(define_split
- [(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
- (set (match_operand 0 "" "")
+ [(parallel [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:DI 1 "register_operand" ""))
(match_operand 2 "" "")))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (use (match_dup 3))
+ (clobber (match_operand 3))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 1))])]
diff --git a/gcc/config/rs6000/8540.md b/gcc/config/rs6000/8540.md
index 4096dff432c..c767c0d8aa3 100644
--- a/gcc/config/rs6000/8540.md
+++ b/gcc/config/rs6000/8540.md
@@ -87,18 +87,18 @@
(and (eq_attr "type" "integer,insert_word,insert_dword,cmp,compare,\
delayed_compare,var_delayed_compare,fast_compare,\
shift,trap,var_shift_rotate,cntlz,exts,isel")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
(define_insn_reservation "ppc8540_two" 1
(and (eq_attr "type" "two")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire,\
ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
(define_insn_reservation "ppc8540_three" 1
(and (eq_attr "type" "three")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire,\
ppc8540_issue+ppc8540_su_stage0+ppc8540_retire,\
ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
@@ -106,13 +106,13 @@
;; Branch. Actually this latency time is not used by the scheduler.
(define_insn_reservation "ppc8540_branch" 1
(and (eq_attr "type" "jmpreg,branch,isync")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_bu,ppc8540_retire")
;; Multiply
(define_insn_reservation "ppc8540_multiply" 4
(and (eq_attr "type" "imul,imul2,imul3,imul_compare")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\
ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire")
@@ -122,57 +122,57 @@
;; time.
(define_insn_reservation "ppc8540_divide" 14
(and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0+ppc8540_mu_div,\
ppc8540_mu_div*13")
;; CR logical
(define_insn_reservation "ppc8540_cr_logical" 1
(and (eq_attr "type" "cr_logical,delayed_cr")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_bu,ppc8540_retire")
;; Mfcr
(define_insn_reservation "ppc8540_mfcr" 1
(and (eq_attr "type" "mfcr")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
;; Mtcrf
(define_insn_reservation "ppc8540_mtcrf" 1
(and (eq_attr "type" "mtcr")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
;; Mtjmpr
(define_insn_reservation "ppc8540_mtjmpr" 1
(and (eq_attr "type" "mtjmpr,mfjmpr")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
;; Loads
(define_insn_reservation "ppc8540_load" 3
(and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\
load_l,sync")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire")
;; Stores.
(define_insn_reservation "ppc8540_store" 3
(and (eq_attr "type" "store,store_ux,store_u,store_c")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire")
;; Simple FP
(define_insn_reservation "ppc8540_simple_float" 1
(and (eq_attr "type" "fpsimple")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
;; FP
(define_insn_reservation "ppc8540_float" 4
(and (eq_attr "type" "fp")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\
ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire")
@@ -180,44 +180,44 @@
;; because of the result automata will be huge.
(define_insn_reservation "ppc8540_float_vector_divide" 29
(and (eq_attr "type" "vecfdiv")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0+ppc8540_mu_div,\
ppc8540_mu_div*28")
;; Brinc
(define_insn_reservation "ppc8540_brinc" 1
(and (eq_attr "type" "brinc")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
;; Simple vector
(define_insn_reservation "ppc8540_simple_vector" 1
(and (eq_attr "type" "vecsimple")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
;; Simple vector compare
(define_insn_reservation "ppc8540_simple_vector_compare" 1
(and (eq_attr "type" "veccmpsimple")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
;; Vector compare
(define_insn_reservation "ppc8540_vector_compare" 1
(and (eq_attr "type" "veccmp")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
;; evsplatfi evsplati
(define_insn_reservation "ppc8540_vector_perm" 1
(and (eq_attr "type" "vecperm")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
;; Vector float
(define_insn_reservation "ppc8540_float_vector" 4
(and (eq_attr "type" "vecfloat")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\
ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire")
@@ -226,25 +226,25 @@
;; of miu_stage3 here because we use the average latency time.
(define_insn_reservation "ppc8540_vector_divide" 14
(and (eq_attr "type" "vecdiv")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0+ppc8540_mu_div,\
ppc8540_mu_div*13")
;; Complex vector.
(define_insn_reservation "ppc8540_complex_vector" 4
(and (eq_attr "type" "veccomplex")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\
ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire")
;; Vector load
(define_insn_reservation "ppc8540_vector_load" 3
(and (eq_attr "type" "vecload")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire")
;; Vector store
(define_insn_reservation "ppc8540_vector_store" 3
(and (eq_attr "type" "vecstore")
- (eq_attr "cpu" "ppc8540"))
+ (eq_attr "cpu" "ppc8540,ppc8548"))
"ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire")
diff --git a/gcc/config/rs6000/e500-double.h b/gcc/config/rs6000/e500-double.h
deleted file mode 100644
index 2e73dd94c1b..00000000000
--- a/gcc/config/rs6000/e500-double.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Target definitions for E500 with double precision FP.
- Copyright (C) 2004, 2006, 2007, 2011 Free Software Foundation, Inc.
- Contributed by Aldy Hernandez (aldyh@redhat.com).
-
- This file is part of GCC.
-
- GCC 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 3, or (at your
- option) any later version.
-
- GCC 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 GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
-
-#undef SUB3TARGET_OVERRIDE_OPTIONS
-#define SUB3TARGET_OVERRIDE_OPTIONS \
- if (!global_options_set.x_rs6000_float_gprs) \
- rs6000_float_gprs = 2;
diff --git a/gcc/config/rs6000/e500.h b/gcc/config/rs6000/e500.h
index 807df0900a5..53a849a8646 100644
--- a/gcc/config/rs6000/e500.h
+++ b/gcc/config/rs6000/e500.h
@@ -19,7 +19,6 @@
#undef TARGET_SPE_ABI
#undef TARGET_SPE
-#undef TARGET_E500
#undef TARGET_FPRS
#undef TARGET_E500_SINGLE
#undef TARGET_E500_DOUBLE
@@ -27,21 +26,20 @@
#define TARGET_SPE_ABI rs6000_spe_abi
#define TARGET_SPE rs6000_spe
-#define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
#define TARGET_FPRS (rs6000_float_gprs == 0)
#define TARGET_E500_SINGLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 1)
#define TARGET_E500_DOUBLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 2)
#define CHECK_E500_OPTIONS \
do { \
- if (TARGET_E500 || TARGET_SPE || TARGET_SPE_ABI \
+ if (TARGET_SPE || TARGET_SPE_ABI \
|| TARGET_E500_SINGLE || TARGET_E500_DOUBLE) \
{ \
if (TARGET_ALTIVEC) \
- error ("AltiVec and E500 instructions cannot coexist"); \
+ error ("AltiVec and SPE instructions cannot coexist"); \
if (TARGET_VSX) \
- error ("VSX and E500 instructions cannot coexist"); \
+ error ("VSX and SPE instructions cannot coexist"); \
if (TARGET_64BIT) \
- error ("64-bit E500 not supported"); \
+ error ("64-bit SPE not supported"); \
if (TARGET_HARD_FLOAT && TARGET_FPRS) \
error ("E500 and FPRs not supported"); \
} \
diff --git a/gcc/config/rs6000/eabispe.h b/gcc/config/rs6000/eabispe.h
index 19f24726c2e..e7ffbe3decb 100644
--- a/gcc/config/rs6000/eabispe.h
+++ b/gcc/config/rs6000/eabispe.h
@@ -21,21 +21,8 @@
<http://www.gnu.org/licenses/>. */
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_EABI \
- | MASK_STRICT_ALIGN)
-
-#undef SUBSUBTARGET_OVERRIDE_OPTIONS
-#define SUBSUBTARGET_OVERRIDE_OPTIONS \
- if (!global_options_set.x_rs6000_cpu_index) \
- rs6000_cpu = PROCESSOR_PPC8540; \
- if (!global_options_set.x_rs6000_spe_abi) \
- rs6000_spe_abi = 1; \
- if (!global_options_set.x_rs6000_float_gprs) \
- rs6000_float_gprs = 1; \
- if (!global_options_set.x_rs6000_spe) \
- rs6000_spe = 1; \
- if (target_flags & MASK_64BIT) \
- error ("-m64 not supported in this configuration")
+#define TARGET_DEFAULT \
+ (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN | MASK_EABI)
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mppc -mspe -me500"
diff --git a/gcc/config/rs6000/linuxspe.h b/gcc/config/rs6000/linuxspe.h
index 8b95d25ff5b..74f7b060633 100644
--- a/gcc/config/rs6000/linuxspe.h
+++ b/gcc/config/rs6000/linuxspe.h
@@ -22,20 +22,8 @@
/* Override rs6000.h and sysv4.h definition. */
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN)
-
-#undef SUBSUBTARGET_OVERRIDE_OPTIONS
-#define SUBSUBTARGET_OVERRIDE_OPTIONS \
- if (!global_options_set.x_rs6000_cpu_index) \
- rs6000_cpu = PROCESSOR_PPC8540; \
- if (!global_options_set.x_rs6000_spe_abi) \
- rs6000_spe_abi = 1; \
- if (!global_options_set.x_rs6000_float_gprs) \
- rs6000_float_gprs = 1; \
- if (!global_options_set.x_rs6000_spe) \
- rs6000_spe = 1; \
- if (target_flags & MASK_64BIT) \
- error ("-m64 not supported in this configuration")
+#define TARGET_DEFAULT \
+ (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN)
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mppc -mspe -me500"
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 232773d5d14..70a4d2ca708 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -1,5 +1,5 @@
;; Predicate definitions for POWER and PowerPC.
-;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
+;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
;; Free Software Foundation, Inc.
;;
;; This file is part of GCC.
@@ -824,8 +824,8 @@
;; Return 1 if this operand is a valid input for a move insn.
(define_predicate "input_operand"
- (match_code "label_ref,symbol_ref,const,high,reg,subreg,mem,
- const_double,const_vector,const_int,plus")
+ (match_code "symbol_ref,const,reg,subreg,mem,
+ const_double,const_vector,const_int")
{
/* Memory is always valid. */
if (memory_operand (op, mode))
@@ -833,7 +833,6 @@
/* For floating-point, easy constants are valid. */
if (SCALAR_FLOAT_MODE_P (mode)
- && CONSTANT_P (op)
&& easy_fp_constant (op, mode))
return 1;
@@ -866,14 +865,6 @@
if (register_operand (op, mode))
return 1;
- /* A SYMBOL_REF referring to the TOC is valid. */
- if (legitimate_constant_pool_address_p (op, mode, false))
- return 1;
-
- /* A constant pool expression (relative to the TOC) is valid */
- if (toc_relative_expr_p (op))
- return 1;
-
/* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
to be valid. */
if (DEFAULT_ABI == ABI_V4
@@ -886,8 +877,8 @@
;; Return 1 if this operand is a valid input for a vsx_splat insn.
(define_predicate "splat_input_operand"
- (match_code "label_ref,symbol_ref,const,high,reg,subreg,mem,
- const_double,const_vector,const_int,plus")
+ (match_code "symbol_ref,const,reg,subreg,mem,
+ const_double,const_vector,const_int")
{
if (MEM_P (op))
{
@@ -1461,3 +1452,14 @@
&& GET_MODE (XEXP (XVECEXP (op, 0, 0), 0)) == BLKmode
&& XEXP (XVECEXP (op, 0, 0), 1) == const0_rtx);
})
+
+;; Match a small code model toc reference (or medium and large
+;; model toc references before reload).
+(define_predicate "small_toc_ref"
+ (match_code "unspec,plus")
+{
+ if (GET_CODE (op) == PLUS && CONST_INT_P (XEXP (op, 1)))
+ op = XEXP (op, 0);
+
+ return GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_TOCREL;
+})
diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def
index 5da8917c440..6974b157771 100644
--- a/gcc/config/rs6000/rs6000-cpus.def
+++ b/gcc/config/rs6000/rs6000-cpus.def
@@ -76,8 +76,7 @@ RS6000_CPU ("821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT)
RS6000_CPU ("823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT)
RS6000_CPU ("8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
| MASK_ISEL)
-/* 8548 has a dummy entry for now. */
-RS6000_CPU ("8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
+RS6000_CPU ("8548", PROCESSOR_PPC8548, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
| MASK_ISEL)
RS6000_CPU ("a2", PROCESSOR_PPCA2,
POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
diff --git a/gcc/config/rs6000/rs6000-opts.h b/gcc/config/rs6000/rs6000-opts.h
index ea7e7c74f60..41c16f2733f 100644
--- a/gcc/config/rs6000/rs6000-opts.h
+++ b/gcc/config/rs6000/rs6000-opts.h
@@ -49,6 +49,7 @@ enum processor_type
PROCESSOR_PPC7400,
PROCESSOR_PPC7450,
PROCESSOR_PPC8540,
+ PROCESSOR_PPC8548,
PROCESSOR_PPCE300C2,
PROCESSOR_PPCE300C3,
PROCESSOR_PPCE500MC,
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 23327f853fd..119482fbafc 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler, for IBM RS/6000.
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
- 2010, 2011
+ 2010, 2011, 2012
Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
@@ -38,7 +38,7 @@ extern bool macho_lo_sum_memory_operand (rtx, enum machine_mode);
extern int num_insns_constant (rtx, enum machine_mode);
extern int num_insns_constant_wide (HOST_WIDE_INT);
extern int small_data_operand (rtx, enum machine_mode);
-extern bool toc_relative_expr_p (rtx);
+extern bool toc_relative_expr_p (const_rtx, bool);
extern bool invalid_e500_subreg (rtx, enum machine_mode);
extern void validate_condition_mode (enum rtx_code, enum machine_mode);
extern bool legitimate_constant_pool_address_p (const_rtx, enum machine_mode,
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index c3331dce213..dbd1b4a37ca 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -2592,7 +2592,10 @@ rs6000_option_override_internal (bool global_init_p)
{
bool ret = true;
bool have_cpu = false;
- const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
+
+ /* The default cpu requested at configure time, if any. */
+ const char *implicit_cpu = OPTION_TARGET_CPU_DEFAULT;
+
int set_masks;
int cpu_index;
int tune_index;
@@ -2611,11 +2614,6 @@ rs6000_option_override_internal (bool global_init_p)
warning (0, "-malign-power is not supported for 64-bit Darwin;"
" it is incompatible with the installed C and C++ libraries");
- if (global_options_set.x_rs6000_spe_abi
- && rs6000_spe_abi
- && !TARGET_SPE_ABI)
- error ("not configured for SPE ABI");
-
/* Numerous experiment shows that IRA based loop pressure
calculation works better for RTL loop invariant motion on targets
with enough (>= 32) registers. It is an expensive optimization.
@@ -2651,7 +2649,8 @@ rs6000_option_override_internal (bool global_init_p)
/* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
the cpu in a target attribute or pragma, but did not specify a tuning
option, use the cpu for the tuning option rather than the option specified
- with -mtune on the command line. */
+ with -mtune on the command line. Process a '--with-cpu' configuration
+ request as an implicit --cpu. */
if (rs6000_cpu_index >= 0)
{
cpu_index = rs6000_cpu_index;
@@ -2664,10 +2663,12 @@ rs6000_option_override_internal (bool global_init_p)
}
else
{
- if (!default_cpu)
- default_cpu = (TARGET_POWERPC64 ? "powerpc64" : "powerpc");
+ const char *default_cpu =
+ (implicit_cpu ? implicit_cpu
+ : (TARGET_POWERPC64 ? "powerpc64" : "powerpc"));
rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
+ have_cpu = implicit_cpu != 0;
}
gcc_assert (cpu_index >= 0);
@@ -2698,6 +2699,42 @@ rs6000_option_override_internal (bool global_init_p)
gcc_assert (tune_index >= 0);
rs6000_cpu = processor_target_table[tune_index].processor;
+ /* Pick defaults for SPE related control flags. Do this early to make sure
+ that the TARGET_ macros are representative ASAP. */
+ {
+ int spe_capable_cpu =
+ (rs6000_cpu == PROCESSOR_PPC8540
+ || rs6000_cpu == PROCESSOR_PPC8548);
+
+ if (!global_options_set.x_rs6000_spe_abi)
+ rs6000_spe_abi = spe_capable_cpu;
+
+ if (!global_options_set.x_rs6000_spe)
+ rs6000_spe = spe_capable_cpu;
+
+ if (!global_options_set.x_rs6000_float_gprs)
+ rs6000_float_gprs =
+ (rs6000_cpu == PROCESSOR_PPC8540 ? 1
+ : rs6000_cpu == PROCESSOR_PPC8548 ? 2
+ : 0);
+ }
+
+ if (global_options_set.x_rs6000_spe_abi
+ && rs6000_spe_abi
+ && !TARGET_SPE_ABI)
+ error ("not configured for SPE ABI");
+
+ if (global_options_set.x_rs6000_spe
+ && rs6000_spe
+ && !TARGET_SPE)
+ error ("not configured for SPE instruction set");
+
+ if (main_target_opt != NULL
+ && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
+ || (main_target_opt->x_rs6000_spe != rs6000_spe)
+ || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
+ error ("target attribute or pragma changes SPE ABI");
+
if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
|| rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
{
@@ -2933,35 +2970,44 @@ rs6000_option_override_internal (bool global_init_p)
SUB3TARGET_OVERRIDE_OPTIONS;
#endif
- if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
- || rs6000_cpu == PROCESSOR_PPCE500MC64)
+ /* For the E500 family of cores, reset the single/double FP flags to let us
+ check that they remain constant across attributes or pragmas. Also,
+ clear a possible request for string instructions, not supported and which
+ we might have silently queried above for -Os.
+
+ For other families, clear ISEL in case it was set implicitly.
+ */
+
+ switch (rs6000_cpu)
{
- /* The e500 and e500mc do not have string instructions, and we set
- MASK_STRING above when optimizing for size. */
- if ((target_flags & MASK_STRING) != 0)
- target_flags = target_flags & ~MASK_STRING;
+ case PROCESSOR_PPC8540:
+ case PROCESSOR_PPC8548:
+ case PROCESSOR_PPCE500MC:
+ case PROCESSOR_PPCE500MC64:
+
+ rs6000_single_float = TARGET_E500_SINGLE || TARGET_E500_DOUBLE;
+ rs6000_double_float = TARGET_E500_DOUBLE;
+
+ target_flags &= ~MASK_STRING;
+
+ break;
+
+ default:
+
+ if (have_cpu && !(target_flags_explicit & MASK_ISEL))
+ target_flags &= ~MASK_ISEL;
+
+ break;
}
- else if (global_options_set.x_rs6000_cpu_index)
+
+ if (main_target_opt)
{
- /* For the powerpc-eabispe configuration, we set all these by
- default, so let's unset them if we manually set another
- CPU that is not the E500. */
- if (main_target_opt != NULL
- && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
- || (main_target_opt->x_rs6000_spe != rs6000_spe)
- || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
- error ("target attribute or pragma changes SPE ABI");
- else
- {
- if (!global_options_set.x_rs6000_spe_abi)
- rs6000_spe_abi = 0;
- if (!global_options_set.x_rs6000_spe)
- rs6000_spe = 0;
- if (!global_options_set.x_rs6000_float_gprs)
- rs6000_float_gprs = 0;
- }
- if (!(target_flags_explicit & MASK_ISEL))
- target_flags &= ~MASK_ISEL;
+ if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
+ error ("target attribute or pragma changes single precision floating "
+ "point");
+ if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
+ error ("target attribute or pragma changes double precision floating "
+ "point");
}
/* Detect invalid option combinations with E500. */
@@ -3188,6 +3234,7 @@ rs6000_option_override_internal (bool global_init_p)
break;
case PROCESSOR_PPC8540:
+ case PROCESSOR_PPC8548:
rs6000_cost = &ppc8540_cost;
break;
@@ -3260,26 +3307,6 @@ rs6000_option_override_internal (bool global_init_p)
&& rs6000_single_float == 0 && rs6000_double_float == 0)
rs6000_single_float = rs6000_double_float = 1;
- /* Reset single and double FP flags if target is E500. */
- if (TARGET_E500)
- {
- rs6000_single_float = rs6000_double_float = 0;
- if (TARGET_E500_SINGLE)
- rs6000_single_float = 1;
- if (TARGET_E500_DOUBLE)
- rs6000_single_float = rs6000_double_float = 1;
- }
-
- if (main_target_opt)
- {
- if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
- error ("target attribute or pragma changes single precision floating "
- "point");
- if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
- error ("target attribute or pragma changes double precision floating "
- "point");
- }
-
/* If not explicitly specified via option, decide whether to generate indexed
load/store instructions. */
if (TARGET_AVOID_XFORM == -1)
@@ -5280,15 +5307,37 @@ constant_pool_expr_p (rtx op)
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
}
-static rtx tocrel_base, tocrel_offset;
+static const_rtx tocrel_base, tocrel_offset;
+
+/* Return true if OP is a toc pointer relative address (the output
+ of create_TOC_reference). If STRICT, do not match high part or
+ non-split -mcmodel=large/medium toc pointer relative addresses. */
bool
-toc_relative_expr_p (rtx op)
+toc_relative_expr_p (const_rtx op, bool strict)
{
- if (GET_CODE (op) != CONST)
+ if (!TARGET_TOC)
return false;
- split_const (op, &tocrel_base, &tocrel_offset);
+ if (TARGET_CMODEL != CMODEL_SMALL)
+ {
+ /* Only match the low part. */
+ if (GET_CODE (op) == LO_SUM
+ && REG_P (XEXP (op, 0))
+ && INT_REG_OK_FOR_BASE_P (XEXP (op, 0), strict))
+ op = XEXP (op, 1);
+ else if (strict)
+ return false;
+ }
+
+ tocrel_base = op;
+ tocrel_offset = const0_rtx;
+ if (GET_CODE (op) == PLUS && CONST_INT_P (XEXP (op, 1)))
+ {
+ tocrel_base = XEXP (op, 0);
+ tocrel_offset = XEXP (op, 1);
+ }
+
return (GET_CODE (tocrel_base) == UNSPEC
&& XINT (tocrel_base, 1) == UNSPEC_TOCREL);
}
@@ -5300,14 +5349,7 @@ bool
legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
bool strict)
{
- return (TARGET_TOC
- && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
- && GET_CODE (XEXP (x, 0)) == REG
- && (REGNO (XEXP (x, 0)) == TOC_REGISTER
- || ((TARGET_MINIMAL_TOC
- || TARGET_CMODEL != CMODEL_SMALL)
- && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
- && toc_relative_expr_p (XEXP (x, 1))
+ return (toc_relative_expr_p (x, strict)
&& (TARGET_CMODEL != CMODEL_MEDIUM
|| constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
|| mode == QImode
@@ -5687,10 +5729,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
&& GET_CODE (x) == SYMBOL_REF
&& constant_pool_expr_p (x)
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
- {
- rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
- return create_TOC_reference (x, reg);
- }
+ return create_TOC_reference (x, NULL_RTX);
else
return x;
}
@@ -5773,49 +5812,55 @@ rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
static rtx
rs6000_delegitimize_address (rtx orig_x)
{
- rtx x, y;
+ rtx x, y, offset;
orig_x = delegitimize_mem_from_attrs (orig_x);
x = orig_x;
if (MEM_P (x))
x = XEXP (x, 0);
- if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
- && GET_CODE (XEXP (x, 1)) == CONST)
+ y = x;
+ if (TARGET_CMODEL != CMODEL_SMALL
+ && GET_CODE (y) == LO_SUM)
+ y = XEXP (y, 1);
+
+ offset = NULL_RTX;
+ if (GET_CODE (y) == PLUS
+ && GET_MODE (y) == Pmode
+ && CONST_INT_P (XEXP (y, 1)))
{
- rtx offset = NULL_RTX;
+ offset = XEXP (y, 1);
+ y = XEXP (y, 0);
+ }
- y = XEXP (XEXP (x, 1), 0);
- if (GET_CODE (y) == PLUS
- && GET_MODE (y) == Pmode
- && CONST_INT_P (XEXP (y, 1)))
+ if (GET_CODE (y) == UNSPEC
+ && XINT (y, 1) == UNSPEC_TOCREL)
+ {
+#ifdef ENABLE_CHECKING
+ if (REG_P (XVECEXP (y, 0, 1))
+ && REGNO (XVECEXP (y, 0, 1)) == TOC_REGISTER)
{
- offset = XEXP (y, 1);
- y = XEXP (y, 0);
+ /* All good. */
}
- if (GET_CODE (y) == UNSPEC
- && XINT (y, 1) == UNSPEC_TOCREL
- && ((GET_CODE (XEXP (x, 0)) == REG
- && (REGNO (XEXP (x, 0)) == TOC_REGISTER
- || TARGET_MINIMAL_TOC
- || TARGET_CMODEL != CMODEL_SMALL))
- || (TARGET_CMODEL != CMODEL_SMALL
- && GET_CODE (XEXP (x, 0)) == CONST
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
- && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == REG
- && REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0)) == TOC_REGISTER
- && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == HIGH
- && rtx_equal_p (XEXP (x, 1),
- XEXP (XEXP (XEXP (XEXP (x, 0), 0), 1), 0)))))
- {
- y = XVECEXP (y, 0, 0);
- if (offset != NULL_RTX)
- y = gen_rtx_PLUS (Pmode, y, offset);
- if (!MEM_P (orig_x))
- return y;
- else
- return replace_equiv_address_nv (orig_x, y);
+ else if (GET_CODE (XVECEXP (y, 0, 1)) == DEBUG_EXPR)
+ {
+ /* Weirdness alert. df_note_compute can replace r2 with a
+ debug_expr when this unspec is in a debug_insn.
+ Seen in gcc.dg/pr51957-1.c */
+ }
+ else
+ {
+ debug_rtx (orig_x);
+ abort ();
}
+#endif
+ y = XVECEXP (y, 0, 0);
+ if (offset != NULL_RTX)
+ y = gen_rtx_PLUS (Pmode, y, offset);
+ if (!MEM_P (orig_x))
+ return y;
+ else
+ return replace_equiv_address_nv (orig_x, y);
}
if (TARGET_MACHO
@@ -6077,9 +6122,8 @@ rs6000_tls_referenced_p (rtx x)
static bool
rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
- if (GET_CODE (x) == CONST
- && GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH)
+ if (GET_CODE (x) == HIGH
+ && GET_CODE (XEXP (x, 0)) == UNSPEC)
return true;
return rs6000_tls_referenced_p (x);
@@ -6094,6 +6138,21 @@ rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
return RS6000_SYMBOL_REF_TLS_P (*x);
}
+/* Return true iff the given SYMBOL_REF refers to a constant pool entry
+ that we have put in the TOC, or for cmodel=medium, if the SYMBOL_REF
+ can be addressed relative to the toc pointer. */
+
+static bool
+use_toc_relative_ref (rtx sym)
+{
+ return ((constant_pool_expr_p (sym)
+ && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym),
+ get_pool_mode (sym)))
+ || (TARGET_CMODEL == CMODEL_MEDIUM
+ && !CONSTANT_POOL_ADDRESS_P (sym)
+ && SYMBOL_REF_LOCAL_P (sym)));
+}
+
/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
replace the input X, or the original X if no replacement is called for.
The output parameter *WIN is 1 if the calling macro should goto WIN,
@@ -6131,7 +6190,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
{
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
- opnum, (enum reload_type)type);
+ opnum, (enum reload_type) type);
*win = 1;
return x;
}
@@ -6142,7 +6201,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
{
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
- opnum, (enum reload_type)type);
+ opnum, (enum reload_type) type);
*win = 1;
return x;
}
@@ -6160,24 +6219,18 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
floating point constant. */
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
- opnum, (enum reload_type)type);
+ opnum, (enum reload_type) type);
*win = 1;
return x;
}
#endif
if (TARGET_CMODEL != CMODEL_SMALL
- && GET_CODE (x) == LO_SUM
- && GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
- && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST
- && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == HIGH
- && GET_CODE (XEXP (x, 1)) == CONST
- && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
- && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
- && rtx_equal_p (XEXP (XEXP (XEXP (XEXP (x, 0), 1), 0), 0), XEXP (x, 1)))
+ && reg_offset_p
+ && small_toc_ref (x, VOIDmode))
{
+ rtx hi = gen_rtx_HIGH (Pmode, copy_rtx (x));
+ x = gen_rtx_LO_SUM (Pmode, hi, x);
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
opnum, (enum reload_type) type);
@@ -6240,7 +6293,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
- opnum, (enum reload_type)type);
+ opnum, (enum reload_type) type);
*win = 1;
return x;
}
@@ -6281,7 +6334,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
- opnum, (enum reload_type)type);
+ opnum, (enum reload_type) type);
*win = 1;
return x;
}
@@ -6308,8 +6361,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
if (TARGET_TOC
&& reg_offset_p
&& GET_CODE (x) == SYMBOL_REF
- && constant_pool_expr_p (x)
- && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
+ && use_toc_relative_ref (x))
{
x = create_TOC_reference (x, NULL_RTX);
if (TARGET_CMODEL != CMODEL_SMALL)
@@ -6544,9 +6596,13 @@ rs6000_debug_mode_dependent_address (const_rtx addr)
rtx
rs6000_find_base_term (rtx op)
{
- rtx base, offset;
+ rtx base;
- split_const (op, &base, &offset);
+ base = op;
+ if (GET_CODE (base) == CONST)
+ base = XEXP (base, 0);
+ if (GET_CODE (base) == PLUS)
+ base = XEXP (base, 0);
if (GET_CODE (base) == UNSPEC)
switch (XINT (base, 1))
{
@@ -7198,33 +7254,13 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
/* If this is a SYMBOL_REF that refers to a constant pool entry,
and we have put it in the TOC, we just need to make a TOC-relative
reference to it. */
- if ((TARGET_TOC
- && GET_CODE (operands[1]) == SYMBOL_REF
- && constant_pool_expr_p (operands[1])
- && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
- get_pool_mode (operands[1])))
- || (TARGET_CMODEL == CMODEL_MEDIUM
- && GET_CODE (operands[1]) == SYMBOL_REF
- && !CONSTANT_POOL_ADDRESS_P (operands[1])
- && SYMBOL_REF_LOCAL_P (operands[1])))
- {
- rtx reg = NULL_RTX;
- if (TARGET_CMODEL != CMODEL_SMALL)
- {
- if (can_create_pseudo_p ())
- reg = gen_reg_rtx (Pmode);
- else
- reg = operands[0];
- }
- operands[1] = create_TOC_reference (operands[1], reg);
- }
+ if (TARGET_TOC
+ && GET_CODE (operands[1]) == SYMBOL_REF
+ && use_toc_relative_ref (operands[1]))
+ operands[1] = create_TOC_reference (operands[1], operands[0]);
else if (mode == Pmode
&& CONSTANT_P (operands[1])
&& GET_CODE (operands[1]) != HIGH
- && !(TARGET_CMODEL != CMODEL_SMALL
- && GET_CODE (operands[1]) == CONST
- && GET_CODE (XEXP (operands[1], 0)) == PLUS
- && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == HIGH)
&& ((GET_CODE (operands[1]) != CONST_INT
&& ! easy_fp_constant (operands[1], mode))
|| (GET_CODE (operands[1]) == CONST_INT
@@ -7232,9 +7268,7 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
> (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
|| (GET_CODE (operands[0]) == REG
&& FP_REGNO_P (REGNO (operands[0]))))
- && ! legitimate_constant_pool_address_p (operands[1], mode,
- false)
- && ! toc_relative_expr_p (operands[1])
+ && !toc_relative_expr_p (operands[1], false)
&& (TARGET_CMODEL == CMODEL_SMALL
|| can_create_pseudo_p ()
|| (REG_P (operands[0])
@@ -7284,16 +7318,8 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
get_pool_constant (XEXP (operands[1], 0)),
get_pool_mode (XEXP (operands[1], 0))))
{
- rtx tocref;
- rtx reg = NULL_RTX;
- if (TARGET_CMODEL != CMODEL_SMALL)
- {
- if (can_create_pseudo_p ())
- reg = gen_reg_rtx (Pmode);
- else
- reg = operands[0];
- }
- tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
+ rtx tocref = create_TOC_reference (XEXP (operands[1], 0),
+ operands[0]);
operands[1] = gen_const_mem (mode, tocref);
set_mem_alias_set (operands[1], get_TOC_alias_set ());
}
@@ -14652,7 +14678,6 @@ void
print_operand (FILE *file, rtx x, int code)
{
int i;
- HOST_WIDE_INT val;
unsigned HOST_WIDE_INT uval;
switch (code)
@@ -14704,7 +14729,7 @@ print_operand (FILE *file, rtx x, int code)
case 'D':
/* Like 'J' but get to the GT bit only. */
- gcc_assert (GET_CODE (x) == REG);
+ gcc_assert (REG_P (x));
/* Bit 1 is GT bit. */
i = 4 * (REGNO (x) - CR0_REGNO) + 1;
@@ -14824,9 +14849,9 @@ print_operand (FILE *file, rtx x, int code)
case 'L':
/* Write second word of DImode or DFmode reference. Works on register
or non-indexed memory only. */
- if (GET_CODE (x) == REG)
+ if (REG_P (x))
fputs (reg_names[REGNO (x) + 1], file);
- else if (GET_CODE (x) == MEM)
+ else if (MEM_P (x))
{
/* Handle possible auto-increment. Since it is pre-increment and
we have already done it, we can just use an offset of word. */
@@ -14995,7 +15020,7 @@ print_operand (FILE *file, rtx x, int code)
case 't':
/* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
- gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
+ gcc_assert (REG_P (x) && GET_MODE (x) == CCmode);
/* Bit 3 is OV bit. */
i = 4 * (REGNO (x) - CR0_REGNO) + 3;
@@ -15035,7 +15060,7 @@ print_operand (FILE *file, rtx x, int code)
case 'U':
/* Print `u' if this has an auto-increment or auto-decrement. */
- if (GET_CODE (x) == MEM
+ if (MEM_P (x)
&& (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC
|| GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
@@ -15093,34 +15118,17 @@ print_operand (FILE *file, rtx x, int code)
case 'W':
/* MB value for a PowerPC64 rldic operand. */
- val = (GET_CODE (x) == CONST_INT
- ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
-
- if (val < 0)
- i = -1;
- else
- for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
- if ((val <<= 1) < 0)
- break;
+ i = clz_hwi (GET_CODE (x) == CONST_INT
+ ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
#if HOST_BITS_PER_WIDE_INT == 32
- if (GET_CODE (x) == CONST_INT && i >= 0)
+ if (GET_CODE (x) == CONST_INT && i > 0)
i += 32; /* zero-extend high-part was all 0's */
else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
- {
- val = CONST_DOUBLE_LOW (x);
-
- gcc_assert (val);
- if (val < 0)
- --i;
- else
- for ( ; i < 64; i++)
- if ((val <<= 1) < 0)
- break;
- }
+ i = clz_hwi (CONST_DOUBLE_LOW (x)) + 32;
#endif
- fprintf (file, "%d", i + 1);
+ fprintf (file, "%d", i);
return;
case 'x':
@@ -15144,7 +15152,7 @@ print_operand (FILE *file, rtx x, int code)
return;
case 'X':
- if (GET_CODE (x) == MEM
+ if (MEM_P (x)
&& (legitimate_indexed_address_p (XEXP (x, 0), 0)
|| (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
&& legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
@@ -15153,9 +15161,9 @@ print_operand (FILE *file, rtx x, int code)
case 'Y':
/* Like 'L', for third word of TImode */
- if (GET_CODE (x) == REG)
+ if (REG_P (x))
fputs (reg_names[REGNO (x) + 2], file);
- else if (GET_CODE (x) == MEM)
+ else if (MEM_P (x))
{
if (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
@@ -15203,9 +15211,9 @@ print_operand (FILE *file, rtx x, int code)
case 'Z':
/* Like 'L', for last word of TImode. */
- if (GET_CODE (x) == REG)
+ if (REG_P (x))
fputs (reg_names[REGNO (x) + 3], file);
- else if (GET_CODE (x) == MEM)
+ else if (MEM_P (x))
{
if (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
@@ -15225,7 +15233,7 @@ print_operand (FILE *file, rtx x, int code)
{
rtx tmp;
- gcc_assert (GET_CODE (x) == MEM);
+ gcc_assert (MEM_P (x));
tmp = XEXP (x, 0);
@@ -15236,7 +15244,7 @@ print_operand (FILE *file, rtx x, int code)
|| GET_MODE (x) == TImode))
{
/* Handle [reg]. */
- if (GET_CODE (tmp) == REG)
+ if (REG_P (tmp))
{
fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
break;
@@ -15247,7 +15255,7 @@ print_operand (FILE *file, rtx x, int code)
{
int x;
- gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
+ gcc_assert (REG_P (XEXP (tmp, 0)));
x = INTVAL (XEXP (tmp, 1));
fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
@@ -15264,7 +15272,7 @@ print_operand (FILE *file, rtx x, int code)
else if (VECTOR_MEM_VSX_P (GET_MODE (x))
&& GET_CODE (tmp) == PRE_MODIFY)
tmp = XEXP (tmp, 1);
- if (GET_CODE (tmp) == REG)
+ if (REG_P (tmp))
fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
else
{
@@ -15287,9 +15295,9 @@ print_operand (FILE *file, rtx x, int code)
}
case 0:
- if (GET_CODE (x) == REG)
+ if (REG_P (x))
fprintf (file, "%s", reg_names[REGNO (x)]);
- else if (GET_CODE (x) == MEM)
+ else if (MEM_P (x))
{
/* We need to handle PRE_INC and PRE_DEC here, since we need to
know the width from the mode. */
@@ -15306,14 +15314,14 @@ print_operand (FILE *file, rtx x, int code)
}
else
{
- if (toc_relative_expr_p (x))
+ if (toc_relative_expr_p (x, false))
/* This hack along with a corresponding hack in
rs6000_output_addr_const_extra arranges to output addends
where the assembler expects to find them. eg.
- (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
+ (plus (unspec [(symbol_ref ("x")) (reg 2)] tocrel) 4)
without this hack would be output as "x@toc+4". We
want "x+4@toc". */
- output_addr_const (file, tocrel_base);
+ output_addr_const (file, CONST_CAST_RTX (tocrel_base));
else
output_addr_const (file, x);
}
@@ -15333,7 +15341,7 @@ print_operand (FILE *file, rtx x, int code)
void
print_operand_address (FILE *file, rtx x)
{
- if (GET_CODE (x) == REG)
+ if (REG_P (x))
fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
|| GET_CODE (x) == LABEL_REF)
@@ -15345,9 +15353,9 @@ print_operand_address (FILE *file, rtx x)
else
gcc_assert (!TARGET_TOC);
}
- else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
+ else if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0))
+ && REG_P (XEXP (x, 1)))
{
- gcc_assert (REG_P (XEXP (x, 0)));
if (REGNO (XEXP (x, 0)) == 0)
fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
reg_names[ REGNO (XEXP (x, 0)) ]);
@@ -15355,11 +15363,12 @@ print_operand_address (FILE *file, rtx x)
fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
reg_names[ REGNO (XEXP (x, 1)) ]);
}
- else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ else if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0))
+ && GET_CODE (XEXP (x, 1)) == CONST_INT)
fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
#if TARGET_MACHO
- else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
+ else if (GET_CODE (x) == LO_SUM && REG_P (XEXP (x, 0))
&& CONSTANT_P (XEXP (x, 1)))
{
fprintf (file, "lo16(");
@@ -15367,29 +15376,29 @@ print_operand_address (FILE *file, rtx x)
fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
}
#endif
- else if (legitimate_constant_pool_address_p (x, QImode, true))
+#if TARGET_ELF
+ else if (GET_CODE (x) == LO_SUM && REG_P (XEXP (x, 0))
+ && CONSTANT_P (XEXP (x, 1)))
+ {
+ output_addr_const (file, XEXP (x, 1));
+ fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
+ }
+#endif
+ else if (toc_relative_expr_p (x, false))
{
/* This hack along with a corresponding hack in
rs6000_output_addr_const_extra arranges to output addends
where the assembler expects to find them. eg.
(lo_sum (reg 9)
- . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
+ . (plus (unspec [(symbol_ref ("x")) (reg 2)] tocrel) 8))
without this hack would be output as "x@toc+8@l(9)". We
want "x+8@toc@l(9)". */
- output_addr_const (file, tocrel_base);
+ output_addr_const (file, CONST_CAST_RTX (tocrel_base));
if (GET_CODE (x) == LO_SUM)
- fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
+ fprintf (file, "@l(%s)", reg_names[REGNO (XEXP (x, 0))]);
else
- fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
+ fprintf (file, "(%s)", reg_names[REGNO (XVECEXP (tocrel_base, 0, 1))]);
}
-#if TARGET_ELF
- else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
- && CONSTANT_P (XEXP (x, 1)))
- {
- output_addr_const (file, XEXP (x, 1));
- fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
- }
-#endif
else
gcc_unreachable ();
}
@@ -15403,13 +15412,15 @@ rs6000_output_addr_const_extra (FILE *file, rtx x)
switch (XINT (x, 1))
{
case UNSPEC_TOCREL:
- gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
+ gcc_checking_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF
+ && REG_P (XVECEXP (x, 0, 1))
+ && REGNO (XVECEXP (x, 0, 1)) == TOC_REGISTER);
output_addr_const (file, XVECEXP (x, 0, 0));
if (x == tocrel_base && tocrel_offset != const0_rtx)
{
if (INTVAL (tocrel_offset) >= 0)
fprintf (file, "+");
- output_addr_const (file, tocrel_offset);
+ output_addr_const (file, CONST_CAST_RTX (tocrel_offset));
}
if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
{
@@ -18492,7 +18503,7 @@ uses_TOC (void)
rtx
create_TOC_reference (rtx symbol, rtx largetoc_reg)
{
- rtx tocrel, tocreg;
+ rtx tocrel, tocreg, hi;
if (TARGET_DEBUG_ADDR)
{
@@ -18510,24 +18521,18 @@ create_TOC_reference (rtx symbol, rtx largetoc_reg)
if (!can_create_pseudo_p ())
df_set_regs_ever_live (TOC_REGISTER, true);
- tocrel = gen_rtx_CONST (Pmode,
- gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
- UNSPEC_TOCREL));
tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
- if (TARGET_CMODEL != CMODEL_SMALL)
+ tocrel = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, symbol, tocreg), UNSPEC_TOCREL);
+ if (TARGET_CMODEL == CMODEL_SMALL || can_create_pseudo_p ())
+ return tocrel;
+
+ hi = gen_rtx_HIGH (Pmode, copy_rtx (tocrel));
+ if (largetoc_reg != NULL)
{
- rtx hi = gen_rtx_CONST (Pmode,
- gen_rtx_PLUS (Pmode, tocreg,
- gen_rtx_HIGH (Pmode, tocrel)));
- if (largetoc_reg != NULL)
- {
- emit_move_insn (largetoc_reg, hi);
- hi = largetoc_reg;
- }
- return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
+ emit_move_insn (largetoc_reg, hi);
+ hi = largetoc_reg;
}
- else
- return gen_rtx_PLUS (Pmode, tocreg, tocrel);
+ return gen_rtx_LO_SUM (Pmode, hi, tocrel);
}
/* Issue assembly directives that create a reference to the given DWARF
@@ -23126,6 +23131,7 @@ rs6000_issue_rate (void)
case CPU_PPC750:
case CPU_PPC7400:
case CPU_PPC8540:
+ case CPU_PPC8548:
case CPU_CELL:
case CPU_PPCE300C2:
case CPU_PPCE300C3:
@@ -23156,11 +23162,18 @@ rs6000_issue_rate (void)
static int
rs6000_use_sched_lookahead (void)
{
- if (rs6000_cpu_attr == CPU_PPC8540)
- return 4;
- if (rs6000_cpu_attr == CPU_CELL)
- return (reload_completed ? 8 : 0);
- return 0;
+ switch (rs6000_cpu_attr)
+ {
+ case CPU_PPC8540:
+ case CPU_PPC8548:
+ return 4;
+
+ case CPU_CELL:
+ return (reload_completed ? 8 : 0);
+
+ default:
+ return 0;
+ }
}
/* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index c69a209fc8a..38db1f484f9 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -457,7 +457,6 @@ extern int rs6000_vector_align[];
#define TARGET_SPE_ABI 0
#define TARGET_SPE 0
-#define TARGET_E500 0
#define TARGET_ISEL64 (TARGET_ISEL && TARGET_POWERPC64)
#define TARGET_FPRS 1
#define TARGET_E500_SINGLE 0
@@ -500,11 +499,11 @@ extern int rs6000_vector_align[];
|| TARGET_ALTIVEC \
|| TARGET_VSX)))
+/* E500 cores only support plain "sync", not lwsync. */
+#define TARGET_NO_LWSYNC (rs6000_cpu == PROCESSOR_PPC8540 \
+ || rs6000_cpu == PROCESSOR_PPC8548)
-/* E500 processors only support plain "sync", not lwsync. */
-#define TARGET_NO_LWSYNC TARGET_E500
-
/* Which machine supports the various reciprocal estimate instructions. */
#define TARGET_FRES (TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT \
&& TARGET_FPRS && TARGET_SINGLE_FLOAT)
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 78e56030b04..e852c3e5306 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -1,6 +1,7 @@
;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+;; 2011, 2012
;; Free Software Foundation, Inc.
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
@@ -165,7 +166,7 @@
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in rs6000.h.
-(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,power4,power5,power6,power7,cell,ppca2,titan"
+(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,power4,power5,power6,power7,cell,ppca2,titan"
(const (symbol_ref "rs6000_cpu_attr")))
@@ -9305,8 +9306,8 @@
(set_attr "length" "4")])
(define_insn "*movsi_internal1"
- [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h")
- (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,r,0"))]
+ [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*q,*c*l,*h,*h")
+ (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,r,0"))]
"!TARGET_SINGLE_FPU &&
(gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
"@
@@ -9317,18 +9318,17 @@
{lil|li} %0,%1
{liu|lis} %0,%v1
#
- {cal|la} %0,%a1
mf%1 %0
mt%0 %1
mt%0 %1
mt%0 %1
{cror 0,0,0|nop}"
- [(set_attr "type" "*,*,load,store,*,*,*,*,mfjmpr,*,mtjmpr,*,*")
- (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
+ [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,*,mtjmpr,*,*")
+ (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4")])
(define_insn "*movsi_internal1_single"
- [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h,m,*f")
- (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,r,0,f,m"))]
+ [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*q,*c*l,*h,*h,m,*f")
+ (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,r,0,f,m"))]
"TARGET_SINGLE_FPU &&
(gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
"@
@@ -9339,7 +9339,6 @@
{lil|li} %0,%1
{liu|lis} %0,%v1
#
- {cal|la} %0,%a1
mf%1 %0
mt%0 %1
mt%0 %1
@@ -9347,8 +9346,8 @@
{cror 0,0,0|nop}
stfs%U0%X0 %1, %0
lfs%U1%X1 %0, %1"
- [(set_attr "type" "*,*,load,store,*,*,*,*,mfjmpr,*,mtjmpr,*,*,*,*")
- (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4,4,4")])
+ [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,*,mtjmpr,*,*,*,*")
+ (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4,4")])
;; Split a load of a large constant into the appropriate two-insn
;; sequence.
@@ -9543,8 +9542,8 @@
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,8")])
(define_insn "*movsf_softfloat"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=r,cl,q,r,r,m,r,r,r,r,r,*h")
- (match_operand:SF 1 "input_operand" "r,r,r,h,m,r,I,L,R,G,Fn,0"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,cl,q,r,r,m,r,r,r,r,*h")
+ (match_operand:SF 1 "input_operand" "r,r,r,h,m,r,I,L,G,Fn,0"))]
"(gpc_reg_operand (operands[0], SFmode)
|| gpc_reg_operand (operands[1], SFmode))
&& (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
@@ -9557,12 +9556,11 @@
{st%U0%X0|stw%U0%X0} %1,%0
{lil|li} %0,%1
{liu|lis} %0,%v1
- {cal|la} %0,%a1
#
#
{cror 0,0,0|nop}"
- [(set_attr "type" "*,mtjmpr,*,mfjmpr,load,store,*,*,*,*,*,*")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8,4")])
+ [(set_attr "type" "*,mtjmpr,*,mfjmpr,load,store,*,*,*,*,*")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,8,4")])
(define_expand "movdf"
@@ -10190,8 +10188,8 @@
{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
(define_insn "*movdi_mfpgpr"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*d,*d,m,r,*h,*h,r,*d")
- (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,d,m,d,*h,r,0,*d,r"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,*d,*d,m,r,*h,*h,r,*d")
+ (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,d,m,d,*h,r,0,*d,r"))]
"TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
&& (gpc_reg_operand (operands[0], DImode)
|| gpc_reg_operand (operands[1], DImode))"
@@ -10202,7 +10200,6 @@
li %0,%1
lis %0,%v1
#
- la %0,%a1
fmr %0,%1
lfd%U1%X1 %0,%1
stfd%U0%X0 %1,%0
@@ -10211,12 +10208,12 @@
{cror 0,0,0|nop}
mftgpr %0,%1
mffgpr %0,%1"
- [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*,mftgpr,mffgpr")
- (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4")])
+ [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*,mftgpr,mffgpr")
+ (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4")])
(define_insn "*movdi_internal64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*d,*d,m,r,*h,*h,?wa")
- (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,d,m,d,*h,r,0,O"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,*d,*d,m,r,*h,*h,?wa")
+ (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,d,m,d,*h,r,0,O"))]
"TARGET_POWERPC64 && (!TARGET_MFPGPR || !TARGET_HARD_FLOAT || !TARGET_FPRS)
&& (gpc_reg_operand (operands[0], DImode)
|| gpc_reg_operand (operands[1], DImode))"
@@ -10227,7 +10224,6 @@
li %0,%1
lis %0,%v1
#
- la %0,%a1
fmr %0,%1
lfd%U1%X1 %0,%1
stfd%U0%X0 %1,%0
@@ -10235,8 +10231,8 @@
mt%0 %1
{cror 0,0,0|nop}
xxlxor %x0,%x0,%x0"
- [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*,vecsimple")
- (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4")])
+ [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*,vecsimple")
+ (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")])
;; immediate value valid for a single instruction hiding in a const_double
(define_insn ""
@@ -11592,10 +11588,8 @@
"addi %0,%1,%2@got@tlsgd"
"&& TARGET_CMODEL != CMODEL_SMALL"
[(set (match_dup 3)
- (const:TLSmode
- (plus:TLSmode (match_dup 1)
- (high:TLSmode
- (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)))))
+ (high:TLSmode
+ (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
(set (match_dup 0)
(lo_sum:TLSmode (match_dup 3)
(unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)))]
@@ -11610,11 +11604,10 @@
(define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
[(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
- (const:TLSmode
- (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
- (high:TLSmode
- (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSGD)))))]
+ (high:TLSmode
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGD)))]
"HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
"addis %0,%1,%2@got@tlsgd@ha"
[(set_attr "length" "4")])
@@ -11729,10 +11722,8 @@
"addi %0,%1,%&@got@tlsld"
"&& TARGET_CMODEL != CMODEL_SMALL"
[(set (match_dup 2)
- (const:TLSmode
- (plus:TLSmode (match_dup 1)
- (high:TLSmode
- (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))))
+ (high:TLSmode
+ (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
(set (match_dup 0)
(lo_sum:TLSmode (match_dup 2)
(unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))]
@@ -11747,10 +11738,10 @@
(define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
[(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
- (const:TLSmode
- (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
- (high:TLSmode
- (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))))]
+ (high:TLSmode
+ (unspec:TLSmode [(const_int 0)
+ (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
+ UNSPEC_TLSLD)))]
"HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
"addis %0,%1,%&@got@tlsld@ha"
[(set_attr "length" "4")])
@@ -11826,10 +11817,8 @@
"l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
"&& TARGET_CMODEL != CMODEL_SMALL"
[(set (match_dup 3)
- (const:TLSmode
- (plus:TLSmode (match_dup 1)
- (high:TLSmode
- (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL)))))
+ (high:TLSmode
+ (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
(set (match_dup 0)
(lo_sum:TLSmode (match_dup 3)
(unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
@@ -11844,11 +11833,10 @@
(define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
[(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
- (const:TLSmode
- (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
- (high:TLSmode
- (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSGOTDTPREL)))))]
+ (high:TLSmode
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGOTDTPREL)))]
"HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
"addis %0,%1,%2@got@dtprel@ha"
[(set_attr "length" "4")])
@@ -11898,10 +11886,8 @@
"l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
"&& TARGET_CMODEL != CMODEL_SMALL"
[(set (match_dup 3)
- (const:TLSmode
- (plus:TLSmode (match_dup 1)
- (high:TLSmode
- (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL)))))
+ (high:TLSmode
+ (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
(set (match_dup 0)
(lo_sum:TLSmode (match_dup 3)
(unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL)))]
@@ -11916,11 +11902,10 @@
(define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
[(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
- (const:TLSmode
- (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
- (high:TLSmode
- (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
- UNSPEC_TLSGOTTPREL)))))]
+ (high:TLSmode
+ (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+ (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGOTTPREL)))]
"HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
"addis %0,%1,%2@got@tprel@ha"
[(set_attr "length" "4")])
@@ -12277,6 +12262,45 @@
DONE;
}")
+;; Largetoc support
+(define_insn "*largetoc_high"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
+ (high:DI
+ (unspec [(match_operand:DI 1 "" "")
+ (match_operand:DI 2 "gpc_reg_operand" "b")]
+ UNSPEC_TOCREL)))]
+ "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
+ "{cau|addis} %0,%2,%1@toc@ha")
+
+(define_insn "*largetoc_high_plus"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
+ (high:DI
+ (plus:DI
+ (unspec [(match_operand:DI 1 "" "")
+ (match_operand:DI 2 "gpc_reg_operand" "b")]
+ UNSPEC_TOCREL)
+ (match_operand 3 "const_int_operand" "n"))))]
+ "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
+ "{cau|addis} %0,%2,%1+%3@toc@ha")
+
+(define_insn "*largetoc_low"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+ (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,!*r")
+ (match_operand:DI 2 "" "")))]
+ "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
+ "@
+ {cal %0,%2@l(%1)|addi %0,%1,%2@l}
+ {ai|addic} %0,%1,%2@l")
+
+(define_insn_and_split "*tocref<mode>"
+ [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
+ (match_operand:P 1 "small_toc_ref" "R"))]
+ "TARGET_TOC"
+ "{cal|la} %0,%a1"
+ "&& TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL && reload_completed"
+ [(set (match_dup 0) (high:P (match_dup 1)))
+ (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
+
;; Elf specific ways of loading addresses for non-PIC code.
;; The output of this could be r0, but we make a very strong
;; preference for a base register because it will usually
@@ -12295,22 +12319,6 @@
"@
{cal|la} %0,%2@l(%1)
{ai|addic} %0,%1,%K2")
-
-;; Largetoc support
-(define_insn "largetoc_high"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
- (const:DI
- (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b")
- (high:DI (match_operand:DI 2 "" "")))))]
- "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
- "{cau|addis} %0,%1,%2@ha")
-
-(define_insn "largetoc_low"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
- (match_operand:DI 2 "" "")))]
- "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
- "{cal %0,%2@l(%1)|addi %0,%1,%2@l}")
;; Call and call_value insns
(define_expand "call"
diff --git a/gcc/config/rs6000/rtems.h b/gcc/config/rs6000/rtems.h
index 5641162fab4..60398df4849 100644
--- a/gcc/config/rs6000/rtems.h
+++ b/gcc/config/rs6000/rtems.h
@@ -55,17 +55,3 @@
#undef SUBSUBTARGET_EXTRA_SPECS
#define SUBSUBTARGET_EXTRA_SPECS \
{ "cpp_os_rtems", CPP_OS_RTEMS_SPEC }
-
-#undef SUBSUBTARGET_OVERRIDE_OPTIONS
-#define SUBSUBTARGET_OVERRIDE_OPTIONS \
- do { \
- if (TARGET_E500) \
- { \
- if (TARGET_HARD_FLOAT && !global_options_set.x_rs6000_float_gprs) \
- rs6000_float_gprs = 1; \
- if (rs6000_float_gprs != 0 && !global_options_set.x_rs6000_spe) \
- rs6000_spe = 1; \
- if (rs6000_spe && !global_options_set.x_rs6000_spe_abi) \
- rs6000_spe_abi = 1; \
- } \
- } while(0)
diff --git a/gcc/config/rs6000/vxworks.h b/gcc/config/rs6000/vxworks.h
index bef041cf39e..dc311d206c4 100644
--- a/gcc/config/rs6000/vxworks.h
+++ b/gcc/config/rs6000/vxworks.h
@@ -122,19 +122,8 @@ VXWORKS_ADDITIONAL_CPP_SPEC
#undef ABI_STACK_BOUNDARY
-/* Make -mcpu=8540 imply SPE. ISEL is automatically enabled, the
- others must be done by hand. Handle -mrtp. Disable -fPIC
- for -mrtp - the VxWorks PIC model is not compatible with it. */
#undef SUBSUBTARGET_OVERRIDE_OPTIONS
#define SUBSUBTARGET_OVERRIDE_OPTIONS \
- do { \
- if (TARGET_E500) \
- { \
- rs6000_spe = 1; \
- rs6000_spe_abi = 1; \
- rs6000_float_gprs = 1; \
- } \
- \
if (!global_options_set.x_g_switch_value) \
g_switch_value = SDATA_DEFAULT_SIZE; \
VXWORKS_OVERRIDE_OPTIONS; \