diff options
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/arm/aarch-common.c | 8 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 8 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 12 | ||||
-rw-r--r-- | gcc/config/arm/predicates.md | 3 | ||||
-rw-r--r-- | gcc/config/avr/avr.c | 6 | ||||
-rw-r--r-- | gcc/config/i386/i386-c.c | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 13 | ||||
-rw-r--r-- | gcc/config/m68k/m68k.md | 4 | ||||
-rw-r--r-- | gcc/config/rs6000/altivec.md | 112 | ||||
-rw-r--r-- | gcc/config/rs6000/dfp.md | 69 | ||||
-rw-r--r-- | gcc/config/rs6000/predicates.md | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-builtin.def | 135 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 82 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 10 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 208 | ||||
-rw-r--r-- | gcc/config/sol2.h | 1 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 13 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.opt | 4 | ||||
-rw-r--r-- | gcc/config/sparc/sync.md | 19 |
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")) |