diff options
Diffstat (limited to 'gcc-4.9/gcc/config/sparc')
-rw-r--r-- | gcc-4.9/gcc/config/sparc/sparc-protos.h | 1 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/sparc/sparc.c | 16 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/sparc/sparc.md | 304 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/sparc/sparc.opt | 4 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/sparc/sync.md | 19 |
5 files changed, 183 insertions, 161 deletions
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")) |