aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/config
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2014-05-17 17:03:43 -0700
committerBen Cheng <bccheng@google.com>2014-05-17 17:12:35 -0700
commit8c493ead6366b552adee796de296936b78f34c5a (patch)
tree4936e52fb9b84edbcd9293bd321027413d1835bf /gcc-4.9/gcc/config
parent9750bde7e561731ce8a07cdbd0165a688e74a696 (diff)
downloadtoolchain_gcc-8c493ead6366b552adee796de296936b78f34c5a.tar.gz
toolchain_gcc-8c493ead6366b552adee796de296936b78f34c5a.tar.bz2
toolchain_gcc-8c493ead6366b552adee796de296936b78f34c5a.zip
[4.9] Refresh GCC 4.9 to the 20140514 snapshot.
For critical bug fixes including devirtualization and codegen. Change-Id: I8138d3dc408fc12db5eecb01d2753d39219712f2
Diffstat (limited to 'gcc-4.9/gcc/config')
-rw-r--r--gcc-4.9/gcc/config/aarch64/aarch64.h12
-rw-r--r--gcc-4.9/gcc/config/alpha/alpha.c49
-rw-r--r--gcc-4.9/gcc/config/avr/avr-mcus.def2
-rw-r--r--gcc-4.9/gcc/config/avr/avr.c13
-rw-r--r--gcc-4.9/gcc/config/avr/avr.md8
-rw-r--r--gcc-4.9/gcc/config/i386/cygwin.h1
-rw-r--r--gcc-4.9/gcc/config/i386/i386.c22
-rw-r--r--gcc-4.9/gcc/config/i386/i386.md11
-rw-r--r--gcc-4.9/gcc/config/i386/mingw32.h1
-rw-r--r--gcc-4.9/gcc/config/msp430/msp430-protos.h3
-rw-r--r--gcc-4.9/gcc/config/msp430/msp430.c97
-rw-r--r--gcc-4.9/gcc/config/msp430/msp430.md32
-rw-r--r--gcc-4.9/gcc/config/msp430/msp430.opt35
-rw-r--r--gcc-4.9/gcc/config/rs6000/altivec.md112
-rw-r--r--gcc-4.9/gcc/config/rs6000/dfp.md69
-rw-r--r--gcc-4.9/gcc/config/rs6000/predicates.md9
-rw-r--r--gcc-4.9/gcc/config/rs6000/rs6000-builtin.def135
-rw-r--r--gcc-4.9/gcc/config/rs6000/rs6000.c116
-rw-r--r--gcc-4.9/gcc/config/rs6000/rs6000.h15
-rw-r--r--gcc-4.9/gcc/config/rs6000/rs6000.md255
-rw-r--r--gcc-4.9/gcc/config/rs6000/sync.md105
-rw-r--r--gcc-4.9/gcc/config/rs6000/vsx.md14
-rw-r--r--gcc-4.9/gcc/config/sh/sh.c8
-rw-r--r--gcc-4.9/gcc/config/sparc/sparc-protos.h1
-rw-r--r--gcc-4.9/gcc/config/sparc/sparc.c16
-rw-r--r--gcc-4.9/gcc/config/sparc/sparc.md304
-rw-r--r--gcc-4.9/gcc/config/sparc/sparc.opt4
-rw-r--r--gcc-4.9/gcc/config/sparc/sync.md19
28 files changed, 1143 insertions, 325 deletions
diff --git a/gcc-4.9/gcc/config/aarch64/aarch64.h b/gcc-4.9/gcc/config/aarch64/aarch64.h
index 7962aa472..2fd6df4af 100644
--- a/gcc-4.9/gcc/config/aarch64/aarch64.h
+++ b/gcc-4.9/gcc/config/aarch64/aarch64.h
@@ -32,7 +32,7 @@
else \
builtin_define ("__AARCH64EL__"); \
\
- if (!TARGET_GENERAL_REGS_ONLY) \
+ if (TARGET_SIMD) \
builtin_define ("__ARM_NEON"); \
\
switch (aarch64_cmodel) \
@@ -83,9 +83,9 @@
#define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN)
/* AdvSIMD is supported in the default configuration, unless disabled by
- -mgeneral-regs-only. */
-#define TARGET_SIMD !TARGET_GENERAL_REGS_ONLY
-#define TARGET_FLOAT !TARGET_GENERAL_REGS_ONLY
+ -mgeneral-regs-only or by the +nosimd extension. */
+#define TARGET_SIMD (!TARGET_GENERAL_REGS_ONLY && AARCH64_ISA_SIMD)
+#define TARGET_FLOAT (!TARGET_GENERAL_REGS_ONLY && AARCH64_ISA_FP)
#define UNITS_PER_WORD 8
@@ -185,8 +185,8 @@ extern unsigned long aarch64_isa_flags;
extern unsigned long aarch64_tune_flags;
#define AARCH64_TUNE_SLOWMUL (aarch64_tune_flags & AARCH64_FL_SLOWMUL)
-/* Crypto is an optional feature. */
-#define TARGET_CRYPTO AARCH64_ISA_CRYPTO
+/* Crypto is an optional extension to AdvSIMD. */
+#define TARGET_CRYPTO (TARGET_SIMD && AARCH64_ISA_CRYPTO)
/* Standard register usage. */
diff --git a/gcc-4.9/gcc/config/alpha/alpha.c b/gcc-4.9/gcc/config/alpha/alpha.c
index df4cc1b1c..dc07a02c0 100644
--- a/gcc-4.9/gcc/config/alpha/alpha.c
+++ b/gcc-4.9/gcc/config/alpha/alpha.c
@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-expr.h"
#include "is-a.h"
#include "gimple.h"
+#include "gimple-iterator.h"
#include "gimplify.h"
#include "gimple-ssa.h"
#include "stringpool.h"
@@ -7042,9 +7043,6 @@ alpha_fold_builtin (tree fndecl, int n_args, tree *op,
case ALPHA_BUILTIN_MSKQH:
return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, true);
- case ALPHA_BUILTIN_UMULH:
- return fold_build2 (MULT_HIGHPART_EXPR, alpha_dimode_u, op[0], op[1]);
-
case ALPHA_BUILTIN_ZAP:
opint[1] ^= 0xff;
/* FALLTHRU */
@@ -7094,6 +7092,49 @@ alpha_fold_builtin (tree fndecl, int n_args, tree *op,
return NULL;
}
}
+
+bool
+alpha_gimple_fold_builtin (gimple_stmt_iterator *gsi)
+{
+ bool changed = false;
+ gimple stmt = gsi_stmt (*gsi);
+ tree call = gimple_call_fn (stmt);
+ gimple new_stmt = NULL;
+
+ if (call)
+ {
+ tree fndecl = gimple_call_fndecl (stmt);
+
+ if (fndecl)
+ {
+ tree arg0, arg1;
+
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case ALPHA_BUILTIN_UMULH:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+
+ new_stmt
+ = gimple_build_assign_with_ops (MULT_HIGHPART_EXPR,
+ gimple_call_lhs (stmt),
+ arg0,
+ arg1);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (new_stmt)
+ {
+ gsi_replace (gsi, new_stmt, true);
+ changed = true;
+ }
+
+ return changed;
+}
/* This page contains routines that are used to determine what the function
prologue and epilogue code will do and write them out. */
@@ -9790,6 +9831,8 @@ alpha_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
#define TARGET_EXPAND_BUILTIN alpha_expand_builtin
#undef TARGET_FOLD_BUILTIN
#define TARGET_FOLD_BUILTIN alpha_fold_builtin
+#undef TARGET_GIMPLE_FOLD_BUILTIN
+#define TARGET_GIMPLE_FOLD_BUILTIN alpha_gimple_fold_builtin
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
diff --git a/gcc-4.9/gcc/config/avr/avr-mcus.def b/gcc-4.9/gcc/config/avr/avr-mcus.def
index 3cf2fcd41..483a30321 100644
--- a/gcc-4.9/gcc/config/avr/avr-mcus.def
+++ b/gcc-4.9/gcc/config/avr/avr-mcus.def
@@ -291,7 +291,7 @@ AVR_MCU ("atxmega192a3", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega192A3__
AVR_MCU ("atxmega192d3", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega192D3__", 0x2000, 4, "x192d3")
AVR_MCU ("atxmega256a3", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega256A3__", 0x2000, 5, "x256a3")
AVR_MCU ("atxmega256a3b", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega256A3B__", 0x2000, 5, "x256a3b")
-AVR_MCU ("atxmega256a3bu", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega258A3BU__", 0x2000, 5, "x256a3bu")
+AVR_MCU ("atxmega256a3bu", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega256A3BU__", 0x2000, 5, "x256a3bu")
AVR_MCU ("atxmega256d3", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega256D3__", 0x2000, 5, "x256d3")
AVR_MCU ("atxmega128a3u", ARCH_AVRXMEGA6, AVR_ISA_RMW, "__AVR_ATxmega128A3U__", 0x2000, 3, "x128a3u")
AVR_MCU ("atxmega128b1", ARCH_AVRXMEGA6, AVR_ISA_RMW, "__AVR_ATxmega128B1__", 0x2000, 3, "x128b1")
diff --git a/gcc-4.9/gcc/config/avr/avr.c b/gcc-4.9/gcc/config/avr/avr.c
index 99644ec92..fa979df46 100644
--- a/gcc-4.9/gcc/config/avr/avr.c
+++ b/gcc-4.9/gcc/config/avr/avr.c
@@ -2353,6 +2353,12 @@ avr_notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
}
break;
+ case CC_SET_VZN:
+ /* Insn like INC, DEC, NEG that set Z,N,V. We currently don't make use
+ of this combination, cf. also PR61055. */
+ CC_STATUS_INIT;
+ break;
+
case CC_SET_CZN:
/* Insn sets the Z,N,C flags of CC to recog_operand[0].
The V flag may or may not be known but that's ok because
@@ -3987,7 +3993,7 @@ avr_out_store_psi (rtx insn, rtx *op, int *plen)
"std Y+61,%A1" CR_TAB
"std Y+62,%B1" CR_TAB
"std Y+63,%C1" CR_TAB
- "sbiw r28,%o0-60", op, plen, -5);
+ "sbiw r28,%o0-61", op, plen, -5);
return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
"sbci r29,hi8(-%o0)" CR_TAB
@@ -6284,7 +6290,7 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
if (REG_P (xop[2]))
{
- *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_SET_N;
+ *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_CLOBBER;
for (i = 0; i < n_bytes; i++)
{
@@ -6393,7 +6399,7 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
op, plen, 1);
if (n_bytes == 2 && PLUS == code)
- *pcc = CC_SET_ZN;
+ *pcc = CC_SET_CZN;
}
i++;
@@ -6416,6 +6422,7 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
{
avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0",
op, plen, 1);
+ *pcc = CC_CLOBBER;
break;
}
diff --git a/gcc-4.9/gcc/config/avr/avr.md b/gcc-4.9/gcc/config/avr/avr.md
index d7baa4a83..2c59bf3f9 100644
--- a/gcc-4.9/gcc/config/avr/avr.md
+++ b/gcc-4.9/gcc/config/avr/avr.md
@@ -90,7 +90,7 @@
(include "constraints.md")
;; Condition code settings.
-(define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,
+(define_attr "cc" "none,set_czn,set_zn,set_vzn,set_n,compare,clobber,
plus,ldi"
(const_string "none"))
@@ -1098,7 +1098,7 @@
inc %0\;inc %0
dec %0\;dec %0"
[(set_attr "length" "1,1,1,1,2,2")
- (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
+ (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")])
;; "addhi3"
;; "addhq3" "adduhq3"
@@ -1369,7 +1369,7 @@
dec %0\;dec %0
inc %0\;inc %0"
[(set_attr "length" "1,1,1,1,2,2")
- (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
+ (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")])
;; "subhi3"
;; "subhq3" "subuhq3"
@@ -3992,7 +3992,7 @@
""
"neg %0"
[(set_attr "length" "1")
- (set_attr "cc" "set_zn")])
+ (set_attr "cc" "set_vzn")])
(define_insn "*negqihi2"
[(set (match_operand:HI 0 "register_operand" "=r")
diff --git a/gcc-4.9/gcc/config/i386/cygwin.h b/gcc-4.9/gcc/config/i386/cygwin.h
index f7b9a284c..165d3aae2 100644
--- a/gcc-4.9/gcc/config/i386/cygwin.h
+++ b/gcc-4.9/gcc/config/i386/cygwin.h
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s}\
+ %{!shared:%:if-exists(default-manifest.o%s)}\
crtend.o%s"
/* Normally, -lgcc is not needed since everything in it is in the DLL, but we
diff --git a/gcc-4.9/gcc/config/i386/i386.c b/gcc-4.9/gcc/config/i386/i386.c
index 3eefe4ac5..d7c592f48 100644
--- a/gcc-4.9/gcc/config/i386/i386.c
+++ b/gcc-4.9/gcc/config/i386/i386.c
@@ -3128,7 +3128,7 @@ ix86_option_override_internal (bool main_args_p,
(PTA_SANDYBRIDGE | PTA_FSGSBASE | PTA_RDRND | PTA_F16C)
#define PTA_HASWELL \
(PTA_IVYBRIDGE | PTA_AVX2 | PTA_BMI | PTA_BMI2 | PTA_LZCNT \
- | PTA_FMA | PTA_MOVBE | PTA_RTM | PTA_HLE)
+ | PTA_FMA | PTA_MOVBE | PTA_HLE)
#define PTA_BROADWELL \
(PTA_HASWELL | PTA_ADX | PTA_PRFCHW | PTA_RDSEED)
#define PTA_BONNELL \
@@ -24151,8 +24151,13 @@ ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
align = MEM_ALIGN (dst) / BITS_PER_UNIT;
if (CONST_INT_P (count_exp))
- min_size = max_size = probable_max_size = count = expected_size
- = INTVAL (count_exp);
+ {
+ min_size = max_size = probable_max_size = count = expected_size
+ = INTVAL (count_exp);
+ /* When COUNT is 0, there is nothing to do. */
+ if (!count)
+ return true;
+ }
else
{
if (min_size_exp)
@@ -24161,7 +24166,7 @@ ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
max_size = INTVAL (max_size_exp);
if (probable_max_size_exp)
probable_max_size = INTVAL (probable_max_size_exp);
- if (CONST_INT_P (expected_size_exp) && count == 0)
+ if (CONST_INT_P (expected_size_exp))
expected_size = INTVAL (expected_size_exp);
}
@@ -24390,7 +24395,8 @@ ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
if (jump_around_label == NULL_RTX)
jump_around_label = gen_label_rtx ();
emit_cmp_and_jump_insns (count_exp, GEN_INT (dynamic_check - 1),
- LEU, 0, GET_MODE (count_exp), 1, hot_label);
+ LEU, 0, counter_mode (count_exp),
+ 1, hot_label);
predict_jump (REG_BR_PROB_BASE * 90 / 100);
if (issetmem)
set_storage_via_libcall (dst, count_exp, val_exp, false);
@@ -35406,7 +35412,8 @@ rdrand_step:
else
op2 = gen_rtx_SUBREG (SImode, op0, 0);
- if (target == 0)
+ if (target == 0
+ || !register_operand (target, SImode))
target = gen_reg_rtx (SImode);
pat = gen_rtx_GEU (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
@@ -35448,7 +35455,8 @@ rdseed_step:
const0_rtx);
emit_insn (gen_rtx_SET (VOIDmode, op2, pat));
- if (target == 0)
+ if (target == 0
+ || !register_operand (target, SImode))
target = gen_reg_rtx (SImode);
emit_insn (gen_zero_extendqisi2 (target, op2));
diff --git a/gcc-4.9/gcc/config/i386/i386.md b/gcc-4.9/gcc/config/i386/i386.md
index 25e2e93e3..9f103cf30 100644
--- a/gcc-4.9/gcc/config/i386/i386.md
+++ b/gcc-4.9/gcc/config/i386/i386.md
@@ -14427,15 +14427,16 @@
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
{
+ rtx tmp1, tmp2;
if (optimize_insn_for_size_p ())
FAIL;
- operands[3] = gen_reg_rtx (XFmode);
- operands[4] = gen_reg_rtx (XFmode);
+ tmp1 = gen_reg_rtx (XFmode);
+ tmp2 = gen_reg_rtx (XFmode);
- emit_insn (gen_floatsixf2 (operands[3], operands[2]));
- emit_insn (gen_fscalexf4_i387 (operands[0], operands[4],
- operands[1], operands[3]));
+ emit_insn (gen_floatsixf2 (tmp1, operands[2]));
+ emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
+ operands[1], tmp1));
DONE;
})
diff --git a/gcc-4.9/gcc/config/i386/mingw32.h b/gcc-4.9/gcc/config/i386/mingw32.h
index f56382095..4cfd5f013 100644
--- a/gcc-4.9/gcc/config/i386/mingw32.h
+++ b/gcc-4.9/gcc/config/i386/mingw32.h
@@ -148,6 +148,7 @@ along with GCC; see the file COPYING3. If not see
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
+ %{!shared:%:if-exists(default-manifest.o%s)}\
crtend.o%s"
/* Override startfile prefix defaults. */
diff --git a/gcc-4.9/gcc/config/msp430/msp430-protos.h b/gcc-4.9/gcc/config/msp430/msp430-protos.h
index 7f999abbd..f0b8aea03 100644
--- a/gcc-4.9/gcc/config/msp430/msp430-protos.h
+++ b/gcc-4.9/gcc/config/msp430/msp430-protos.h
@@ -30,11 +30,9 @@ const char * msp430x_extendhisi (rtx *);
void msp430_fixup_compare_operands (enum machine_mode, rtx *);
int msp430_hard_regno_mode_ok (int, enum machine_mode);
int msp430_hard_regno_nregs (int, enum machine_mode);
-bool msp430_hwmult_enabled (void);
rtx msp430_incoming_return_addr_rtx (void);
void msp430_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
int msp430_initial_elimination_offset (int, int);
-bool msp430_is_f5_mcu (void);
bool msp430_is_interrupt_func (void);
const char * msp430x_logical_shift_right (rtx);
const char * msp430_mcu_name (void);
@@ -45,5 +43,6 @@ rtx msp430_return_addr_rtx (int);
void msp430_split_movsi (rtx *);
void msp430_start_function (FILE *, const char *, tree);
rtx msp430_subreg (enum machine_mode, rtx, enum machine_mode, int);
+bool msp430_use_f5_series_hwmult (void);
#endif /* GCC_MSP430_PROTOS_H */
diff --git a/gcc-4.9/gcc/config/msp430/msp430.c b/gcc-4.9/gcc/config/msp430/msp430.c
index 80a17a6e3..c844aa2a1 100644
--- a/gcc-4.9/gcc/config/msp430/msp430.c
+++ b/gcc-4.9/gcc/config/msp430/msp430.c
@@ -95,18 +95,6 @@ msp430_init_machine_status (void)
return m;
}
-#undef TARGET_HANDLE_OPTION
-#define TARGET_HANDLE_OPTION msp430_handle_option
-
-bool
-msp430_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED,
- struct gcc_options *opts_set ATTRIBUTE_UNUSED,
- const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED,
- location_t loc ATTRIBUTE_UNUSED)
-{
- return true;
-}
-
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE msp430_option_override
@@ -196,19 +184,14 @@ msp430_option_override (void)
if (target_cpu)
{
- if (strcasecmp (target_cpu, "msp430x") == 0
- || strcasecmp (target_cpu, "msp430xv2") == 0
- || strcasecmp (target_cpu, "430x") == 0
- || strcasecmp (target_cpu, "430xv2") == 0)
+ if (strcasecmp (target_cpu, "msp430x") == 0)
msp430x = true;
- else if (strcasecmp (target_cpu, "msp430") == 0
- || strcasecmp (target_cpu, "430") == 0)
+ else /* target_cpu == "msp430" - already handled by the front end. */
msp430x = false;
- else
- error ("unrecognised argument of -mcpu: %s", target_cpu);
}
-
- if (target_mcu)
+ /* Note - the front end has already ensured at most
+ one of target_cpu and target_mcu will be set. */
+ else if (target_mcu)
{
int i;
@@ -217,25 +200,12 @@ msp430_option_override (void)
supports 430. */
msp430x = true;
- /* For backwards compatibility we recognise two generic MCU
- 430X names. However we want to be able to generate special C
- preprocessor defines for them, which is why we set target_mcu
- to NULL. */
- if (strcasecmp (target_mcu, "msp430") == 0)
- {
- msp430x = false;
- target_mcu = NULL;
- }
- else if (strcasecmp (target_mcu, "msp430x") == 0
- || strcasecmp (target_mcu, "msp430xv2") == 0)
- target_mcu = NULL;
- else
- for (i = ARRAY_SIZE (msp430_mcu_names); i--;)
- if (strcasecmp (msp430_mcu_names[i], target_mcu) == 0)
- {
- msp430x = false;
- break;
- }
+ for (i = ARRAY_SIZE (msp430_mcu_names); i--;)
+ if (strcasecmp (msp430_mcu_names[i], target_mcu) == 0)
+ {
+ msp430x = false;
+ break;
+ }
/* It is not an error if we do not match the MCU name. There are
hundreds of them. */
}
@@ -1847,16 +1817,20 @@ static const struct
/* Returns true if the current MCU is an F5xxx series. */
bool
-msp430_is_f5_mcu (void)
+msp430_use_f5_series_hwmult (void)
{
- if (target_mcu == NULL)
+ if (msp430_hwmult_type == F5SERIES)
+ return true;
+
+ if (target_mcu == NULL || msp430_hwmult_type != AUTO)
return false;
+
return strncasecmp (target_mcu, "msp430f5", 8) == 0;
}
/* Returns true id the current MCU has a second generation 32-bit hardware multiplier. */
static bool
-has_32bit_hw_mult (void)
+use_32bit_hwmult (void)
{
static const char * known_32bit_mult_mcus [] =
{
@@ -1868,7 +1842,11 @@ has_32bit_hw_mult (void)
"msp430f47177", "msp430f47187", "msp430f47197"
};
int i;
- if (target_mcu == NULL)
+
+ if (msp430_hwmult_type == LARGE)
+ return true;
+
+ if (target_mcu == NULL || msp430_hwmult_type != AUTO)
return false;
for (i = ARRAY_SIZE (known_32bit_mult_mcus); i--;)
@@ -1878,25 +1856,6 @@ has_32bit_hw_mult (void)
return false;
}
-/* Returns true if hardware multiply is supported by the chosen MCU. */
-bool
-msp430_hwmult_enabled (void)
-{
- if (target_mcu == NULL)
- return false;
-
- if (!ENABLE_HWMULT)
- return false;
-
- if (msp430_is_interrupt_func ())
- return false;
-
- if (msp430_is_f5_mcu () || has_32bit_hw_mult ())
- return true;
-
- return false;
-}
-
/* This function does the same as the default, but it will replace GCC
function names with the MSPABI-specified ones. */
void
@@ -1913,20 +1872,20 @@ msp430_output_labelref (FILE *file, const char *name)
/* If we have been given a specific MCU name then we may be
able to make use of its hardware multiply capabilities. */
- if (msp430_hwmult_enabled ())
+ if (msp430_hwmult_type != NONE)
{
if (strcmp ("__mspabi_mpyi", name) == 0)
{
- if (msp430_is_f5_mcu ())
+ if (msp430_use_f5_series_hwmult ())
name = "__mulhi2_f5";
else
name = "__mulhi2";
}
else if (strcmp ("__mspabi_mpyl", name) == 0)
{
- if (msp430_is_f5_mcu ())
+ if (msp430_use_f5_series_hwmult ())
name = "__mulsi2_f5";
- else if (has_32bit_hw_mult ())
+ else if (use_32bit_hwmult ())
name = "__mulsi2_hw32";
else
name = "__mulsi2";
@@ -2203,7 +2162,7 @@ msp430_print_operand (FILE * file, rtx op, int letter)
because builtins are expanded before the frame layout is determined. */
fprintf (file, "%d",
msp430_initial_elimination_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM)
- - 2);
+ - (TARGET_LARGE ? 4 : 2));
return;
case 'J':
diff --git a/gcc-4.9/gcc/config/msp430/msp430.md b/gcc-4.9/gcc/config/msp430/msp430.md
index c0c97dae6..74a98b480 100644
--- a/gcc-4.9/gcc/config/msp430/msp430.md
+++ b/gcc-4.9/gcc/config/msp430/msp430.md
@@ -1321,12 +1321,12 @@
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
(sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
- "optimize > 2 && msp430_hwmult_enabled ()"
+ "optimize > 2 && msp430_hwmult_type != NONE"
"*
- if (msp430_is_f5_mcu ())
- return \"MOV.W %1, &0x04C2 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0\";
+ if (msp430_use_f5_series_hwmult ())
+ return \"PUSH.W sr { DINT { MOV.W %1, &0x04C2 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0 { POP.W sr\";
else
- return \"MOV.W %1, &0x0132 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0\";
+ return \"PUSH.W sr { DINT { MOV.W %1, &0x0132 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0 { POP.W sr\";
"
)
@@ -1334,12 +1334,12 @@
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
- "optimize > 2 && msp430_hwmult_enabled ()"
+ "optimize > 2 && msp430_hwmult_type != NONE"
"*
- if (msp430_is_f5_mcu ())
- return \"MOV.W %1, &0x04C0 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0\";
+ if (msp430_use_f5_series_hwmult ())
+ return \"PUSH.W sr { DINT { MOV.W %1, &0x04C0 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0 { POP.W sr\";
else
- return \"MOV.W %1, &0x0130 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0\";
+ return \"PUSH.W sr { DINT { MOV.W %1, &0x0130 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0 { POP.W sr\";
"
)
@@ -1347,12 +1347,12 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
(sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
- "optimize > 2 && msp430_hwmult_enabled ()"
+ "optimize > 2 && msp430_hwmult_type != NONE"
"*
- if (msp430_is_f5_mcu ())
- return \"MOV.W %L1, &0x04D4 { MOV.W %H1, &0x04D6 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0\";
+ if (msp430_use_f5_series_hwmult ())
+ return \"PUSH.W sr { DINT { MOV.W %L1, &0x04D4 { MOV.W %H1, &0x04D6 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0 { POP.W sr\";
else
- return \"MOV.W %L1, &0x0144 { MOV.W %H1, &0x0146 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0\";
+ return \"PUSH.W sr { DINT { MOV.W %L1, &0x0144 { MOV.W %H1, &0x0146 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0 { POP.W sr\";
"
)
@@ -1360,11 +1360,11 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
(zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
- "optimize > 2 && msp430_hwmult_enabled ()"
+ "optimize > 2 && msp430_hwmult_type != NONE"
"*
- if (msp430_is_f5_mcu ())
- return \"MOV.W %L1, &0x04D0 { MOV.W %H1, &0x04D2 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0\";
+ if (msp430_use_f5_series_hwmult ())
+ return \"PUSH.W sr { DINT { MOV.W %L1, &0x04D0 { MOV.W %H1, &0x04D2 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0 { POP.W sr\";
else
- return \"MOV.W %L1, &0x0140 { MOV.W %H1, &0x0141 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0\";
+ return \"PUSH.W sr { DINT { MOV.W %L1, &0x0140 { MOV.W %H1, &0x0142 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0 { POP.W sr\";
"
)
diff --git a/gcc-4.9/gcc/config/msp430/msp430.opt b/gcc-4.9/gcc/config/msp430/msp430.opt
index 5a447c0d2..8215013e8 100644
--- a/gcc-4.9/gcc/config/msp430/msp430.opt
+++ b/gcc-4.9/gcc/config/msp430/msp430.opt
@@ -7,19 +7,19 @@ Target Mask(ASM_HEX)
Force assembly output to always use hex constants
mmcu=
-Target ToLower Joined RejectNegative Var(target_mcu)
+Target Report ToLower Joined RejectNegative Var(target_mcu)
Specify the MCU to build for.
mcpu=
-Target Joined RejectNegative Var(target_cpu)
+Target Report Joined RejectNegative Var(target_cpu)
Specify the ISA to build for: msp430, mdsp430x, msp430xv2
mlarge
-Target Mask(LARGE) RejectNegative
+Target Report Mask(LARGE) RejectNegative
Select large model - 20-bit addresses/pointers
msmall
-Target InverseMask(LARGE) RejectNegative
+Target Report InverseMask(LARGE) RejectNegative
Select small model - 16-bit addresses/pointers (default)
mrelax
@@ -33,6 +33,27 @@ minrt
Target Report Mask(MINRT) RejectNegative
Use a minimum runtime (no static initializers or ctors) for memory-constrained devices.
-mhwmult
-Target Report Var(ENABLE_HWMULT, 1) Init(1)
-Enable hardware multiply (except in interrupt routines)
+HeaderInclude
+config/msp430/msp430-opts.h
+
+mhwmult=
+Target Joined RejectNegative Report ToLower Var(msp430_hwmult_type) Enum(msp430_hwmult_types) Init(AUTO)
+Specify the type of hardware multiply to support
+
+Enum
+Name(msp430_hwmult_types) Type(enum msp430_hwmult_types)
+
+EnumValue
+Enum(msp430_hwmult_types) String(none) Value(NONE)
+
+EnumValue
+Enum(msp430_hwmult_types) String(auto) Value(AUTO)
+
+EnumValue
+Enum(msp430_hwmult_types) String(16bit) Value(SMALL)
+
+EnumValue
+Enum(msp430_hwmult_types) String(32bit) Value(LARGE)
+
+EnumValue
+Enum(msp430_hwmult_types) String(f5series) Value(F5SERIES)
diff --git a/gcc-4.9/gcc/config/rs6000/altivec.md b/gcc-4.9/gcc/config/rs6000/altivec.md
index 674cb40bf..a8cfcb739 100644
--- a/gcc-4.9/gcc/config/rs6000/altivec.md
+++ b/gcc-4.9/gcc/config/rs6000/altivec.md
@@ -143,6 +143,9 @@
UNSPEC_VSUBEUQM
UNSPEC_VSUBECUQ
UNSPEC_VBPERMQ
+ UNSPEC_BCDADD
+ UNSPEC_BCDSUB
+ UNSPEC_BCD_OVERFLOW
])
(define_c_enum "unspecv"
@@ -3334,3 +3337,112 @@
"vbpermq %0,%1,%2"
[(set_attr "length" "4")
(set_attr "type" "vecsimple")])
+
+;; Decimal Integer operations
+(define_int_iterator UNSPEC_BCD_ADD_SUB [UNSPEC_BCDADD UNSPEC_BCDSUB])
+
+(define_int_attr bcd_add_sub [(UNSPEC_BCDADD "add")
+ (UNSPEC_BCDSUB "sub")])
+
+(define_code_iterator BCD_TEST [eq lt gt unordered])
+
+(define_insn "bcd<bcd_add_sub>"
+ [(set (match_operand:V1TI 0 "register_operand" "")
+ (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "")
+ (match_operand:V1TI 2 "register_operand" "")
+ (match_operand:QI 3 "const_0_to_1_operand" "")]
+ UNSPEC_BCD_ADD_SUB))
+ (clobber (reg:CCFP 74))]
+ "TARGET_P8_VECTOR"
+ "bcd<bcd_add_sub>. %0,%1,%2,%3"
+ [(set_attr "length" "4")
+ (set_attr "type" "vecsimple")])
+
+;; Use a floating point type (V2DFmode) for the compare to set CR6 so that we
+;; can use the unordered test for BCD nans and add/subtracts that overflow. An
+;; UNORDERED test on an integer type (like V1TImode) is not defined. The type
+;; probably should be one that can go in the VMX (Altivec) registers, so we
+;; can't use DDmode or DFmode.
+(define_insn "*bcd<bcd_add_sub>_test"
+ [(set (reg:CCFP 74)
+ (compare:CCFP
+ (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "v")
+ (match_operand:V1TI 2 "register_operand" "v")
+ (match_operand:QI 3 "const_0_to_1_operand" "i")]
+ UNSPEC_BCD_ADD_SUB)
+ (match_operand:V2DF 4 "zero_constant" "j")))
+ (clobber (match_scratch:V1TI 0 "=v"))]
+ "TARGET_P8_VECTOR"
+ "bcd<bcd_add_sub>. %0,%1,%2,%3"
+ [(set_attr "length" "4")
+ (set_attr "type" "vecsimple")])
+
+(define_insn "*bcd<bcd_add_sub>_test2"
+ [(set (match_operand:V1TI 0 "register_operand" "=v")
+ (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
+ (match_operand:V1TI 2 "register_operand" "v")
+ (match_operand:QI 3 "const_0_to_1_operand" "i")]
+ UNSPEC_BCD_ADD_SUB))
+ (set (reg:CCFP 74)
+ (compare:CCFP
+ (unspec:V2DF [(match_dup 1)
+ (match_dup 2)
+ (match_dup 3)]
+ UNSPEC_BCD_ADD_SUB)
+ (match_operand:V2DF 4 "zero_constant" "j")))]
+ "TARGET_P8_VECTOR"
+ "bcd<bcd_add_sub>. %0,%1,%2,%3"
+ [(set_attr "length" "4")
+ (set_attr "type" "vecsimple")])
+
+(define_expand "bcd<bcd_add_sub>_<code>"
+ [(parallel [(set (reg:CCFP 74)
+ (compare:CCFP
+ (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "")
+ (match_operand:V1TI 2 "register_operand" "")
+ (match_operand:QI 3 "const_0_to_1_operand" "")]
+ UNSPEC_BCD_ADD_SUB)
+ (match_dup 4)))
+ (clobber (match_scratch:V1TI 5 ""))])
+ (set (match_operand:SI 0 "register_operand" "")
+ (BCD_TEST:SI (reg:CCFP 74)
+ (const_int 0)))]
+ "TARGET_P8_VECTOR"
+{
+ operands[4] = CONST0_RTX (V2DFmode);
+})
+
+;; Peephole2 pattern to combine a bcdadd/bcdsub that calculates the value and
+;; the bcdadd/bcdsub that tests the value. The combiner won't work since
+;; CR6 is a hard coded register. Unfortunately, all of the Altivec predicate
+;; support is hard coded to use the fixed register CR6 instead of creating
+;; a register class for CR6.
+
+(define_peephole2
+ [(parallel [(set (match_operand:V1TI 0 "register_operand" "")
+ (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "")
+ (match_operand:V1TI 2 "register_operand" "")
+ (match_operand:QI 3 "const_0_to_1_operand" "")]
+ UNSPEC_BCD_ADD_SUB))
+ (clobber (reg:CCFP 74))])
+ (parallel [(set (reg:CCFP 74)
+ (compare:CCFP
+ (unspec:V2DF [(match_dup 1)
+ (match_dup 2)
+ (match_dup 3)]
+ UNSPEC_BCD_ADD_SUB)
+ (match_operand:V2DF 4 "zero_constant" "")))
+ (clobber (match_operand:V1TI 5 "register_operand" ""))])]
+ "TARGET_P8_VECTOR"
+ [(parallel [(set (match_dup 0)
+ (unspec:V1TI [(match_dup 1)
+ (match_dup 2)
+ (match_dup 3)]
+ UNSPEC_BCD_ADD_SUB))
+ (set (reg:CCFP 74)
+ (compare:CCFP
+ (unspec:V2DF [(match_dup 1)
+ (match_dup 2)
+ (match_dup 3)]
+ UNSPEC_BCD_ADD_SUB)
+ (match_dup 4)))])])
diff --git a/gcc-4.9/gcc/config/rs6000/dfp.md b/gcc-4.9/gcc/config/rs6000/dfp.md
index 8e99bc0d7..40e27e77d 100644
--- a/gcc-4.9/gcc/config/rs6000/dfp.md
+++ b/gcc-4.9/gcc/config/rs6000/dfp.md
@@ -322,3 +322,72 @@
"TARGET_DFP"
"dctfixq %0,%1"
[(set_attr "type" "fp")])
+
+
+;; Decimal builtin support
+
+(define_c_enum "unspec"
+ [UNSPEC_DDEDPD
+ UNSPEC_DENBCD
+ UNSPEC_DXEX
+ UNSPEC_DIEX
+ UNSPEC_DSCLI
+ UNSPEC_DSCRI])
+
+(define_mode_iterator D64_D128 [DD TD])
+
+(define_mode_attr dfp_suffix [(DD "")
+ (TD "q")])
+
+(define_insn "dfp_ddedpd_<mode>"
+ [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+ (unspec:D64_D128 [(match_operand:QI 1 "const_0_to_3_operand" "i")
+ (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
+ UNSPEC_DDEDPD))]
+ "TARGET_DFP"
+ "ddedpd<dfp_suffix> %1,%0,%2"
+ [(set_attr "type" "fp")])
+
+(define_insn "dfp_denbcd_<mode>"
+ [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+ (unspec:D64_D128 [(match_operand:QI 1 "const_0_to_1_operand" "i")
+ (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
+ UNSPEC_DENBCD))]
+ "TARGET_DFP"
+ "denbcd<dfp_suffix> %1,%0,%2"
+ [(set_attr "type" "fp")])
+
+(define_insn "dfp_dxex_<mode>"
+ [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+ (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")]
+ UNSPEC_DXEX))]
+ "TARGET_DFP"
+ "dxex<dfp_suffix> %0,%1"
+ [(set_attr "type" "fp")])
+
+(define_insn "dfp_diex_<mode>"
+ [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+ (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
+ (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
+ UNSPEC_DXEX))]
+ "TARGET_DFP"
+ "diex<dfp_suffix> %0,%1,%2"
+ [(set_attr "type" "fp")])
+
+(define_insn "dfp_dscli_<mode>"
+ [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+ (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
+ (match_operand:QI 2 "immediate_operand" "i")]
+ UNSPEC_DSCLI))]
+ "TARGET_DFP"
+ "dscli<dfp_suffix> %0,%1,%2"
+ [(set_attr "type" "fp")])
+
+(define_insn "dfp_dscri_<mode>"
+ [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+ (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
+ (match_operand:QI 2 "immediate_operand" "i")]
+ UNSPEC_DSCRI))]
+ "TARGET_DFP"
+ "dscri<dfp_suffix> %0,%1,%2"
+ [(set_attr "type" "fp")])
diff --git a/gcc-4.9/gcc/config/rs6000/predicates.md b/gcc-4.9/gcc/config/rs6000/predicates.md
index 28f4f5d98..8c384b380 100644
--- a/gcc-4.9/gcc/config/rs6000/predicates.md
+++ b/gcc-4.9/gcc/config/rs6000/predicates.md
@@ -171,6 +171,11 @@
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 1)")))
+;; Match op = 0..3.
+(define_predicate "const_0_to_3_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 3)")))
+
;; Match op = 2 or op = 3.
(define_predicate "const_2_to_3_operand"
(and (match_code "const_int")
@@ -624,14 +629,14 @@
(match_test "offsettable_nonstrict_memref_p (op)")))
;; Return 1 if the operand is suitable for load/store quad memory.
-;; This predicate only checks for non-atomic loads/stores.
+;; This predicate only checks for non-atomic loads/stores (not lqarx/stqcx).
(define_predicate "quad_memory_operand"
(match_code "mem")
{
rtx addr, op0, op1;
int ret;
- if (!TARGET_QUAD_MEMORY)
+ if (!TARGET_QUAD_MEMORY && !TARGET_SYNC_TI)
ret = 0;
else if (!memory_operand (op, mode))
diff --git a/gcc-4.9/gcc/config/rs6000/rs6000-builtin.def b/gcc-4.9/gcc/config/rs6000/rs6000-builtin.def
index 83351691f..8e15bdf16 100644
--- a/gcc-4.9/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc-4.9/gcc/config/rs6000/rs6000-builtin.def
@@ -570,6 +570,75 @@
MASK, /* MASK */ \
(ATTR | RS6000_BTC_SPECIAL), /* ATTR */ \
CODE_FOR_nothing) /* ICODE */
+
+
+/* Decimal floating point builtins for instructions. */
+#define BU_DFP_MISC_1(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_DFP, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_UNARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+#define BU_DFP_MISC_2(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_DFP, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_BINARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+
+/* Miscellaneous builtins for instructions added in ISA 2.06. These
+ instructions don't require either the DFP or VSX options, just the basic ISA
+ 2.06 (popcntd) enablement since they operate on general purpose
+ registers. */
+#define BU_P7_MISC_1(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_POPCNTD, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_UNARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+#define BU_P7_MISC_2(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_POPCNTD, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_BINARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+
+/* Miscellaneous builtins for instructions added in ISA 2.07. These
+ instructions do require the ISA 2.07 vector support, but they aren't vector
+ instructions. */
+#define BU_P8V_MISC_3(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_3 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_P8_VECTOR, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_TERNARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+/* Miscellaneous builtins. */
+#define BU_MISC_1(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_HARD_FLOAT, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_UNARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+#define BU_MISC_2(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_HARD_FLOAT, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_BINARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
#endif
/* Insure 0 is not a legitimate index. */
@@ -1412,10 +1481,10 @@ BU_P8V_AV_2 (ORC_V4SF, "orc_v4sf", CONST, orcv4sf3)
BU_P8V_AV_2 (ORC_V2DF, "orc_v2df", CONST, orcv2df3)
/* 3 argument altivec instructions added in ISA 2.07. */
-BU_P8V_AV_3 (VADDEUQM, "vaddeuqm", CONST, altivec_vaddeuqm)
-BU_P8V_AV_3 (VADDECUQ, "vaddecuq", CONST, altivec_vaddecuq)
-BU_P8V_AV_3 (VSUBEUQM, "vsubeuqm", CONST, altivec_vsubeuqm)
-BU_P8V_AV_3 (VSUBECUQ, "vsubecuq", CONST, altivec_vsubecuq)
+BU_P8V_AV_3 (VADDEUQM, "vaddeuqm", CONST, altivec_vaddeuqm)
+BU_P8V_AV_3 (VADDECUQ, "vaddecuq", CONST, altivec_vaddecuq)
+BU_P8V_AV_3 (VSUBEUQM, "vsubeuqm", CONST, altivec_vsubeuqm)
+BU_P8V_AV_3 (VSUBECUQ, "vsubecuq", CONST, altivec_vsubecuq)
/* Vector comparison instructions added in ISA 2.07. */
BU_P8V_AV_2 (VCMPEQUD, "vcmpequd", CONST, vector_eqv2di)
@@ -1475,6 +1544,64 @@ BU_P8V_OVERLOAD_3 (VSUBECUQ, "vsubecuq")
BU_P8V_OVERLOAD_3 (VSUBEUQM, "vsubeuqm")
+/* 2 argument extended divide functions added in ISA 2.06. */
+BU_P7_MISC_2 (DIVWE, "divwe", CONST, dive_si)
+BU_P7_MISC_2 (DIVWEO, "divweo", CONST, diveo_si)
+BU_P7_MISC_2 (DIVWEU, "divweu", CONST, diveu_si)
+BU_P7_MISC_2 (DIVWEUO, "divweuo", CONST, diveuo_si)
+BU_P7_MISC_2 (DIVDE, "divde", CONST, dive_di)
+BU_P7_MISC_2 (DIVDEO, "divdeo", CONST, diveo_di)
+BU_P7_MISC_2 (DIVDEU, "divdeu", CONST, diveu_di)
+BU_P7_MISC_2 (DIVDEUO, "divdeuo", CONST, diveuo_di)
+
+/* 1 argument DFP (decimal floating point) functions added in ISA 2.05. */
+BU_DFP_MISC_1 (DXEX, "dxex", CONST, dfp_dxex_dd)
+BU_DFP_MISC_1 (DXEXQ, "dxexq", CONST, dfp_dxex_td)
+
+/* 2 argument DFP (decimal floating point) functions added in ISA 2.05. */
+BU_DFP_MISC_2 (DDEDPD, "ddedpd", CONST, dfp_ddedpd_dd)
+BU_DFP_MISC_2 (DDEDPDQ, "ddedpdq", CONST, dfp_ddedpd_td)
+BU_DFP_MISC_2 (DENBCD, "denbcd", CONST, dfp_denbcd_dd)
+BU_DFP_MISC_2 (DENBCDQ, "denbcdq", CONST, dfp_denbcd_td)
+BU_DFP_MISC_2 (DIEX, "diex", CONST, dfp_diex_dd)
+BU_DFP_MISC_2 (DIEXQ, "diexq", CONST, dfp_diex_td)
+BU_DFP_MISC_2 (DSCLI, "dscli", CONST, dfp_dscli_dd)
+BU_DFP_MISC_2 (DSCLIQ, "dscliq", CONST, dfp_dscli_td)
+BU_DFP_MISC_2 (DSCRI, "dscri", CONST, dfp_dscri_dd)
+BU_DFP_MISC_2 (DSCRIQ, "dscriq", CONST, dfp_dscri_td)
+
+/* 1 argument BCD functions added in ISA 2.06. */
+BU_P7_MISC_1 (CDTBCD, "cdtbcd", CONST, cdtbcd)
+BU_P7_MISC_1 (CBCDTD, "cbcdtd", CONST, cbcdtd)
+
+/* 2 argument BCD functions added in ISA 2.06. */
+BU_P7_MISC_2 (ADDG6S, "addg6s", CONST, addg6s)
+
+/* 3 argument BCD functions added in ISA 2.07. */
+BU_P8V_MISC_3 (BCDADD, "bcdadd", CONST, bcdadd)
+BU_P8V_MISC_3 (BCDADD_LT, "bcdadd_lt", CONST, bcdadd_lt)
+BU_P8V_MISC_3 (BCDADD_EQ, "bcdadd_eq", CONST, bcdadd_eq)
+BU_P8V_MISC_3 (BCDADD_GT, "bcdadd_gt", CONST, bcdadd_gt)
+BU_P8V_MISC_3 (BCDADD_OV, "bcdadd_ov", CONST, bcdadd_unordered)
+BU_P8V_MISC_3 (BCDSUB, "bcdsub", CONST, bcdsub)
+BU_P8V_MISC_3 (BCDSUB_LT, "bcdsub_lt", CONST, bcdsub_lt)
+BU_P8V_MISC_3 (BCDSUB_EQ, "bcdsub_eq", CONST, bcdsub_eq)
+BU_P8V_MISC_3 (BCDSUB_GT, "bcdsub_gt", CONST, bcdsub_gt)
+BU_P8V_MISC_3 (BCDSUB_OV, "bcdsub_ov", CONST, bcdsub_unordered)
+
+/* 2 argument pack/unpack 128-bit floating point types. */
+BU_DFP_MISC_2 (PACK_TD, "pack_dec128", CONST, packtd)
+BU_DFP_MISC_2 (UNPACK_TD, "unpack_dec128", CONST, unpacktd)
+
+BU_MISC_2 (PACK_TF, "pack_longdouble", CONST, packtf)
+BU_MISC_2 (UNPACK_TF, "unpack_longdouble", CONST, unpacktf)
+BU_MISC_1 (UNPACK_TF_0, "longdouble_dw0", CONST, unpacktf_0)
+BU_MISC_1 (UNPACK_TF_1, "longdouble_dw1", CONST, unpacktf_1)
+
+BU_P7_MISC_2 (PACK_V1TI, "pack_vector_int128", CONST, packv1ti)
+BU_P7_MISC_2 (UNPACK_V1TI, "unpack_vector_int128", CONST, unpackv1ti)
+
+
/* 1 argument crypto functions. */
BU_CRYPTO_1 (VSBOX, "vsbox", CONST, crypto_vsbox)
diff --git a/gcc-4.9/gcc/config/rs6000/rs6000.c b/gcc-4.9/gcc/config/rs6000/rs6000.c
index 494efc562..4f1a399a2 100644
--- a/gcc-4.9/gcc/config/rs6000/rs6000.c
+++ b/gcc-4.9/gcc/config/rs6000/rs6000.c
@@ -2283,6 +2283,24 @@ rs6000_debug_reg_global (void)
if (rs6000_float_gprs)
fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
+ fprintf (stderr, DEBUG_FMT_S, "fprs",
+ (TARGET_FPRS ? "true" : "false"));
+
+ fprintf (stderr, DEBUG_FMT_S, "single_float",
+ (TARGET_SINGLE_FLOAT ? "true" : "false"));
+
+ fprintf (stderr, DEBUG_FMT_S, "double_float",
+ (TARGET_DOUBLE_FLOAT ? "true" : "false"));
+
+ fprintf (stderr, DEBUG_FMT_S, "soft_float",
+ (TARGET_SOFT_FLOAT ? "true" : "false"));
+
+ fprintf (stderr, DEBUG_FMT_S, "e500_single",
+ (TARGET_E500_SINGLE ? "true" : "false"));
+
+ fprintf (stderr, DEBUG_FMT_S, "e500_double",
+ (TARGET_E500_DOUBLE ? "true" : "false"));
+
if (TARGET_LINK_STACK)
fprintf (stderr, DEBUG_FMT_S, "link_stack", "true");
@@ -3017,7 +3035,9 @@ rs6000_builtin_mask_calculate (void)
| ((rs6000_cpu == PROCESSOR_CELL) ? RS6000_BTM_CELL : 0)
| ((TARGET_P8_VECTOR) ? RS6000_BTM_P8_VECTOR : 0)
| ((TARGET_CRYPTO) ? RS6000_BTM_CRYPTO : 0)
- | ((TARGET_HTM) ? RS6000_BTM_HTM : 0));
+ | ((TARGET_HTM) ? RS6000_BTM_HTM : 0)
+ | ((TARGET_DFP) ? RS6000_BTM_DFP : 0)
+ | ((TARGET_HARD_FLOAT) ? RS6000_BTM_HARD_FLOAT : 0));
}
/* Override command line options. Mostly we process the processor type and
@@ -3374,6 +3394,13 @@ rs6000_option_override_internal (bool global_init_p)
rs6000_isa_flags &= ~OPTION_MASK_VSX_TIMODE;
}
+ if (TARGET_DFP && !TARGET_HARD_FLOAT)
+ {
+ if (rs6000_isa_flags_explicit & OPTION_MASK_DFP)
+ error ("-mhard-dfp requires -mhard-float");
+ rs6000_isa_flags &= ~OPTION_MASK_DFP;
+ }
+
/* The quad memory instructions only works in 64-bit mode. In 32-bit mode,
silently turn off quad memory mode. */
if ((TARGET_QUAD_MEMORY || TARGET_QUAD_MEMORY_ATOMIC) && !TARGET_POWERPC64)
@@ -12381,7 +12408,15 @@ rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
}
}
else if (icode == CODE_FOR_vsx_set_v2df
- || icode == CODE_FOR_vsx_set_v2di)
+ || icode == CODE_FOR_vsx_set_v2di
+ || icode == CODE_FOR_bcdadd
+ || icode == CODE_FOR_bcdadd_lt
+ || icode == CODE_FOR_bcdadd_eq
+ || icode == CODE_FOR_bcdadd_gt
+ || icode == CODE_FOR_bcdsub
+ || icode == CODE_FOR_bcdsub_lt
+ || icode == CODE_FOR_bcdsub_eq
+ || icode == CODE_FOR_bcdsub_gt)
{
/* Only allow 1-bit unsigned literals. */
STRIP_NOPS (arg2);
@@ -12392,6 +12427,44 @@ rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
return const0_rtx;
}
}
+ else if (icode == CODE_FOR_dfp_ddedpd_dd
+ || icode == CODE_FOR_dfp_ddedpd_td)
+ {
+ /* Only allow 2-bit unsigned literals where the value is 0 or 2. */
+ STRIP_NOPS (arg0);
+ if (TREE_CODE (arg0) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg2) & ~0x3)
+ {
+ error ("argument 1 must be 0 or 2");
+ return const0_rtx;
+ }
+ }
+ else if (icode == CODE_FOR_dfp_denbcd_dd
+ || icode == CODE_FOR_dfp_denbcd_td)
+ {
+ /* Only allow 1-bit unsigned literals. */
+ STRIP_NOPS (arg0);
+ if (TREE_CODE (arg0) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg0) & ~0x1)
+ {
+ error ("argument 1 must be a 1-bit unsigned literal");
+ return const0_rtx;
+ }
+ }
+ else if (icode == CODE_FOR_dfp_dscli_dd
+ || icode == CODE_FOR_dfp_dscli_td
+ || icode == CODE_FOR_dfp_dscri_dd
+ || icode == CODE_FOR_dfp_dscri_td)
+ {
+ /* Only allow 6-bit unsigned literals. */
+ STRIP_NOPS (arg1);
+ if (TREE_CODE (arg1) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg1) & ~0x3f)
+ {
+ error ("argument 2 must be a 6-bit unsigned literal");
+ return const0_rtx;
+ }
+ }
else if (icode == CODE_FOR_crypto_vshasigmaw
|| icode == CODE_FOR_crypto_vshasigmad)
{
@@ -13483,6 +13556,16 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode)
error ("Builtin function %s requires the -mpaired option", name);
else if ((fnmask & RS6000_BTM_SPE) != 0)
error ("Builtin function %s requires the -mspe option", name);
+ else if ((fnmask & (RS6000_BTM_DFP | RS6000_BTM_P8_VECTOR))
+ == (RS6000_BTM_DFP | RS6000_BTM_P8_VECTOR))
+ error ("Builtin function %s requires the -mhard-dfp and"
+ "-mpower8-vector options", name);
+ else if ((fnmask & RS6000_BTM_DFP) != 0)
+ error ("Builtin function %s requires the -mhard-dfp option", name);
+ else if ((fnmask & RS6000_BTM_P8_VECTOR) != 0)
+ error ("Builtin function %s requires the -mpower8-vector option", name);
+ else if ((fnmask & RS6000_BTM_HARD_FLOAT) != 0)
+ error ("Builtin function %s requires the -mhard-float option", name);
else
error ("Builtin function %s is not supported with the current options",
name);
@@ -13671,7 +13754,10 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
return ret;
}
- gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
+ unsigned attr = rs6000_builtin_info[uns_fcode].attr & RS6000_BTC_TYPE_MASK;
+ gcc_assert (attr == RS6000_BTC_UNARY
+ || attr == RS6000_BTC_BINARY
+ || attr == RS6000_BTC_TERNARY);
/* Handle simple unary operations. */
d = bdesc_1arg;
@@ -13762,6 +13848,9 @@ rs6000_init_builtins (void)
uintTI_type_internal_node = unsigned_intTI_type_node;
float_type_internal_node = float_type_node;
double_type_internal_node = double_type_node;
+ long_double_type_internal_node = long_double_type_node;
+ dfloat64_type_internal_node = dfloat64_type_node;
+ dfloat128_type_internal_node = dfloat128_type_node;
void_type_internal_node = void_type_node;
/* Initialize the modes for builtin_function_type, mapping a machine mode to
@@ -13776,6 +13865,9 @@ rs6000_init_builtins (void)
builtin_mode_to_type[TImode][1] = unsigned_intTI_type_node;
builtin_mode_to_type[SFmode][0] = float_type_node;
builtin_mode_to_type[DFmode][0] = double_type_node;
+ builtin_mode_to_type[TFmode][0] = long_double_type_node;
+ builtin_mode_to_type[DDmode][0] = dfloat64_type_node;
+ builtin_mode_to_type[TDmode][0] = dfloat128_type_node;
builtin_mode_to_type[V1TImode][0] = V1TI_type_node;
builtin_mode_to_type[V1TImode][1] = unsigned_V1TI_type_node;
builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
@@ -14868,6 +14960,8 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
/* unsigned 1 argument functions. */
case CRYPTO_BUILTIN_VSBOX:
case P8V_BUILTIN_VGBBD:
+ case MISC_BUILTIN_CDTBCD:
+ case MISC_BUILTIN_CBCDTD:
h.uns_p[0] = 1;
h.uns_p[1] = 1;
break;
@@ -14886,6 +14980,11 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
case CRYPTO_BUILTIN_VPMSUMW:
case CRYPTO_BUILTIN_VPMSUMD:
case CRYPTO_BUILTIN_VPMSUM:
+ case MISC_BUILTIN_ADDG6S:
+ case MISC_BUILTIN_DIVWEU:
+ case MISC_BUILTIN_DIVWEUO:
+ case MISC_BUILTIN_DIVDEU:
+ case MISC_BUILTIN_DIVDEUO:
h.uns_p[0] = 1;
h.uns_p[1] = 1;
h.uns_p[2] = 1;
@@ -14947,9 +15046,18 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
/* signed args, unsigned return. */
case VSX_BUILTIN_XVCVDPUXDS_UNS:
case ALTIVEC_BUILTIN_FIXUNS_V4SF_V4SI:
+ case MISC_BUILTIN_UNPACK_TD:
+ case MISC_BUILTIN_UNPACK_V1TI:
h.uns_p[0] = 1;
break;
+ /* unsigned arguments for 128-bit pack instructions. */
+ case MISC_BUILTIN_PACK_TD:
+ case MISC_BUILTIN_PACK_V1TI:
+ h.uns_p[1] = 1;
+ h.uns_p[2] = 1;
+ break;
+
default:
break;
}
@@ -31203,6 +31311,8 @@ static struct rs6000_opt_mask const rs6000_builtin_mask_names[] =
{ "power8-vector", RS6000_BTM_P8_VECTOR, false, false },
{ "crypto", RS6000_BTM_CRYPTO, false, false },
{ "htm", RS6000_BTM_HTM, false, false },
+ { "hard-dfp", RS6000_BTM_DFP, false, false },
+ { "hard-float", RS6000_BTM_HARD_FLOAT, false, false },
};
/* Option variables that we want to support inside attribute((target)) and
diff --git a/gcc-4.9/gcc/config/rs6000/rs6000.h b/gcc-4.9/gcc/config/rs6000/rs6000.h
index 9ec3647fe..21330dc65 100644
--- a/gcc-4.9/gcc/config/rs6000/rs6000.h
+++ b/gcc-4.9/gcc/config/rs6000/rs6000.h
@@ -624,7 +624,8 @@ extern int rs6000_vector_align[];
|| TARGET_CMPB /* ISA 2.05 */ \
|| TARGET_POPCNTD /* ISA 2.06 */ \
|| TARGET_ALTIVEC \
- || TARGET_VSX)))
+ || TARGET_VSX \
+ || TARGET_HARD_FLOAT)))
/* E500 cores only support plain "sync", not lwsync. */
#define TARGET_NO_LWSYNC (rs6000_cpu == PROCESSOR_PPC8540 \
@@ -2516,6 +2517,8 @@ extern int frame_pointer_needed;
#define RS6000_BTM_FRSQRTES MASK_POPCNTB /* FRSQRTES instruction. */
#define RS6000_BTM_POPCNTD MASK_POPCNTD /* Target supports ISA 2.06. */
#define RS6000_BTM_CELL MASK_FPRND /* Target is cell powerpc. */
+#define RS6000_BTM_DFP MASK_DFP /* Decimal floating point. */
+#define RS6000_BTM_HARD_FLOAT MASK_SOFT_FLOAT /* Hardware floating point. */
#define RS6000_BTM_COMMON (RS6000_BTM_ALTIVEC \
| RS6000_BTM_VSX \
@@ -2527,7 +2530,9 @@ extern int frame_pointer_needed;
| RS6000_BTM_FRSQRTES \
| RS6000_BTM_HTM \
| RS6000_BTM_POPCNTD \
- | RS6000_BTM_CELL)
+ | RS6000_BTM_CELL \
+ | RS6000_BTM_DFP \
+ | RS6000_BTM_HARD_FLOAT)
/* Define builtin enum index. */
@@ -2622,6 +2627,9 @@ enum rs6000_builtin_type_index
RS6000_BTI_UINTTI, /* unsigned_intTI_type_node */
RS6000_BTI_float, /* float_type_node */
RS6000_BTI_double, /* double_type_node */
+ RS6000_BTI_long_double, /* long_double_type_node */
+ RS6000_BTI_dfloat64, /* dfloat64_type_node */
+ RS6000_BTI_dfloat128, /* dfloat128_type_node */
RS6000_BTI_void, /* void_type_node */
RS6000_BTI_MAX
};
@@ -2673,6 +2681,9 @@ enum rs6000_builtin_type_index
#define uintTI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTTI])
#define float_type_internal_node (rs6000_builtin_types[RS6000_BTI_float])
#define double_type_internal_node (rs6000_builtin_types[RS6000_BTI_double])
+#define long_double_type_internal_node (rs6000_builtin_types[RS6000_BTI_long_double])
+#define dfloat64_type_internal_node (rs6000_builtin_types[RS6000_BTI_dfloat64])
+#define dfloat128_type_internal_node (rs6000_builtin_types[RS6000_BTI_dfloat128])
#define void_type_internal_node (rs6000_builtin_types[RS6000_BTI_void])
extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX];
diff --git a/gcc-4.9/gcc/config/rs6000/rs6000.md b/gcc-4.9/gcc/config/rs6000/rs6000.md
index 64c9e7c10..e853bc4f9 100644
--- a/gcc-4.9/gcc/config/rs6000/rs6000.md
+++ b/gcc-4.9/gcc/config/rs6000/rs6000.md
@@ -125,6 +125,16 @@
UNSPEC_P8V_MTVSRD
UNSPEC_P8V_XXPERMDI
UNSPEC_P8V_RELOAD_FROM_VSX
+ UNSPEC_ADDG6S
+ UNSPEC_CDTBCD
+ UNSPEC_CBCDTD
+ UNSPEC_DIVE
+ UNSPEC_DIVEO
+ UNSPEC_DIVEU
+ UNSPEC_DIVEUO
+ UNSPEC_UNPACK_128BIT
+ UNSPEC_PACK_128BIT
+ UNSPEC_LSQ
])
;;
@@ -481,6 +491,10 @@
(V2DF "X,X,X,X,X")
(V1TI "X,X,X,X,X")])
+;; Mode attribute to give the correct type for integer divides
+(define_mode_attr idiv_ldiv [(SI "idiv")
+ (DI "ldiv")])
+
;; Start with fixed-point load and store insns. Here we put only the more
;; complex forms. Basic data transfer is done later.
@@ -2755,10 +2769,7 @@
(match_operand:GPR 2 "gpc_reg_operand" "r")))]
""
"div<wd>u %0,%1,%2"
- [(set (attr "type")
- (cond [(match_operand:SI 0 "" "")
- (const_string "idiv")]
- (const_string "ldiv")))])
+ [(set_attr "type" "<idiv_ldiv>")])
;; For powers of two we can do srai/aze for divide and then adjust for
@@ -2782,10 +2793,7 @@
(match_operand:GPR 2 "gpc_reg_operand" "r")))]
""
"div<wd> %0,%1,%2"
- [(set (attr "type")
- (cond [(match_operand:SI 0 "" "")
- (const_string "idiv")]
- (const_string "ldiv")))])
+ [(set_attr "type" "<idiv_ldiv>")])
(define_expand "mod<mode>3"
[(use (match_operand:GPR 0 "gpc_reg_operand" ""))
@@ -6534,6 +6542,49 @@
[(set_attr "length" "8")
(set_attr "type" "fpload")])
+;; Define the TImode operations that can be done in a small number
+;; of instructions. The & constraints are to prevent the register
+;; allocator from allocating registers that overlap with the inputs
+;; (for example, having an input in 7,8 and an output in 6,7). We
+;; also allow for the output being the same as one of the inputs.
+
+(define_insn "addti3"
+ [(set (match_operand:TI 0 "gpc_reg_operand" "=&r,&r,r,r")
+ (plus:TI (match_operand:TI 1 "gpc_reg_operand" "%r,r,0,0")
+ (match_operand:TI 2 "reg_or_short_operand" "r,I,r,I")))]
+ "TARGET_64BIT"
+{
+ if (WORDS_BIG_ENDIAN)
+ return (GET_CODE (operands[2])) != CONST_INT
+ ? \"addc %L0,%L1,%L2\;adde %0,%1,%2\"
+ : \"addic %L0,%L1,%2\;add%G2e %0,%1\";
+ else
+ return (GET_CODE (operands[2])) != CONST_INT
+ ? \"addc %0,%1,%2\;adde %L0,%L1,%L2\"
+ : \"addic %0,%1,%2\;add%G2e %L0,%L1\";
+}
+ [(set_attr "type" "two")
+ (set_attr "length" "8")])
+
+(define_insn "subti3"
+ [(set (match_operand:TI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
+ (minus:TI (match_operand:TI 1 "reg_or_short_operand" "r,I,0,r,I")
+ (match_operand:TI 2 "gpc_reg_operand" "r,r,r,0,0")))]
+ "TARGET_64BIT"
+{
+ if (WORDS_BIG_ENDIAN)
+ return (GET_CODE (operands[1]) != CONST_INT)
+ ? \"subfc %L0,%L2,%L1\;subfe %0,%2,%1\"
+ : \"subfic %L0,%L2,%1\;subf%G1e %0,%2\";
+ else
+ return (GET_CODE (operands[1]) != CONST_INT)
+ ? \"subfc %0,%2,%1\;subfe %L0,%L2,%L1\"
+ : \"subfic %0,%2,%1\;subf%G1e %L0,%L2\";
+}
+ [(set_attr "type" "two")
+ (set_attr "length" "8")])
+
+
;; Define the DImode operations that can be done in a small number
;; of instructions. The & constraints are to prevent the register
;; allocator from allocating registers that overlap with the inputs
@@ -9395,7 +9446,8 @@
(match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
"! TARGET_POWERPC64
&& ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
- || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
+ || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE
+ || (<MODE>mode == DDmode && TARGET_E500_DOUBLE))
&& (gpc_reg_operand (operands[0], <MODE>mode)
|| gpc_reg_operand (operands[1], <MODE>mode))"
"#"
@@ -15691,6 +15743,191 @@
})
+;; Miscellaneous ISA 2.06 (power7) instructions
+(define_insn "addg6s"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r")]
+ UNSPEC_ADDG6S))]
+ "TARGET_POPCNTD"
+ "addg6s %0,%1,%2"
+ [(set_attr "type" "integer")
+ (set_attr "length" "4")])
+
+(define_insn "cdtbcd"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
+ UNSPEC_CDTBCD))]
+ "TARGET_POPCNTD"
+ "cdtbcd %0,%1"
+ [(set_attr "type" "integer")
+ (set_attr "length" "4")])
+
+(define_insn "cbcdtd"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
+ UNSPEC_CBCDTD))]
+ "TARGET_POPCNTD"
+ "cbcdtd %0,%1"
+ [(set_attr "type" "integer")
+ (set_attr "length" "4")])
+
+(define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
+ UNSPEC_DIVEO
+ UNSPEC_DIVEU
+ UNSPEC_DIVEUO])
+
+(define_int_attr div_extend [(UNSPEC_DIVE "e")
+ (UNSPEC_DIVEO "eo")
+ (UNSPEC_DIVEU "eu")
+ (UNSPEC_DIVEUO "euo")])
+
+(define_insn "div<div_extend>_<mode>"
+ [(set (match_operand:GPR 0 "register_operand" "=r")
+ (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
+ (match_operand:GPR 2 "register_operand" "r")]
+ UNSPEC_DIV_EXTEND))]
+ "TARGET_POPCNTD"
+ "div<wd><div_extend> %0,%1,%2"
+ [(set_attr "type" "<idiv_ldiv>")])
+
+
+;; Pack/unpack 128-bit floating point types that take 2 scalar registers
+
+; Type of the 64-bit part when packing/unpacking 128-bit floating point types
+(define_mode_attr FP128_64 [(TF "DF") (TD "DI")])
+
+(define_expand "unpack<mode>"
+ [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
+ (unspec:<FP128_64>
+ [(match_operand:FMOVE128 1 "register_operand" "")
+ (match_operand:QI 2 "const_0_to_1_operand" "")]
+ UNSPEC_UNPACK_128BIT))]
+ ""
+ "")
+
+;; The Advance Toolchain 7.0-3 added private builtins: __builtin_longdouble_dw0
+;; and __builtin_longdouble_dw1 to optimize glibc. Add support for these
+;; builtins here.
+
+(define_expand "unpacktf_0"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (unspec:DF [(match_operand:TF 1 "register_operand" "")
+ (const_int 0)]
+ UNSPEC_UNPACK_128BIT))]
+ ""
+ "")
+
+(define_expand "unpacktf_1"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (unspec:DF [(match_operand:TF 1 "register_operand" "")
+ (const_int 1)]
+ UNSPEC_UNPACK_128BIT))]
+ ""
+ "")
+
+(define_insn_and_split "unpack<mode>_dm"
+ [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
+ (unspec:<FP128_64>
+ [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
+ (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
+ UNSPEC_UNPACK_128BIT))]
+ "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (match_dup 3))]
+{
+ unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
+
+ if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
+ {
+ emit_note (NOTE_INSN_DELETED);
+ DONE;
+ }
+
+ operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
+}
+ [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "unpack<mode>_nodm"
+ [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
+ (unspec:<FP128_64>
+ [(match_operand:FMOVE128 1 "register_operand" "d,d")
+ (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
+ UNSPEC_UNPACK_128BIT))]
+ "!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (match_dup 3))]
+{
+ unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
+
+ if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
+ {
+ emit_note (NOTE_INSN_DELETED);
+ DONE;
+ }
+
+ operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
+}
+ [(set_attr "type" "fp,fpstore")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "pack<mode>"
+ [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
+ (unspec:FMOVE128
+ [(match_operand:<FP128_64> 1 "register_operand" "0,d")
+ (match_operand:<FP128_64> 2 "register_operand" "d,d")]
+ UNSPEC_PACK_128BIT))]
+ ""
+ "@
+ fmr %L0,%2
+ #"
+ "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 4) (match_dup 2))]
+{
+ unsigned dest_hi = REGNO (operands[0]);
+ unsigned dest_lo = dest_hi + 1;
+
+ gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
+ gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
+
+ operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
+ operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
+}
+ [(set_attr "type" "fp,fp")
+ (set_attr "length" "4,8")])
+
+(define_insn "unpackv1ti"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (unspec:DI [(match_operand:V1TI 1 "register_operand" "0,wa")
+ (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
+ UNSPEC_UNPACK_128BIT))]
+ "TARGET_VSX"
+{
+ if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
+ return ASM_COMMENT_START " xxpermdi to same register";
+
+ operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
+ return "xxpermdi %x0,%x1,%x1,%3";
+}
+ [(set_attr "type" "vecperm")
+ (set_attr "length" "4")])
+
+(define_insn "packv1ti"
+ [(set (match_operand:V1TI 0 "register_operand" "=wa")
+ (unspec:V1TI
+ [(match_operand:DI 1 "register_operand" "d")
+ (match_operand:DI 2 "register_operand" "d")]
+ UNSPEC_PACK_128BIT))]
+ "TARGET_VSX"
+ "xxpermdi %x0,%x1,%x2,0"
+ [(set_attr "type" "vecperm")
+ (set_attr "length" "4")])
+
+
(include "sync.md")
(include "vector.md")
diff --git a/gcc-4.9/gcc/config/rs6000/sync.md b/gcc-4.9/gcc/config/rs6000/sync.md
index 7db439074..63152ed04 100644
--- a/gcc-4.9/gcc/config/rs6000/sync.md
+++ b/gcc-4.9/gcc/config/rs6000/sync.md
@@ -107,10 +107,17 @@
"isync"
[(set_attr "type" "isync")])
+;; Types that we should provide atomic instructions for.
+(define_mode_iterator AINT [QI
+ HI
+ SI
+ (DI "TARGET_POWERPC64")
+ (TI "TARGET_SYNC_TI")])
+
;; The control dependency used for load dependency described
;; in B.2.3 of the Power ISA 2.06B.
(define_insn "loadsync_<mode>"
- [(unspec_volatile:BLK [(match_operand:INT1 0 "register_operand" "r")]
+ [(unspec_volatile:BLK [(match_operand:AINT 0 "register_operand" "r")]
UNSPECV_ISYNC)
(clobber (match_scratch:CC 1 "=y"))]
""
@@ -118,18 +125,56 @@
[(set_attr "type" "isync")
(set_attr "length" "12")])
+(define_insn "load_quadpti"
+ [(set (match_operand:PTI 0 "quad_int_reg_operand" "=&r")
+ (unspec:PTI
+ [(match_operand:TI 1 "quad_memory_operand" "wQ")] UNSPEC_LSQ))]
+ "TARGET_SYNC_TI
+ && !reg_mentioned_p (operands[0], operands[1])"
+ "lq %0,%1"
+ [(set_attr "type" "load")
+ (set_attr "length" "4")])
+
(define_expand "atomic_load<mode>"
- [(set (match_operand:INT1 0 "register_operand" "") ;; output
- (match_operand:INT1 1 "memory_operand" "")) ;; memory
+ [(set (match_operand:AINT 0 "register_operand" "") ;; output
+ (match_operand:AINT 1 "memory_operand" "")) ;; memory
(use (match_operand:SI 2 "const_int_operand" ""))] ;; model
""
{
+ if (<MODE>mode == TImode && !TARGET_SYNC_TI)
+ FAIL;
+
enum memmodel model = (enum memmodel) INTVAL (operands[2]);
if (model == MEMMODEL_SEQ_CST)
emit_insn (gen_hwsync ());
- emit_move_insn (operands[0], operands[1]);
+ if (<MODE>mode != TImode)
+ emit_move_insn (operands[0], operands[1]);
+ else
+ {
+ rtx op0 = operands[0];
+ rtx op1 = operands[1];
+ rtx pti_reg = gen_reg_rtx (PTImode);
+
+ // Can't have indexed address for 'lq'
+ if (indexed_address (XEXP (op1, 0), TImode))
+ {
+ rtx old_addr = XEXP (op1, 0);
+ rtx new_addr = force_reg (Pmode, old_addr);
+ operands[1] = op1 = replace_equiv_address (op1, new_addr);
+ }
+
+ emit_insn (gen_load_quadpti (pti_reg, op1));
+
+ if (WORDS_BIG_ENDIAN)
+ emit_move_insn (op0, gen_lowpart (TImode, pti_reg));
+ else
+ {
+ emit_move_insn (gen_lowpart (DImode, op0), gen_highpart (DImode, pti_reg));
+ emit_move_insn (gen_highpart (DImode, op0), gen_lowpart (DImode, pti_reg));
+ }
+ }
switch (model)
{
@@ -146,12 +191,24 @@
DONE;
})
+(define_insn "store_quadpti"
+ [(set (match_operand:PTI 0 "quad_memory_operand" "=wQ")
+ (unspec:PTI
+ [(match_operand:PTI 1 "quad_int_reg_operand" "r")] UNSPEC_LSQ))]
+ "TARGET_SYNC_TI"
+ "stq %1,%0"
+ [(set_attr "type" "store")
+ (set_attr "length" "4")])
+
(define_expand "atomic_store<mode>"
- [(set (match_operand:INT1 0 "memory_operand" "") ;; memory
- (match_operand:INT1 1 "register_operand" "")) ;; input
+ [(set (match_operand:AINT 0 "memory_operand" "") ;; memory
+ (match_operand:AINT 1 "register_operand" "")) ;; input
(use (match_operand:SI 2 "const_int_operand" ""))] ;; model
""
{
+ if (<MODE>mode == TImode && !TARGET_SYNC_TI)
+ FAIL;
+
enum memmodel model = (enum memmodel) INTVAL (operands[2]);
switch (model)
{
@@ -166,7 +223,33 @@
default:
gcc_unreachable ();
}
- emit_move_insn (operands[0], operands[1]);
+ if (<MODE>mode != TImode)
+ emit_move_insn (operands[0], operands[1]);
+ else
+ {
+ rtx op0 = operands[0];
+ rtx op1 = operands[1];
+ rtx pti_reg = gen_reg_rtx (PTImode);
+
+ // Can't have indexed address for 'stq'
+ if (indexed_address (XEXP (op0, 0), TImode))
+ {
+ rtx old_addr = XEXP (op0, 0);
+ rtx new_addr = force_reg (Pmode, old_addr);
+ operands[0] = op0 = replace_equiv_address (op0, new_addr);
+ }
+
+ if (WORDS_BIG_ENDIAN)
+ emit_move_insn (pti_reg, gen_lowpart (PTImode, op1));
+ else
+ {
+ emit_move_insn (gen_lowpart (DImode, pti_reg), gen_highpart (DImode, op1));
+ emit_move_insn (gen_highpart (DImode, pti_reg), gen_lowpart (DImode, op1));
+ }
+
+ emit_insn (gen_store_quadpti (gen_lowpart (PTImode, op0), pti_reg));
+ }
+
DONE;
})
@@ -180,14 +263,6 @@
SI
(DI "TARGET_POWERPC64")])
-;; Types that we should provide atomic instructions for.
-
-(define_mode_iterator AINT [QI
- HI
- SI
- (DI "TARGET_POWERPC64")
- (TI "TARGET_SYNC_TI")])
-
(define_insn "load_locked<mode>"
[(set (match_operand:ATOMIC 0 "int_reg_operand" "=r")
(unspec_volatile:ATOMIC
diff --git a/gcc-4.9/gcc/config/rs6000/vsx.md b/gcc-4.9/gcc/config/rs6000/vsx.md
index d83cdc3df..23d85ab06 100644
--- a/gcc-4.9/gcc/config/rs6000/vsx.md
+++ b/gcc-4.9/gcc/config/rs6000/vsx.md
@@ -1891,7 +1891,12 @@
(parallel [(const_int 0) (const_int 4)
(const_int 1) (const_int 5)])))]
"VECTOR_MEM_VSX_P (<MODE>mode)"
- "xxmrghw %x0,%x1,%x2"
+{
+ if (BYTES_BIG_ENDIAN)
+ return "xxmrghw %x0,%x1,%x2";
+ else
+ return "xxmrglw %x0,%x2,%x1";
+}
[(set_attr "type" "vecperm")])
(define_insn "vsx_xxmrglw_<mode>"
@@ -1903,7 +1908,12 @@
(parallel [(const_int 2) (const_int 6)
(const_int 3) (const_int 7)])))]
"VECTOR_MEM_VSX_P (<MODE>mode)"
- "xxmrglw %x0,%x1,%x2"
+{
+ if (BYTES_BIG_ENDIAN)
+ return "xxmrglw %x0,%x1,%x2";
+ else
+ return "xxmrghw %x0,%x2,%x1";
+}
[(set_attr "type" "vecperm")])
;; Shift left double by word immediate
diff --git a/gcc-4.9/gcc/config/sh/sh.c b/gcc-4.9/gcc/config/sh/sh.c
index 6d909c79e..12724a20d 100644
--- a/gcc-4.9/gcc/config/sh/sh.c
+++ b/gcc-4.9/gcc/config/sh/sh.c
@@ -19,6 +19,10 @@ 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/>. */
+#include <sstream>
+#include <vector>
+#include <algorithm>
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
@@ -70,10 +74,6 @@ along with GCC; see the file COPYING3. If not see
#include "pass_manager.h"
#include "context.h"
-#include <sstream>
-#include <vector>
-#include <algorithm>
-
int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch;
/* These are some macros to abstract register modes. */
diff --git a/gcc-4.9/gcc/config/sparc/sparc-protos.h b/gcc-4.9/gcc/config/sparc/sparc-protos.h
index 1d63e4640..ee2091bb8 100644
--- a/gcc-4.9/gcc/config/sparc/sparc-protos.h
+++ b/gcc-4.9/gcc/config/sparc/sparc-protos.h
@@ -69,7 +69,6 @@ extern bool sparc_expand_move (enum machine_mode, rtx *);
extern void sparc_emit_set_symbolic_const64 (rtx, rtx, rtx);
extern int sparc_splitdi_legitimate (rtx, rtx);
extern int sparc_split_regreg_legitimate (rtx, rtx);
-extern int sparc_absnegfloat_split_legitimate (rtx, rtx);
extern const char *output_ubranch (rtx, rtx);
extern const char *output_cbranch (rtx, rtx, int, int, int, rtx);
extern const char *output_return (rtx);
diff --git a/gcc-4.9/gcc/config/sparc/sparc.c b/gcc-4.9/gcc/config/sparc/sparc.c
index f52b9761a..5b00cca47 100644
--- a/gcc-4.9/gcc/config/sparc/sparc.c
+++ b/gcc-4.9/gcc/config/sparc/sparc.c
@@ -8539,22 +8539,6 @@ sparc_split_regreg_legitimate (rtx reg1, rtx reg2)
return 0;
}
-/* Return 1 if x and y are some kind of REG and they refer to
- different hard registers. This test is guaranteed to be
- run after reload. */
-
-int
-sparc_absnegfloat_split_legitimate (rtx x, rtx y)
-{
- if (GET_CODE (x) != REG)
- return 0;
- if (GET_CODE (y) != REG)
- return 0;
- if (REGNO (x) == REGNO (y))
- return 0;
- return 1;
-}
-
/* Return 1 if REGNO (reg1) is even and REGNO (reg1) == REGNO (reg2) - 1.
This makes them candidates for using ldd and std insns.
diff --git a/gcc-4.9/gcc/config/sparc/sparc.md b/gcc-4.9/gcc/config/sparc/sparc.md
index 8b6c647fc..76c331597 100644
--- a/gcc-4.9/gcc/config/sparc/sparc.md
+++ b/gcc-4.9/gcc/config/sparc/sparc.md
@@ -424,6 +424,10 @@
(define_attr "fptype" "single,double"
(const_string "single"))
+;; FP precision specific to the UT699.
+(define_attr "fptype_ut699" "none,single"
+ (const_string "none"))
+
;; UltraSPARC-III integer load type.
(define_attr "us3load_type" "2cycle,3cycle"
(const_string "2cycle"))
@@ -464,7 +468,8 @@
(const_string "false")
(and (eq_attr "fix_ut699" "true")
(and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts")
- (eq_attr "fptype" "single")))
+ (ior (eq_attr "fptype" "single")
+ (eq_attr "fptype_ut699" "single"))))
(const_string "false")
(eq_attr "length" "1")
(const_string "true")
@@ -3455,7 +3460,8 @@
"TARGET_FPU"
"fdtos\t%1, %0"
[(set_attr "type" "fp")
- (set_attr "fptype" "double")])
+ (set_attr "fptype" "double")
+ (set_attr "fptype_ut699" "single")])
(define_expand "trunctfsf2"
[(set (match_operand:SF 0 "register_operand" "")
@@ -3496,7 +3502,7 @@
"TARGET_FPU"
"fitos\t%1, %0"
[(set_attr "type" "fp")
- (set_attr "fptype" "double")])
+ (set_attr "fptype" "single")])
(define_insn "floatsidf2"
[(set (match_operand:DF 0 "register_operand" "=e")
@@ -3583,7 +3589,7 @@
"TARGET_FPU"
"fstoi\t%1, %0"
[(set_attr "type" "fp")
- (set_attr "fptype" "double")])
+ (set_attr "fptype" "single")])
(define_insn "fix_truncdfsi2"
[(set (match_operand:SI 0 "register_operand" "=f")
@@ -3591,7 +3597,8 @@
"TARGET_FPU"
"fdtoi\t%1, %0"
[(set_attr "type" "fp")
- (set_attr "fptype" "double")])
+ (set_attr "fptype" "double")
+ (set_attr "fptype_ut699" "single")])
(define_expand "fix_trunctfsi2"
[(set (match_operand:SI 0 "register_operand" "")
@@ -5554,53 +5561,52 @@
[(set_attr "type" "fpdivs")])
(define_expand "negtf2"
- [(set (match_operand:TF 0 "register_operand" "=e,e")
- (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
+ [(set (match_operand:TF 0 "register_operand" "")
+ (neg:TF (match_operand:TF 1 "register_operand" "")))]
"TARGET_FPU"
"")
-(define_insn_and_split "*negtf2_notv9"
- [(set (match_operand:TF 0 "register_operand" "=e,e")
- (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
- ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
- "TARGET_FPU
- && ! TARGET_V9"
- "@
- fnegs\t%0, %0
- #"
- "&& reload_completed
- && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
- [(set (match_dup 2) (neg:SF (match_dup 3)))
- (set (match_dup 4) (match_dup 5))
- (set (match_dup 6) (match_dup 7))]
- "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
- operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
- operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
- operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
- operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
- operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
- [(set_attr "type" "fpmove,*")
- (set_attr "length" "*,2")])
-
-(define_insn_and_split "*negtf2_v9"
- [(set (match_operand:TF 0 "register_operand" "=e,e")
- (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
- ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
- "TARGET_FPU && TARGET_V9"
- "@
- fnegd\t%0, %0
- #"
- "&& reload_completed
- && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
- [(set (match_dup 2) (neg:DF (match_dup 3)))
- (set (match_dup 4) (match_dup 5))]
- "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
- operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
- operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
- operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
- [(set_attr "type" "fpmove,*")
- (set_attr "length" "*,2")
- (set_attr "fptype" "double")])
+(define_insn "*negtf2_hq"
+ [(set (match_operand:TF 0 "register_operand" "=e")
+ (neg:TF (match_operand:TF 1 "register_operand" "e")))]
+ "TARGET_FPU && TARGET_HARD_QUAD"
+ "fnegq\t%1, %0"
+ [(set_attr "type" "fpmove")])
+
+(define_insn_and_split "*negtf2"
+ [(set (match_operand:TF 0 "register_operand" "=e")
+ (neg:TF (match_operand:TF 1 "register_operand" "e")))]
+ "TARGET_FPU && !TARGET_HARD_QUAD"
+ "#"
+ "&& reload_completed"
+ [(clobber (const_int 0))]
+{
+ rtx set_dest = operands[0];
+ rtx set_src = operands[1];
+ rtx dest1, dest2;
+ rtx src1, src2;
+
+ dest1 = gen_df_reg (set_dest, 0);
+ dest2 = gen_df_reg (set_dest, 1);
+ src1 = gen_df_reg (set_src, 0);
+ src2 = gen_df_reg (set_src, 1);
+
+ /* Now emit using the real source and destination we found, swapping
+ the order if we detect overlap. */
+ if (reg_overlap_mentioned_p (dest1, src2))
+ {
+ emit_insn (gen_movdf (dest2, src2));
+ emit_insn (gen_negdf2 (dest1, src1));
+ }
+ else
+ {
+ emit_insn (gen_negdf2 (dest1, src1));
+ if (REGNO (dest2) != REGNO (src2))
+ emit_insn (gen_movdf (dest2, src2));
+ }
+ DONE;
+}
+ [(set_attr "length" "2")])
(define_expand "negdf2"
[(set (match_operand:DF 0 "register_operand" "")
@@ -5609,22 +5615,39 @@
"")
(define_insn_and_split "*negdf2_notv9"
- [(set (match_operand:DF 0 "register_operand" "=e,e")
- (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
- "TARGET_FPU && ! TARGET_V9"
- "@
- fnegs\t%0, %0
- #"
- "&& reload_completed
- && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
- [(set (match_dup 2) (neg:SF (match_dup 3)))
- (set (match_dup 4) (match_dup 5))]
- "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
- operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
- operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
- operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
- [(set_attr "type" "fpmove,*")
- (set_attr "length" "*,2")])
+ [(set (match_operand:DF 0 "register_operand" "=e")
+ (neg:DF (match_operand:DF 1 "register_operand" "e")))]
+ "TARGET_FPU && !TARGET_V9"
+ "#"
+ "&& reload_completed"
+ [(clobber (const_int 0))]
+{
+ rtx set_dest = operands[0];
+ rtx set_src = operands[1];
+ rtx dest1, dest2;
+ rtx src1, src2;
+
+ dest1 = gen_highpart (SFmode, set_dest);
+ dest2 = gen_lowpart (SFmode, set_dest);
+ src1 = gen_highpart (SFmode, set_src);
+ src2 = gen_lowpart (SFmode, set_src);
+
+ /* Now emit using the real source and destination we found, swapping
+ the order if we detect overlap. */
+ if (reg_overlap_mentioned_p (dest1, src2))
+ {
+ emit_insn (gen_movsf (dest2, src2));
+ emit_insn (gen_negsf2 (dest1, src1));
+ }
+ else
+ {
+ emit_insn (gen_negsf2 (dest1, src1));
+ if (REGNO (dest2) != REGNO (src2))
+ emit_insn (gen_movsf (dest2, src2));
+ }
+ DONE;
+}
+ [(set_attr "length" "2")])
(define_insn "*negdf2_v9"
[(set (match_operand:DF 0 "register_operand" "=e")
@@ -5647,56 +5670,47 @@
"TARGET_FPU"
"")
-(define_insn_and_split "*abstf2_notv9"
- [(set (match_operand:TF 0 "register_operand" "=e,e")
- (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
- ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
- "TARGET_FPU && ! TARGET_V9"
- "@
- fabss\t%0, %0
- #"
- "&& reload_completed
- && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
- [(set (match_dup 2) (abs:SF (match_dup 3)))
- (set (match_dup 4) (match_dup 5))
- (set (match_dup 6) (match_dup 7))]
- "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
- operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
- operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
- operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
- operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
- operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
- [(set_attr "type" "fpmove,*")
- (set_attr "length" "*,2")])
-
-(define_insn "*abstf2_hq_v9"
- [(set (match_operand:TF 0 "register_operand" "=e,e")
- (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
- "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
- "@
- fabsd\t%0, %0
- fabsq\t%1, %0"
- [(set_attr "type" "fpmove")
- (set_attr "fptype" "double,*")])
+(define_insn "*abstf2_hq"
+ [(set (match_operand:TF 0 "register_operand" "=e")
+ (abs:TF (match_operand:TF 1 "register_operand" "e")))]
+ "TARGET_FPU && TARGET_HARD_QUAD"
+ "fabsq\t%1, %0"
+ [(set_attr "type" "fpmove")])
-(define_insn_and_split "*abstf2_v9"
- [(set (match_operand:TF 0 "register_operand" "=e,e")
- (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
- "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
- "@
- fabsd\t%0, %0
- #"
- "&& reload_completed
- && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
- [(set (match_dup 2) (abs:DF (match_dup 3)))
- (set (match_dup 4) (match_dup 5))]
- "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
- operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
- operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
- operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
- [(set_attr "type" "fpmove,*")
- (set_attr "length" "*,2")
- (set_attr "fptype" "double,*")])
+(define_insn_and_split "*abstf2"
+ [(set (match_operand:TF 0 "register_operand" "=e")
+ (abs:TF (match_operand:TF 1 "register_operand" "e")))]
+ "TARGET_FPU && !TARGET_HARD_QUAD"
+ "#"
+ "&& reload_completed"
+ [(clobber (const_int 0))]
+{
+ rtx set_dest = operands[0];
+ rtx set_src = operands[1];
+ rtx dest1, dest2;
+ rtx src1, src2;
+
+ dest1 = gen_df_reg (set_dest, 0);
+ dest2 = gen_df_reg (set_dest, 1);
+ src1 = gen_df_reg (set_src, 0);
+ src2 = gen_df_reg (set_src, 1);
+
+ /* Now emit using the real source and destination we found, swapping
+ the order if we detect overlap. */
+ if (reg_overlap_mentioned_p (dest1, src2))
+ {
+ emit_insn (gen_movdf (dest2, src2));
+ emit_insn (gen_absdf2 (dest1, src1));
+ }
+ else
+ {
+ emit_insn (gen_absdf2 (dest1, src1));
+ if (REGNO (dest2) != REGNO (src2))
+ emit_insn (gen_movdf (dest2, src2));
+ }
+ DONE;
+}
+ [(set_attr "length" "2")])
(define_expand "absdf2"
[(set (match_operand:DF 0 "register_operand" "")
@@ -5705,22 +5719,39 @@
"")
(define_insn_and_split "*absdf2_notv9"
- [(set (match_operand:DF 0 "register_operand" "=e,e")
- (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
- "TARGET_FPU && ! TARGET_V9"
- "@
- fabss\t%0, %0
- #"
- "&& reload_completed
- && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
- [(set (match_dup 2) (abs:SF (match_dup 3)))
- (set (match_dup 4) (match_dup 5))]
- "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
- operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
- operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
- operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
- [(set_attr "type" "fpmove,*")
- (set_attr "length" "*,2")])
+ [(set (match_operand:DF 0 "register_operand" "=e")
+ (abs:DF (match_operand:DF 1 "register_operand" "e")))]
+ "TARGET_FPU && !TARGET_V9"
+ "#"
+ "&& reload_completed"
+ [(clobber (const_int 0))]
+{
+ rtx set_dest = operands[0];
+ rtx set_src = operands[1];
+ rtx dest1, dest2;
+ rtx src1, src2;
+
+ dest1 = gen_highpart (SFmode, set_dest);
+ dest2 = gen_lowpart (SFmode, set_dest);
+ src1 = gen_highpart (SFmode, set_src);
+ src2 = gen_lowpart (SFmode, set_src);
+
+ /* Now emit using the real source and destination we found, swapping
+ the order if we detect overlap. */
+ if (reg_overlap_mentioned_p (dest1, src2))
+ {
+ emit_insn (gen_movsf (dest2, src2));
+ emit_insn (gen_abssf2 (dest1, src1));
+ }
+ else
+ {
+ emit_insn (gen_abssf2 (dest1, src1));
+ if (REGNO (dest2) != REGNO (src2))
+ emit_insn (gen_movsf (dest2, src2));
+ }
+ DONE;
+}
+ [(set_attr "length" "2")])
(define_insn "*absdf2_v9"
[(set (match_operand:DF 0 "register_operand" "=e")
@@ -5795,19 +5826,6 @@
}
[(set_attr "type" "shift")])
-(define_insn "*ashlsi3_extend"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (ashift:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith_operand" "rI"))))]
- "TARGET_ARCH64"
-{
- if (GET_CODE (operands[2]) == CONST_INT)
- operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
- return "sll\t%1, %2, %0";
-}
- [(set_attr "type" "shift")])
-
(define_expand "ashldi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (match_operand:DI 1 "register_operand" "r")
diff --git a/gcc-4.9/gcc/config/sparc/sparc.opt b/gcc-4.9/gcc/config/sparc/sparc.opt
index c02aec59f..64e40955a 100644
--- a/gcc-4.9/gcc/config/sparc/sparc.opt
+++ b/gcc-4.9/gcc/config/sparc/sparc.opt
@@ -113,6 +113,10 @@ mrelax
Target
Optimize tail call instructions in assembler and linker
+muser-mode
+Target Report Mask(USER_MODE)
+Do not generate code that can only run in supervisor mode
+
mcpu=
Target RejectNegative Joined Var(sparc_cpu_and_features) Enum(sparc_processor_type) Init(PROCESSOR_V7)
Use features of and schedule code for given CPU
diff --git a/gcc-4.9/gcc/config/sparc/sync.md b/gcc-4.9/gcc/config/sparc/sync.md
index fd5691f73..e6e237f25 100644
--- a/gcc-4.9/gcc/config/sparc/sync.md
+++ b/gcc-4.9/gcc/config/sparc/sync.md
@@ -200,10 +200,27 @@
[(match_operand:I48MODE 2 "register_operand" "r")
(match_operand:I48MODE 3 "register_operand" "0")]
UNSPECV_CAS))]
- "(TARGET_V9 || TARGET_LEON3) && (<MODE>mode != DImode || TARGET_ARCH64)"
+ "TARGET_V9 && (<MODE>mode != DImode || TARGET_ARCH64)"
"cas<modesuffix>\t%1, %2, %0"
[(set_attr "type" "multi")])
+(define_insn "*atomic_compare_and_swap_leon3_1"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operand:SI 1 "mem_noofs_operand" "+w"))
+ (set (match_dup 1)
+ (unspec_volatile:SI
+ [(match_operand:SI 2 "register_operand" "r")
+ (match_operand:SI 3 "register_operand" "0")]
+ UNSPECV_CAS))]
+ "TARGET_LEON3"
+{
+ if (TARGET_USER_MODE)
+ return "casa\t%1 0xa, %2, %0"; /* ASI for user data space. */
+ else
+ return "casa\t%1 0xb, %2, %0"; /* ASI for supervisor data space. */
+}
+ [(set_attr "type" "multi")])
+
(define_insn "*atomic_compare_and_swapdi_v8plus"
[(set (match_operand:DI 0 "register_operand" "=h")
(match_operand:DI 1 "mem_noofs_operand" "+w"))