summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arm/aarch-common.c8
-rw-r--r--gcc/config/arm/arm.c8
-rw-r--r--gcc/config/arm/arm.md12
-rw-r--r--gcc/config/arm/predicates.md3
-rw-r--r--gcc/config/avr/avr.c6
-rw-r--r--gcc/config/i386/i386-c.c7
-rw-r--r--gcc/config/i386/i386.md13
-rw-r--r--gcc/config/m68k/m68k.md4
-rw-r--r--gcc/config/rs6000/altivec.md112
-rw-r--r--gcc/config/rs6000/dfp.md69
-rw-r--r--gcc/config/rs6000/predicates.md5
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def135
-rw-r--r--gcc/config/rs6000/rs6000.c82
-rw-r--r--gcc/config/rs6000/rs6000.h10
-rw-r--r--gcc/config/rs6000/rs6000.md208
-rw-r--r--gcc/config/sol2.h1
-rw-r--r--gcc/config/sparc/sparc.md13
-rw-r--r--gcc/config/sparc/sparc.opt4
-rw-r--r--gcc/config/sparc/sync.md19
19 files changed, 669 insertions, 50 deletions
diff --git a/gcc/config/arm/aarch-common.c b/gcc/config/arm/aarch-common.c
index 884d4b37fac..d31191ab9e7 100644
--- a/gcc/config/arm/aarch-common.c
+++ b/gcc/config/arm/aarch-common.c
@@ -195,14 +195,18 @@ bool
aarch_rev16_shright_mask_imm_p (rtx val, enum machine_mode mode)
{
return CONST_INT_P (val)
- && INTVAL (val) == trunc_int_for_mode (0xff00ff00ff00ff, mode);
+ && INTVAL (val)
+ == trunc_int_for_mode (HOST_WIDE_INT_C (0xff00ff00ff00ff),
+ mode);
}
bool
aarch_rev16_shleft_mask_imm_p (rtx val, enum machine_mode mode)
{
return CONST_INT_P (val)
- && INTVAL (val) == trunc_int_for_mode (0xff00ff00ff00ff00, mode);
+ && INTVAL (val)
+ == trunc_int_for_mode (HOST_WIDE_INT_C (0xff00ff00ff00ff00),
+ mode);
}
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 8ca945f1a67..1e44080d601 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -1710,7 +1710,8 @@ const struct tune_params arm_cortex_a8_tune =
false, /* Prefer LDRD/STRD. */
{true, true}, /* Prefer non short circuit. */
&arm_default_vec_cost, /* Vectorizer costs. */
- false /* Prefer Neon for 64-bits bitops. */
+ false, /* Prefer Neon for 64-bits bitops. */
+ false, false /* Prefer 32-bit encodings. */
};
const struct tune_params arm_cortex_a7_tune =
@@ -6216,11 +6217,6 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
if (TARGET_VXWORKS_RTP && flag_pic && !targetm.binds_local_p (decl))
return false;
- /* Cannot tail-call to long calls, since these are out of range of
- a branch instruction. */
- if (decl && arm_is_long_call_p (decl))
- return false;
-
/* If we are interworking and the function is not declared static
then we can't tail-call it unless we know that it exists in this
compilation unit (since it might be a Thumb routine). */
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 8a949b929fa..97753ce1e98 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -9367,8 +9367,10 @@
"TARGET_32BIT"
"
{
- if (!REG_P (XEXP (operands[0], 0))
- && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
+ if ((!REG_P (XEXP (operands[0], 0))
+ && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
+ || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
+ && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
if (operands[2] == NULL_RTX)
@@ -9385,8 +9387,10 @@
"TARGET_32BIT"
"
{
- if (!REG_P (XEXP (operands[1], 0)) &&
- (GET_CODE (XEXP (operands[1],0)) != SYMBOL_REF))
+ if ((!REG_P (XEXP (operands[1], 0))
+ && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
+ || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
+ && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
if (operands[3] == NULL_RTX)
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index 6273e8820c6..d74fcb31bc7 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -681,5 +681,6 @@
(match_code "reg" "0")))
(define_predicate "call_insn_operand"
- (ior (match_code "symbol_ref")
+ (ior (and (match_code "symbol_ref")
+ (match_test "!arm_is_long_call_p (SYMBOL_REF_DECL (op))"))
(match_operand 0 "s_register_operand")))
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 25075b2f4b3..0fa7f6633e2 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -290,6 +290,12 @@ avr_to_int_mode (rtx x)
static void
avr_option_override (void)
{
+ /* Disable -fdelete-null-pointer-checks option for AVR target.
+ This option compiler assumes that dereferencing of a null pointer
+ would halt the program. For AVR this assumption is not true and
+ programs can safely dereference null pointers. Changes made by this
+ option may not work properly for AVR. So disable this option. */
+
flag_delete_null_pointer_checks = 0;
/* caller-save.c looks for call-clobbered hard registers that are assigned
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index c9977bf2b0e..2c31dc8062d 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -518,6 +518,13 @@ ix86_target_macros (void)
if (TARGET_LONG_DOUBLE_128)
cpp_define (parse_in, "__LONG_DOUBLE_128__");
+ if (TARGET_128BIT_LONG_DOUBLE)
+ cpp_define (parse_in, "__SIZEOF_FLOAT80__=16");
+ else
+ cpp_define (parse_in, "__SIZEOF_FLOAT80__=12");
+
+ cpp_define (parse_in, "__SIZEOF_FLOAT128__=16");
+
cpp_define_formatted (parse_in, "__ATOMIC_HLE_ACQUIRE=%d", IX86_HLE_ACQUIRE);
cpp_define_formatted (parse_in, "__ATOMIC_HLE_RELEASE=%d", IX86_HLE_RELEASE);
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 25e2e93e317..fde0a93e68f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -3201,7 +3201,7 @@
(const_string "1")
(const_string "*")))
(set (attr "mode")
- (cond [(eq_attr "alternative" "3,4,9,10,13,14,15")
+ (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
(const_string "SI")
(eq_attr "alternative" "11")
(const_string "DI")
@@ -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/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index e61048b4d0b..72c11f592db 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -1868,9 +1868,11 @@
;; Maybe there is a way to make that the general case, by forcing the
;; result of the SI tree to be in the lower register of the DI target
+;; Don't allow memory for operand 1 as that would require an earlyclobber
+;; which results in worse code
(define_insn "extendplussidi"
[(set (match_operand:DI 0 "register_operand" "=d")
- (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rmn")
+ (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rn")
(match_operand:SI 2 "general_operand" "rmn"))))]
""
{
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 674cb40bf7a..a8cfcb739ea 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/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/config/rs6000/dfp.md b/gcc/config/rs6000/dfp.md
index 8e99bc0d787..40e27e77d23 100644
--- a/gcc/config/rs6000/dfp.md
+++ b/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/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 2ed1d4a184d..1616b888c9c 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/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")
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 83351691fa5..16793f501e7 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/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_ALWAYS, /* 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_ALWAYS, /* 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/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index bab79df7760..0c983f9a105 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3038,7 +3038,8 @@ 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));
}
/* Override command line options. Mostly we process the processor type and
@@ -12396,7 +12397,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);
@@ -12407,6 +12416,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)
{
@@ -13496,6 +13543,14 @@ 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
error ("Builtin function %s is not supported with the current options",
name);
@@ -13775,6 +13830,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
@@ -13789,6 +13847,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;
@@ -14881,6 +14942,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;
@@ -14899,6 +14962,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;
@@ -14960,9 +15028,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;
}
@@ -31226,6 +31303,7 @@ 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 },
};
/* Option variables that we want to support inside attribute((target)) and
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 9d0d61c74ea..2e677d5936e 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2516,6 +2516,7 @@ 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_COMMON (RS6000_BTM_ALTIVEC \
| RS6000_BTM_VSX \
@@ -2527,7 +2528,8 @@ extern int frame_pointer_needed;
| RS6000_BTM_FRSQRTES \
| RS6000_BTM_HTM \
| RS6000_BTM_POPCNTD \
- | RS6000_BTM_CELL)
+ | RS6000_BTM_CELL \
+ | RS6000_BTM_DFP)
/* Define builtin enum index. */
@@ -2622,6 +2624,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 +2678,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/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index cdefc8f78c4..937eabf3727 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -125,6 +125,15 @@
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
])
;;
@@ -481,6 +490,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 +2768,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 +2792,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" ""))
@@ -15735,6 +15742,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/config/sol2.h b/gcc/config/sol2.h
index 2a657db59c1..a21c953b035 100644
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -115,7 +115,6 @@ along with GCC; see the file COPYING3. If not see
#define LIB_SPEC \
"%{!symbolic:\
%{pthreads|pthread:-lpthread} \
- %{pthreads|pthread|fprofile-generate*:" LIB_TLS_SPEC "} \
%{p|pg:-ldl} -lc}"
#ifndef CROSS_DIRECTORY_STRUCTURE
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 8b6c647fc00..e2a4669e05d 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -5795,19 +5795,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/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index c02aec59f06..64e40955a53 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/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/config/sparc/sync.md b/gcc/config/sparc/sync.md
index fd5691f73be..e6e237f256f 100644
--- a/gcc/config/sparc/sync.md
+++ b/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"))