|
View:
New views
6 Messages
—
Rating Filter:
Alert me
|
|
|
{RFA] PowerPC e500mc64 core supportFreescale would like to contribute this patch to gcc.
It enables gcc for the new Freescale 64 bit core. It creates a pipeline description, and set proper default flags for the e500mc64 core. It also create new patterns for 64 bit isel instruction generation. The patch was generated from subversion revision 153598 from 2009-10-27 The patch was regression tested for both 603e and 970 targets under these conditions: --enable-checking --disable-decimal-float --enable-languages=c,c++,fortran We thanks in advance for your time to review and commit the patch Regards, Edmar 2009-11-03 Edmar Wienskoski edmar@... * config.gcc (cpu_is_64bit): Add new core e500mc64. (powerpc*-*-*): Add new core e500mc64. * config/rs6000/e500mc64.md: New file. * config/rs6000/rs6000.c (processor_costs): Add new costs for e500mc64. (rs6000_override_options): Add e500mc64 case to processor_target_table. Altivec and Spe options not allowed with e500mc64. Disable string instructions for e500mc64. Enable branch targets alignment for both e500mc and e500mc64. Initialize rs6000_cost for e500mc64. (rs6000_emit_sISEL): New function. (rs6000_emit_int_cmove): Fix mode of 64 bit isel pattern generation. (rs6000_issue_rate): Set issue rate for e500mc64. (rs6000_rtx_costs): Set more accurate cost for mfcr instruction on architectures with isel. * config/rs6000/rs6000-protos.h: Declare new function. * config/rs6000/rs6000.h (processor_type): Add PROCESSOR_PPCE500MC64. (ASM_CPU_SPEC): Add e500mc64. Define TARGET_E500MC64. * config/rs6000/rs6000.md (define_attr "cpu"): Add ppce500mc64. Include e500mc64.md. (abssi2_isel): Expand pattern to handle DImode. (nabs<mode>2_isel): New pattern. (floatdidf2): Add e500mc64 (floatdidf2_fpr): Ditto. (fix_truncdfdi2): Ditto. (fix_truncdfdi2_fpr): Ditto. (absdi2): Change pattern to handle 64 bit isel targets. (absdi2_internal): Exclude isel targets. (nabsdi2): Exclude isel targets. (cstore<mode>4): Call rs6000_emit_sISEL for isel targets. * doc/invoke.texi: Add e500mc64 to list of cpus. 2009-11-03 Edmar Wienskoski edmar@... * gcc.target/powerpc/ppc-eq0-1.c: Adjust testcase for isel targets. diff -ruN gcc-4.5-20091027/gcc/config/rs6000/e500mc64.md gcc-4.5-e500mc64-20091027/gcc/config/rs6000/e500mc64.md --- gcc-4.5-20091027/gcc/config/rs6000/e500mc64.md 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/e500mc64.md 2009-10-27 11:00:02.000000000 -0500 @@ -0,0 +1,186 @@ +;; Pipeline description for Motorola PowerPC e500mc64 core. +;; Copyright (C) 2009 Free Software Foundation, Inc. +;; Contributed by Edmar Wienskoski (edmar@...) +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; <http://www.gnu.org/licenses/>. +;; +;; e500mc64 64-bit SU(2), LSU, FPU, BPU +;; Max issue 3 insns/clock cycle (includes 1 branch) + +(define_automaton "e500mc64_most,e500mc64_long,e500mc64_retire") +(define_cpu_unit "e500mc64_decode_0,e500mc64_decode_1" "e500mc64_most") +(define_cpu_unit "e500mc64_issue_0,e500mc64_issue_1" "e500mc64_most") +(define_cpu_unit "e500mc64_retire_0,e500mc64_retire_1" "e500mc64_retire") + +;; SU. +(define_cpu_unit "e500mc64_su0_stage0,e500mc64_su1_stage0" "e500mc64_most") + +;; MU. +(define_cpu_unit "e500mc64_mu_stage0,e500mc64_mu_stage1" "e500mc64_most") +(define_cpu_unit "e500mc64_mu_stage2,e500mc64_mu_stage3" "e500mc64_most") + +;; Non-pipelined division. +(define_cpu_unit "e500mc64_mu_div" "e500mc64_long") + +;; LSU. +(define_cpu_unit "e500mc64_lsu" "e500mc64_most") + +;; FPU. +(define_cpu_unit "e500mc64_fpu" "e500mc64_most") + +;; Branch unit. +(define_cpu_unit "e500mc64_bu" "e500mc64_most") + +;; The following units are used to make the automata deterministic. +(define_cpu_unit "present_e500mc64_decode_0" "e500mc64_most") +(define_cpu_unit "present_e500mc64_issue_0" "e500mc64_most") +(define_cpu_unit "present_e500mc64_retire_0" "e500mc64_retire") +(define_cpu_unit "present_e500mc64_su0_stage0" "e500mc64_most") + +;; The following sets to make automata deterministic when option ndfa is used. +(presence_set "present_e500mc64_decode_0" "e500mc64_decode_0") +(presence_set "present_e500mc64_issue_0" "e500mc64_issue_0") +(presence_set "present_e500mc64_retire_0" "e500mc64_retire_0") +(presence_set "present_e500mc64_su0_stage0" "e500mc64_su0_stage0") + +;; Some useful abbreviations. +(define_reservation "e500mc64_decode" + "e500mc64_decode_0|e500mc64_decode_1+present_e500mc64_decode_0") +(define_reservation "e500mc64_issue" + "e500mc64_issue_0|e500mc64_issue_1+present_e500mc64_issue_0") +(define_reservation "e500mc64_retire" + "e500mc64_retire_0|e500mc64_retire_1+present_e500mc64_retire_0") +(define_reservation "e500mc64_su_stage0" + "e500mc64_su0_stage0|e500mc64_su1_stage0+present_e500mc64_su0_stage0") + +;; Simple SU insns. +(define_insn_reservation "e500mc64_su" 1 + (and (eq_attr "type" "integer,insert_word,insert_dword,cmp,compare,\ + delayed_compare,fast_compare,shift,trap,cntlz,exts") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +(define_insn_reservation "e500mc64_delayed" 2 + (and (eq_attr "type" "var_shift_rotate,var_delayed_compare") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0,e500mc64_retire") + +(define_insn_reservation "e500mc64_two" 2 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ + e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +(define_insn_reservation "e500mc64_three" 3 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ + e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ + e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +;; Multiply. +(define_insn_reservation "e500mc64_multiply" 4 + (and (eq_attr "type" "imul,imul2,imul3,imul_compare") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_mu_stage0,e500mc64_mu_stage1,\ + e500mc64_mu_stage2,e500mc64_mu_stage3+e500mc64_retire") + +;; Divide. We use the average latency time here. +(define_insn_reservation "e500mc64_divide" 14 + (and (eq_attr "type" "idiv") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_mu_stage0+e500mc64_mu_div,\ + e500mc64_mu_div*13") + +;; Branch. +(define_insn_reservation "e500mc64_branch" 1 + (and (eq_attr "type" "jmpreg,branch,isync") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_bu,e500mc64_retire") + +;; CR logical. +(define_insn_reservation "e500mc64_cr_logical" 1 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_bu,e500mc64_retire") + +;; Mfcr. +(define_insn_reservation "e500mc64_mfcr" 4 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su1_stage0,e500mc64_su1_stage0*3+e500mc64_retire") + +;; Mtcrf. +(define_insn_reservation "e500mc64_mtcrf" 1 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su1_stage0+e500mc64_retire") + +;; Mtjmpr. +(define_insn_reservation "e500mc64_mtjmpr" 1 + (and (eq_attr "type" "mtjmpr,mfjmpr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +;; Brinc. +(define_insn_reservation "e500mc64_brinc" 1 + (and (eq_attr "type" "brinc") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +;; Loads. +(define_insn_reservation "e500mc64_load" 3 + (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\ + load_l,sync") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") + +(define_insn_reservation "e500mc64_fpload" 4 + (and (eq_attr "type" "fpload,fpload_ux,fpload_u") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing*2,e500mc64_retire") + +;; Stores. +(define_insn_reservation "e500mc64_store" 3 + (and (eq_attr "type" "store,store_ux,store_u,store_c") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") + +(define_insn_reservation "e500mc64_fpstore" 3 + (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") + +;; The following ignores the retire unit to avoid a large automata. + +;; FP. +(define_insn_reservation "e500mc64_float" 7 + (and (eq_attr "type" "fpsimple,fp,fpcompare,dmul") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_fpu") +; "e500mc64_decode,e500mc64_issue+e500mc64_fpu,nothing*5,e500mc64_retire") + +;; FP divides are not pipelined. +(define_insn_reservation "e500mc64_sdiv" 20 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_fpu,e500mc64_fpu*19") + +(define_insn_reservation "e500mc64_ddiv" 35 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_fpu,e500mc64_fpu*34") diff -ruN gcc-4.5-20091027/gcc/config/rs6000/rs6000.c gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.c --- gcc-4.5-20091027/gcc/config/rs6000/rs6000.c 2009-10-27 10:49:12.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.c 2009-10-27 11:00:02.000000000 -0500 @@ -761,6 +761,25 @@ 1, /* prefetch streams /*/ }; +/* Instruction costs on PPCE500MC64 processors. */ +static const +struct processor_costs ppce500mc64_cost = { + COSTS_N_INSNS (4), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (4), /* mulsi_const9 */ + COSTS_N_INSNS (4), /* muldi */ + COSTS_N_INSNS (14), /* divsi */ + COSTS_N_INSNS (14), /* divdi */ + COSTS_N_INSNS (4), /* fp */ + COSTS_N_INSNS (10), /* dmul */ + COSTS_N_INSNS (36), /* sdiv */ + COSTS_N_INSNS (66), /* ddiv */ + 64, /* cache line size */ + 32, /* l1 cache */ + 128, /* l2 cache */ + 1, /* prefetch streams /*/ +}; + /* Instruction costs on POWER4 and POWER5 processors. */ static const struct processor_costs power4_cost = { @@ -2217,6 +2236,8 @@ {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK}, {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ISEL}, + {"e500mc64", PROCESSOR_PPCE500MC64, + POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ISEL}, {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"970", PROCESSOR_POWER4, POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64}, @@ -2345,7 +2366,7 @@ } if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3 - || rs6000_cpu == PROCESSOR_PPCE500MC) + || rs6000_cpu == PROCESSOR_PPCE500MC || TARGET_E500MC64) { if (TARGET_ALTIVEC) error ("AltiVec not supported in this target"); @@ -2537,7 +2558,7 @@ SUB3TARGET_OVERRIDE_OPTIONS; #endif - if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC) + if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC || TARGET_E500MC64) { /* The e500 and e500mc do not have string instructions, and we set MASK_STRING above when optimizing for size. */ @@ -2574,7 +2595,9 @@ rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4 || rs6000_cpu == PROCESSOR_POWER5 || rs6000_cpu == PROCESSOR_POWER6 - || rs6000_cpu == PROCESSOR_POWER7); + || rs6000_cpu == PROCESSOR_POWER7 + || rs6000_cpu == PROCESSOR_PPCE500MC + || rs6000_cpu == PROCESSOR_PPCE500MC64); /* Allow debug switches to override the above settings. */ if (TARGET_ALWAYS_HINT > 0) @@ -2776,6 +2799,10 @@ rs6000_cost = &ppce500mc_cost; break; + case PROCESSOR_PPCE500MC64: + rs6000_cost = &ppce500mc64_cost; + break; + case PROCESSOR_POWER4: case PROCESSOR_POWER5: rs6000_cost = &power4_cost; @@ -15433,6 +15460,53 @@ /* Emit the RTL for an sCOND pattern. */ void +rs6000_emit_sISEL (enum machine_mode mode, rtx operands[]) +{ + rtx condition_rtx; + enum machine_mode op_mode; + enum rtx_code cond_code; + rtx result = operands[0]; + + condition_rtx = rs6000_generate_compare (operands[1], mode); + cond_code = GET_CODE (condition_rtx); + + op_mode = GET_MODE (XEXP (operands[1], 0)); + if (op_mode == VOIDmode) + op_mode = GET_MODE (XEXP (operands[1], 1)); + + if (TARGET_POWERPC64 && GET_MODE (result) == DImode) + { + PUT_MODE (condition_rtx, DImode); + if (cond_code == GEU || cond_code == GTU || cond_code == LEU + || cond_code == LTU) + emit_insn (gen_isel_unsigned_di (result, condition_rtx, + force_reg (DImode, const1_rtx), + force_reg (DImode, const0_rtx), + XEXP (condition_rtx, 0))); + else + emit_insn (gen_isel_signed_di (result, condition_rtx, + force_reg (DImode, const1_rtx), + force_reg (DImode, const0_rtx), + XEXP (condition_rtx, 0))); + } + else + { + PUT_MODE (condition_rtx, SImode); + if (cond_code == GEU || cond_code == GTU || cond_code == LEU + || cond_code == LTU) + emit_insn (gen_isel_unsigned_si (result, condition_rtx, + force_reg (SImode, const1_rtx), + force_reg (SImode, const0_rtx), + XEXP (condition_rtx, 0))); + else + emit_insn (gen_isel_signed_si (result, condition_rtx, + force_reg (SImode, const1_rtx), + force_reg (SImode, const0_rtx), + XEXP (condition_rtx, 0))); + } +} + +void rs6000_emit_sCOND (enum machine_mode mode, rtx operands[]) { rtx condition_rtx; @@ -16089,7 +16163,7 @@ rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond) { rtx condition_rtx, cr; - enum machine_mode mode = GET_MODE (XEXP (op, 0)); + enum machine_mode mode = GET_MODE (dest); if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode)) return 0; @@ -16097,7 +16171,7 @@ /* We still have to do the compare, because isel doesn't do a compare, it just looks at the CRx bits set by a previous compare instruction. */ - condition_rtx = rs6000_generate_compare (op, SImode); + condition_rtx = rs6000_generate_compare (op, mode); cr = XEXP (condition_rtx, 0); if (mode == SImode) @@ -21952,6 +22026,7 @@ case CPU_PPCE300C2: case CPU_PPCE300C3: case CPU_PPCE500MC: + case CPU_PPCE500MC64: return 2; case CPU_RIOS2: case CPU_PPC476: @@ -24765,7 +24840,10 @@ { if (XEXP (x, 1) == const0_rtx) { - *total = COSTS_N_INSNS (2); + if (TARGET_ISEL) + *total = COSTS_N_INSNS (8); + else + *total = COSTS_N_INSNS (2); return true; } else if (mode == Pmode) @@ -24781,7 +24859,10 @@ case UNORDERED: if (outer_code == SET && (XEXP (x, 1) == const0_rtx)) { - *total = COSTS_N_INSNS (2); + if (TARGET_ISEL) + *total = COSTS_N_INSNS (8); + else + *total = COSTS_N_INSNS (2); return true; } /* CC COMPARE. */ diff -ruN gcc-4.5-20091027/gcc/config/rs6000/rs6000.h gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.h --- gcc-4.5-20091027/gcc/config/rs6000/rs6000.h 2009-10-27 10:49:12.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.h 2009-10-27 11:00:02.000000000 -0500 @@ -158,6 +158,7 @@ %{mcpu=e300c2: -me300} \ %{mcpu=e300c3: -me300} \ %{mcpu=e500mc: -me500mc} \ +%{mcpu=e500mc64: -me500mc64} \ %{maltivec: -maltivec} \ -many" @@ -341,6 +342,7 @@ PROCESSOR_PPCE300C2, PROCESSOR_PPCE300C3, PROCESSOR_PPCE500MC, + PROCESSOR_PPCE500MC64, PROCESSOR_POWER4, PROCESSOR_POWER5, PROCESSOR_POWER6, @@ -536,6 +538,7 @@ #define TARGET_FPRS 1 #define TARGET_E500_SINGLE 0 #define TARGET_E500_DOUBLE 0 +#define TARGET_E500MC64 (rs6000_cpu == PROCESSOR_PPCE500MC64) #define CHECK_E500_OPTIONS do { } while (0) /* E500 processors only support plain "sync", not lwsync. */ diff -ruN gcc-4.5-20091027/gcc/config/rs6000/rs6000.md gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.md --- gcc-4.5-20091027/gcc/config/rs6000/rs6000.md 2009-10-27 10:49:12.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.md 2009-11-03 10:35:06.000000000 -0600 @@ -139,7 +139,7 @@ ;; Processor type -- this attribute must exactly match the processor_type ;; enumeration in rs6000.h. -(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,power4,power5,power6,power7,cell,ppca2" +(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,power4,power5,power6,power7,cell,ppca2" (const (symbol_ref "rs6000_cpu_attr"))) @@ -166,6 +166,7 @@ (include "8540.md") (include "e300c2c3.md") (include "e500mc.md") +(include "e500mc64.md") (include "power4.md") (include "power5.md") (include "power6.md") @@ -2077,23 +2078,42 @@ "TARGET_POWER" "abs %0,%1") -(define_insn_and_split "abssi2_isel" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (abs:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) - (clobber (match_scratch:SI 2 "=&b")) +(define_insn_and_split "abs<mode>2_isel" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (abs:GPR (match_operand:GPR 1 "gpc_reg_operand" "b"))) + (clobber (match_scratch:GPR 2 "=&b")) (clobber (match_scratch:CC 3 "=y"))] "TARGET_ISEL" "#" "&& reload_completed" - [(set (match_dup 2) (neg:SI (match_dup 1))) + [(set (match_dup 2) (neg:GPR (match_dup 1))) (set (match_dup 3) (compare:CC (match_dup 1) (const_int 0))) (set (match_dup 0) - (if_then_else:SI (ge (match_dup 3) - (const_int 0)) - (match_dup 1) - (match_dup 2)))] + (if_then_else:GPR (ge (match_dup 3) + (const_int 0)) + (match_dup 1) + (match_dup 2)))] + "") + +(define_insn_and_split "nabs<mode>2_isel" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (neg:GPR (abs:GPR (match_operand:GPR 1 "gpc_reg_operand" "b")))) + (clobber (match_scratch:GPR 2 "=&b")) + (clobber (match_scratch:CC 3 "=y"))] + "TARGET_ISEL" + "#" + "&& reload_completed" + [(set (match_dup 2) (neg:GPR (match_dup 1))) + (set (match_dup 3) + (compare:CC (match_dup 1) + (const_int 0))) + (set (match_dup 0) + (if_then_else:GPR (ge (match_dup 3) + (const_int 0)) + (match_dup 2) + (match_dup 1)))] "") (define_insn_and_split "abssi2_nopower" @@ -6738,14 +6758,15 @@ (define_expand "floatdidf2" [(set (match_operand:DF 0 "gpc_reg_operand" "") (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))] - "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode)) + "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode) + || TARGET_E500MC64) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" "") (define_insn "*floatdidf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (float:DF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))] - "(TARGET_POWERPC64 || TARGET_XILINX_FPU) + "(TARGET_POWERPC64 || TARGET_XILINX_FPU || TARGET_E500MC64) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && !VECTOR_UNIT_VSX_P (DFmode)" "fcfid %0,%1" @@ -6760,14 +6781,15 @@ (define_expand "fix_truncdfdi2" [(set (match_operand:DI 0 "gpc_reg_operand" "") (fix:DI (match_operand:DF 1 "gpc_reg_operand" "")))] - "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode)) + "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode) + || TARGET_E500MC64) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" "") (define_insn "*fix_truncdfdi2_fpr" [(set (match_operand:DI 0 "gpc_reg_operand" "=!d#r") (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d")))] - "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT + "(TARGET_POWERPC64 || TARGET_XILINX_FPU || TARGET_E500MC64) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && !VECTOR_UNIT_VSX_P (DFmode)" "fctidz %0,%1" [(set_attr "type" "fp")]) @@ -7197,11 +7219,24 @@ ;; PowerPC64 DImode operations. -(define_insn_and_split "absdi2" +(define_expand "absdi2" + [(set (match_operand:DI 0 "gpc_reg_operand" "") + (abs:DI (match_operand:DI 1 "gpc_reg_operand" "")))] + "TARGET_POWERPC64" + " +{ + if (TARGET_ISEL) + emit_insn (gen_absdi2_isel (operands[0], operands[1])); + else + emit_insn (gen_absdi2_internal (operands[0], operands[1])); + DONE; +}") + +(define_insn_and_split "absdi2_internal" [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))) (clobber (match_scratch:DI 2 "=&r,&r"))] - "TARGET_POWERPC64" + "TARGET_POWERPC64 && !TARGET_ISEL" "#" "&& reload_completed" [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) @@ -7213,7 +7248,7 @@ [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))) (clobber (match_scratch:DI 2 "=&r,&r"))] - "TARGET_POWERPC64" + "TARGET_POWERPC64 && !TARGET_ISEL" "#" "&& reload_completed" [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) @@ -12588,7 +12623,10 @@ || GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE) && operands[3] == const0_rtx) FAIL; - rs6000_emit_sCOND (<MODE>mode, operands); + if (TARGET_ISEL<sel>) + rs6000_emit_sISEL (<MODE>mode, operands); + else + rs6000_emit_sCOND (<MODE>mode, operands); DONE; }") diff -ruN gcc-4.5-20091027/gcc/config/rs6000/rs6000-protos.h gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000-protos.h --- gcc-4.5-20091027/gcc/config/rs6000/rs6000-protos.h 2009-10-27 10:49:12.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000-protos.h 2009-10-27 11:00:02.000000000 -0500 @@ -90,6 +90,7 @@ extern bool rs6000_output_addr_const_extra (FILE *, rtx); extern enum rtx_code rs6000_reverse_condition (enum machine_mode, enum rtx_code); +extern void rs6000_emit_sISEL (enum machine_mode, rtx[]); extern void rs6000_emit_sCOND (enum machine_mode, rtx[]); extern void rs6000_emit_cbranch (enum machine_mode, rtx[]); extern char * output_cbranch (rtx, const char *, int, rtx); diff -ruN gcc-4.5-20091027/gcc/config.gcc gcc-4.5-e500mc64-20091027/gcc/config.gcc --- gcc-4.5-20091027/gcc/config.gcc 2009-10-27 10:49:28.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config.gcc 2009-10-27 11:00:40.000000000 -0500 @@ -327,7 +327,7 @@ extra_headers="ppc-asm.h altivec.h spe.h ppu_intrinsics.h paired.h spu2vmx.h vec_types.h si2vmx.h" need_64bit_hwint=yes case x$with_cpu in - xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[34567]|xpower6x|xrs64a|xcell|xa2) + xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[34567]|xpower6x|xrs64a|xcell|xa2|xe500mc64) cpu_is_64bit=yes ;; esac @@ -3072,7 +3072,7 @@ | 401 | 403 | 405 | 405fp | 440 | 440fp | 464 | 464fp \ | 476 | 476fp | 505 | 601 | 602 | 603 | 603e | ec603e \ | 604 | 604e | 620 | 630 | 740 | 750 | 7400 | 7450 \ - | a2 | e300c[23] | 854[08] | e500mc \ + | a2 | e300c[23] | 854[08] | e500mc | e500mc64 \ | 801 | 821 | 823 | 860 | 970 | G3 | G4 | G5 | cell) # OK ;; diff -ruN gcc-4.5-20091027/gcc/doc/invoke.texi gcc-4.5-e500mc64-20091027/gcc/doc/invoke.texi --- gcc-4.5-20091027/gcc/doc/invoke.texi 2009-10-27 10:42:17.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/doc/invoke.texi 2009-11-03 12:52:17.000000000 -0600 @@ -14656,10 +14656,10 @@ @samp{603e}, @samp{604}, @samp{604e}, @samp{620}, @samp{630}, @samp{740}, @samp{7400}, @samp{7450}, @samp{750}, @samp{801}, @samp{821}, @samp{823}, @samp{860}, @samp{970}, @samp{8540}, @samp{a2}, @samp{e300c2}, -@samp{e300c3}, @samp{e500mc}, @samp{ec603e}, @samp{G3}, @samp{G4}, @samp{G5}, -@samp{power}, @samp{power2}, @samp{power3}, @samp{power4}, -@samp{power5}, @samp{power5+}, @samp{power6}, @samp{power6x}, @samp{power7}, -@samp{common}, @samp{powerpc}, @samp{powerpc64}, @samp{rios}, +@samp{e300c3}, @samp{e500mc}, @samp{e500mc64}, @samp{ec603e}, @samp{G3}, +@samp{G4}, @samp{G5}, @samp{power}, @samp{power2}, @samp{power3}, +@samp{power4}, @samp{power5}, @samp{power5+}, @samp{power6}, @samp{power6x}, +@samp{power7}, @samp{common}, @samp{powerpc}, @samp{powerpc64}, @samp{rios}, @samp{rios1}, @samp{rios2}, @samp{rsc}, and @samp{rs64}. @option{-mcpu=common} selects a completely generic processor. Code diff -ruN gcc-4.5-20091027/gcc/testsuite/gcc.target/powerpc/ppc-eq0-1.c gcc-4.5-e500mc64-20091027/gcc/testsuite/gcc.target/powerpc/ppc-eq0-1.c --- gcc-4.5-20091027/gcc/testsuite/gcc.target/powerpc/ppc-eq0-1.c 2009-10-27 10:42:56.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/testsuite/gcc.target/powerpc/ppc-eq0-1.c 2009-11-03 10:35:53.000000000 -0600 @@ -7,4 +7,4 @@ return x == 0; } -/* { dg-final { scan-assembler "cntlzw" } } */ +/* { dg-final { scan-assembler "cntlzw|isel" } } */ |
|
|
|
|
|
Re: {RFA] PowerPC e500mc64 core supportDavid Edelsohn wrote:
> Edmar, > > Creating TARGET_E500MC64 is incorrect, the macro should represent a > feature, not a processor. The rs6000.c tests should use > PROCESSOR_E500MC64. > > The change to floatdidf2 pattern does not make sense because it > already tests TARGET_POWERPC64 and e500mc64 sets MASK_POWERPC64, > similarly for the other di/df patterns. > > I do not see any useful purpose for TARGET_E500MC64. > > Should rs6000_emit_sCOND() call rs6000_emit_sISEL() instead of > modifying cstore<mode>4 ? > > Thanks, David > > > I updated the patches with the changes. I also updated the Changelog to reflect that the floatdidf2 changes are intended for 32 bits as well. Regards, Edmar 2009-11-03 Edmar Wienskoski edmar@... * config.gcc (cpu_is_64bit): Add new core e500mc64. (powerpc*-*-*): Add new core e500mc64. * config/rs6000/e500mc64.md: New file. * config/rs6000/rs6000.c (processor_costs): Add new costs for e500mc64. (rs6000_override_options): Add e500mc64 case to processor_target_table. Altivec and Spe options not allowed with e500mc64. Disable string instructions for e500mc64. Enable branch targets alignment for both e500mc and e500mc64. Initialize rs6000_cost for e500mc64. (rs6000_emit_sISEL): New function. (rs6000_emit_sCOND): Call rs6000_emit_sISEL for isel targets. (rs6000_emit_int_cmove): Fix mode of 64 bit isel pattern generation. (rs6000_issue_rate): Set issue rate for e500mc64. (rs6000_rtx_costs): Set more accurate cost for mfcr instruction on architectures with isel. * config/rs6000/rs6000-protos.h: Declare new function. * config/rs6000/rs6000.h (processor_type): Add PROCESSOR_PPCE500MC64. (ASM_CPU_SPEC): Add e500mc64. * config/rs6000/rs6000.md (define_attr "cpu"): Add ppce500mc64. Include e500mc64.md. (abssi2_isel): Expand pattern to handle DImode. (nabs<mode>2_isel): New pattern. (floatdidf2): Add e500mc64 for both 32bits and 64bits mode. (floatdidf2_fpr): Ditto. (fix_truncdfdi2): Ditto. (fix_truncdfdi2_fpr): Ditto. (absdi2): Change pattern to handle 64 bit isel targets. (absdi2_internal): Exclude isel targets. (nabsdi2): Exclude isel targets. * doc/invoke.texi: Add e500mc64 to list of cpus. 2009-11-03 Edmar Wienskoski edmar@... * gcc.target/powerpc/ppc-eq0-1.c: Adjust testcase for isel targets. diff -ruN gcc-4.5-20091027/gcc/config/rs6000/e500mc64.md gcc-4.5-e500mc64-20091027/gcc/config/rs6000/e500mc64.md --- gcc-4.5-20091027/gcc/config/rs6000/e500mc64.md 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/e500mc64.md 2009-10-27 11:00:02.000000000 -0500 @@ -0,0 +1,186 @@ +;; Pipeline description for Motorola PowerPC e500mc64 core. +;; Copyright (C) 2009 Free Software Foundation, Inc. +;; Contributed by Edmar Wienskoski (edmar@...) +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; <http://www.gnu.org/licenses/>. +;; +;; e500mc64 64-bit SU(2), LSU, FPU, BPU +;; Max issue 3 insns/clock cycle (includes 1 branch) + +(define_automaton "e500mc64_most,e500mc64_long,e500mc64_retire") +(define_cpu_unit "e500mc64_decode_0,e500mc64_decode_1" "e500mc64_most") +(define_cpu_unit "e500mc64_issue_0,e500mc64_issue_1" "e500mc64_most") +(define_cpu_unit "e500mc64_retire_0,e500mc64_retire_1" "e500mc64_retire") + +;; SU. +(define_cpu_unit "e500mc64_su0_stage0,e500mc64_su1_stage0" "e500mc64_most") + +;; MU. +(define_cpu_unit "e500mc64_mu_stage0,e500mc64_mu_stage1" "e500mc64_most") +(define_cpu_unit "e500mc64_mu_stage2,e500mc64_mu_stage3" "e500mc64_most") + +;; Non-pipelined division. +(define_cpu_unit "e500mc64_mu_div" "e500mc64_long") + +;; LSU. +(define_cpu_unit "e500mc64_lsu" "e500mc64_most") + +;; FPU. +(define_cpu_unit "e500mc64_fpu" "e500mc64_most") + +;; Branch unit. +(define_cpu_unit "e500mc64_bu" "e500mc64_most") + +;; The following units are used to make the automata deterministic. +(define_cpu_unit "present_e500mc64_decode_0" "e500mc64_most") +(define_cpu_unit "present_e500mc64_issue_0" "e500mc64_most") +(define_cpu_unit "present_e500mc64_retire_0" "e500mc64_retire") +(define_cpu_unit "present_e500mc64_su0_stage0" "e500mc64_most") + +;; The following sets to make automata deterministic when option ndfa is used. +(presence_set "present_e500mc64_decode_0" "e500mc64_decode_0") +(presence_set "present_e500mc64_issue_0" "e500mc64_issue_0") +(presence_set "present_e500mc64_retire_0" "e500mc64_retire_0") +(presence_set "present_e500mc64_su0_stage0" "e500mc64_su0_stage0") + +;; Some useful abbreviations. +(define_reservation "e500mc64_decode" + "e500mc64_decode_0|e500mc64_decode_1+present_e500mc64_decode_0") +(define_reservation "e500mc64_issue" + "e500mc64_issue_0|e500mc64_issue_1+present_e500mc64_issue_0") +(define_reservation "e500mc64_retire" + "e500mc64_retire_0|e500mc64_retire_1+present_e500mc64_retire_0") +(define_reservation "e500mc64_su_stage0" + "e500mc64_su0_stage0|e500mc64_su1_stage0+present_e500mc64_su0_stage0") + +;; Simple SU insns. +(define_insn_reservation "e500mc64_su" 1 + (and (eq_attr "type" "integer,insert_word,insert_dword,cmp,compare,\ + delayed_compare,fast_compare,shift,trap,cntlz,exts") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +(define_insn_reservation "e500mc64_delayed" 2 + (and (eq_attr "type" "var_shift_rotate,var_delayed_compare") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0,e500mc64_retire") + +(define_insn_reservation "e500mc64_two" 2 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ + e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +(define_insn_reservation "e500mc64_three" 3 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ + e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ + e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +;; Multiply. +(define_insn_reservation "e500mc64_multiply" 4 + (and (eq_attr "type" "imul,imul2,imul3,imul_compare") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_mu_stage0,e500mc64_mu_stage1,\ + e500mc64_mu_stage2,e500mc64_mu_stage3+e500mc64_retire") + +;; Divide. We use the average latency time here. +(define_insn_reservation "e500mc64_divide" 14 + (and (eq_attr "type" "idiv") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_mu_stage0+e500mc64_mu_div,\ + e500mc64_mu_div*13") + +;; Branch. +(define_insn_reservation "e500mc64_branch" 1 + (and (eq_attr "type" "jmpreg,branch,isync") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_bu,e500mc64_retire") + +;; CR logical. +(define_insn_reservation "e500mc64_cr_logical" 1 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_bu,e500mc64_retire") + +;; Mfcr. +(define_insn_reservation "e500mc64_mfcr" 4 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su1_stage0,e500mc64_su1_stage0*3+e500mc64_retire") + +;; Mtcrf. +(define_insn_reservation "e500mc64_mtcrf" 1 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su1_stage0+e500mc64_retire") + +;; Mtjmpr. +(define_insn_reservation "e500mc64_mtjmpr" 1 + (and (eq_attr "type" "mtjmpr,mfjmpr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +;; Brinc. +(define_insn_reservation "e500mc64_brinc" 1 + (and (eq_attr "type" "brinc") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +;; Loads. +(define_insn_reservation "e500mc64_load" 3 + (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\ + load_l,sync") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") + +(define_insn_reservation "e500mc64_fpload" 4 + (and (eq_attr "type" "fpload,fpload_ux,fpload_u") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing*2,e500mc64_retire") + +;; Stores. +(define_insn_reservation "e500mc64_store" 3 + (and (eq_attr "type" "store,store_ux,store_u,store_c") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") + +(define_insn_reservation "e500mc64_fpstore" 3 + (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") + +;; The following ignores the retire unit to avoid a large automata. + +;; FP. +(define_insn_reservation "e500mc64_float" 7 + (and (eq_attr "type" "fpsimple,fp,fpcompare,dmul") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_fpu") +; "e500mc64_decode,e500mc64_issue+e500mc64_fpu,nothing*5,e500mc64_retire") + +;; FP divides are not pipelined. +(define_insn_reservation "e500mc64_sdiv" 20 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_fpu,e500mc64_fpu*19") + +(define_insn_reservation "e500mc64_ddiv" 35 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_fpu,e500mc64_fpu*34") diff -ruN gcc-4.5-20091027/gcc/config/rs6000/rs6000.c gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.c --- gcc-4.5-20091027/gcc/config/rs6000/rs6000.c 2009-10-27 10:49:12.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.c 2009-11-04 12:44:23.000000000 -0600 @@ -761,6 +761,25 @@ 1, /* prefetch streams /*/ }; +/* Instruction costs on PPCE500MC64 processors. */ +static const +struct processor_costs ppce500mc64_cost = { + COSTS_N_INSNS (4), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (4), /* mulsi_const9 */ + COSTS_N_INSNS (4), /* muldi */ + COSTS_N_INSNS (14), /* divsi */ + COSTS_N_INSNS (14), /* divdi */ + COSTS_N_INSNS (4), /* fp */ + COSTS_N_INSNS (10), /* dmul */ + COSTS_N_INSNS (36), /* sdiv */ + COSTS_N_INSNS (66), /* ddiv */ + 64, /* cache line size */ + 32, /* l1 cache */ + 128, /* l2 cache */ + 1, /* prefetch streams /*/ +}; + /* Instruction costs on POWER4 and POWER5 processors. */ static const struct processor_costs power4_cost = { @@ -2217,6 +2236,8 @@ {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK}, {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ISEL}, + {"e500mc64", PROCESSOR_PPCE500MC64, + POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ISEL}, {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"970", PROCESSOR_POWER4, POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64}, @@ -2345,7 +2366,7 @@ } if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3 - || rs6000_cpu == PROCESSOR_PPCE500MC) + || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64) { if (TARGET_ALTIVEC) error ("AltiVec not supported in this target"); @@ -2537,7 +2558,8 @@ SUB3TARGET_OVERRIDE_OPTIONS; #endif - if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC) + if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC + || rs6000_cpu == PROCESSOR_PPCE500MC64) { /* The e500 and e500mc do not have string instructions, and we set MASK_STRING above when optimizing for size. */ @@ -2574,7 +2596,9 @@ rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4 || rs6000_cpu == PROCESSOR_POWER5 || rs6000_cpu == PROCESSOR_POWER6 - || rs6000_cpu == PROCESSOR_POWER7); + || rs6000_cpu == PROCESSOR_POWER7 + || rs6000_cpu == PROCESSOR_PPCE500MC + || rs6000_cpu == PROCESSOR_PPCE500MC64); /* Allow debug switches to override the above settings. */ if (TARGET_ALWAYS_HINT > 0) @@ -2776,6 +2800,10 @@ rs6000_cost = &ppce500mc_cost; break; + case PROCESSOR_PPCE500MC64: + rs6000_cost = &ppce500mc64_cost; + break; + case PROCESSOR_POWER4: case PROCESSOR_POWER5: rs6000_cost = &power4_cost; @@ -15433,6 +15461,53 @@ /* Emit the RTL for an sCOND pattern. */ void +rs6000_emit_sISEL (enum machine_mode mode, rtx operands[]) +{ + rtx condition_rtx; + enum machine_mode op_mode; + enum rtx_code cond_code; + rtx result = operands[0]; + + condition_rtx = rs6000_generate_compare (operands[1], mode); + cond_code = GET_CODE (condition_rtx); + + op_mode = GET_MODE (XEXP (operands[1], 0)); + if (op_mode == VOIDmode) + op_mode = GET_MODE (XEXP (operands[1], 1)); + + if (TARGET_POWERPC64 && GET_MODE (result) == DImode) + { + PUT_MODE (condition_rtx, DImode); + if (cond_code == GEU || cond_code == GTU || cond_code == LEU + || cond_code == LTU) + emit_insn (gen_isel_unsigned_di (result, condition_rtx, + force_reg (DImode, const1_rtx), + force_reg (DImode, const0_rtx), + XEXP (condition_rtx, 0))); + else + emit_insn (gen_isel_signed_di (result, condition_rtx, + force_reg (DImode, const1_rtx), + force_reg (DImode, const0_rtx), + XEXP (condition_rtx, 0))); + } + else + { + PUT_MODE (condition_rtx, SImode); + if (cond_code == GEU || cond_code == GTU || cond_code == LEU + || cond_code == LTU) + emit_insn (gen_isel_unsigned_si (result, condition_rtx, + force_reg (SImode, const1_rtx), + force_reg (SImode, const0_rtx), + XEXP (condition_rtx, 0))); + else + emit_insn (gen_isel_signed_si (result, condition_rtx, + force_reg (SImode, const1_rtx), + force_reg (SImode, const0_rtx), + XEXP (condition_rtx, 0))); + } +} + +void rs6000_emit_sCOND (enum machine_mode mode, rtx operands[]) { rtx condition_rtx; @@ -15440,6 +15515,12 @@ enum rtx_code cond_code; rtx result = operands[0]; + if (TARGET_ISEL && (mode == SImode || mode == DImode)) + { + rs6000_emit_sISEL (mode, operands); + return; + } + condition_rtx = rs6000_generate_compare (operands[1], mode); cond_code = GET_CODE (condition_rtx); @@ -16089,7 +16170,7 @@ rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond) { rtx condition_rtx, cr; - enum machine_mode mode = GET_MODE (XEXP (op, 0)); + enum machine_mode mode = GET_MODE (dest); if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode)) return 0; @@ -16097,7 +16178,7 @@ /* We still have to do the compare, because isel doesn't do a compare, it just looks at the CRx bits set by a previous compare instruction. */ - condition_rtx = rs6000_generate_compare (op, SImode); + condition_rtx = rs6000_generate_compare (op, mode); cr = XEXP (condition_rtx, 0); if (mode == SImode) @@ -21952,6 +22033,7 @@ case CPU_PPCE300C2: case CPU_PPCE300C3: case CPU_PPCE500MC: + case CPU_PPCE500MC64: return 2; case CPU_RIOS2: case CPU_PPC476: @@ -24765,7 +24847,10 @@ { if (XEXP (x, 1) == const0_rtx) { - *total = COSTS_N_INSNS (2); + if (TARGET_ISEL) + *total = COSTS_N_INSNS (8); + else + *total = COSTS_N_INSNS (2); return true; } else if (mode == Pmode) @@ -24781,7 +24866,10 @@ case UNORDERED: if (outer_code == SET && (XEXP (x, 1) == const0_rtx)) { - *total = COSTS_N_INSNS (2); + if (TARGET_ISEL) + *total = COSTS_N_INSNS (8); + else + *total = COSTS_N_INSNS (2); return true; } /* CC COMPARE. */ diff -ruN gcc-4.5-20091027/gcc/config/rs6000/rs6000.h gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.h --- gcc-4.5-20091027/gcc/config/rs6000/rs6000.h 2009-10-27 10:49:12.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.h 2009-11-04 10:34:41.000000000 -0600 @@ -158,6 +158,7 @@ %{mcpu=e300c2: -me300} \ %{mcpu=e300c3: -me300} \ %{mcpu=e500mc: -me500mc} \ +%{mcpu=e500mc64: -me500mc64} \ %{maltivec: -maltivec} \ -many" @@ -341,6 +342,7 @@ PROCESSOR_PPCE300C2, PROCESSOR_PPCE300C3, PROCESSOR_PPCE500MC, + PROCESSOR_PPCE500MC64, PROCESSOR_POWER4, PROCESSOR_POWER5, PROCESSOR_POWER6, diff -ruN gcc-4.5-20091027/gcc/config/rs6000/rs6000.md gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.md --- gcc-4.5-20091027/gcc/config/rs6000/rs6000.md 2009-10-27 10:49:12.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.md 2009-11-04 10:38:07.000000000 -0600 @@ -139,7 +139,7 @@ ;; Processor type -- this attribute must exactly match the processor_type ;; enumeration in rs6000.h. -(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,power4,power5,power6,power7,cell,ppca2" +(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,power4,power5,power6,power7,cell,ppca2" (const (symbol_ref "rs6000_cpu_attr"))) @@ -166,6 +166,7 @@ (include "8540.md") (include "e300c2c3.md") (include "e500mc.md") +(include "e500mc64.md") (include "power4.md") (include "power5.md") (include "power6.md") @@ -2077,23 +2078,42 @@ "TARGET_POWER" "abs %0,%1") -(define_insn_and_split "abssi2_isel" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (abs:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) - (clobber (match_scratch:SI 2 "=&b")) +(define_insn_and_split "abs<mode>2_isel" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (abs:GPR (match_operand:GPR 1 "gpc_reg_operand" "b"))) + (clobber (match_scratch:GPR 2 "=&b")) (clobber (match_scratch:CC 3 "=y"))] "TARGET_ISEL" "#" "&& reload_completed" - [(set (match_dup 2) (neg:SI (match_dup 1))) + [(set (match_dup 2) (neg:GPR (match_dup 1))) (set (match_dup 3) (compare:CC (match_dup 1) (const_int 0))) (set (match_dup 0) - (if_then_else:SI (ge (match_dup 3) - (const_int 0)) - (match_dup 1) - (match_dup 2)))] + (if_then_else:GPR (ge (match_dup 3) + (const_int 0)) + (match_dup 1) + (match_dup 2)))] + "") + +(define_insn_and_split "nabs<mode>2_isel" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (neg:GPR (abs:GPR (match_operand:GPR 1 "gpc_reg_operand" "b")))) + (clobber (match_scratch:GPR 2 "=&b")) + (clobber (match_scratch:CC 3 "=y"))] + "TARGET_ISEL" + "#" + "&& reload_completed" + [(set (match_dup 2) (neg:GPR (match_dup 1))) + (set (match_dup 3) + (compare:CC (match_dup 1) + (const_int 0))) + (set (match_dup 0) + (if_then_else:GPR (ge (match_dup 3) + (const_int 0)) + (match_dup 2) + (match_dup 1)))] "") (define_insn_and_split "abssi2_nopower" @@ -6738,14 +6758,15 @@ (define_expand "floatdidf2" [(set (match_operand:DF 0 "gpc_reg_operand" "") (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))] - "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode)) + "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode) + || rs6000_cpu == PROCESSOR_PPCE500MC64) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" "") (define_insn "*floatdidf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=d") (float:DF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))] - "(TARGET_POWERPC64 || TARGET_XILINX_FPU) + "(TARGET_POWERPC64 || TARGET_XILINX_FPU || rs6000_cpu == PROCESSOR_PPCE500MC64) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && !VECTOR_UNIT_VSX_P (DFmode)" "fcfid %0,%1" @@ -6760,15 +6781,17 @@ (define_expand "fix_truncdfdi2" [(set (match_operand:DI 0 "gpc_reg_operand" "") (fix:DI (match_operand:DF 1 "gpc_reg_operand" "")))] - "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode)) + "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode) + || rs6000_cpu == PROCESSOR_PPCE500MC64) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" "") (define_insn "*fix_truncdfdi2_fpr" [(set (match_operand:DI 0 "gpc_reg_operand" "=!d#r") (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d")))] - "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT - && TARGET_DOUBLE_FLOAT && TARGET_FPRS && !VECTOR_UNIT_VSX_P (DFmode)" + "(TARGET_POWERPC64 || TARGET_XILINX_FPU || rs6000_cpu == PROCESSOR_PPCE500MC64) + && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS + && !VECTOR_UNIT_VSX_P (DFmode)" "fctidz %0,%1" [(set_attr "type" "fp")]) @@ -7197,11 +7220,24 @@ ;; PowerPC64 DImode operations. -(define_insn_and_split "absdi2" +(define_expand "absdi2" + [(set (match_operand:DI 0 "gpc_reg_operand" "") + (abs:DI (match_operand:DI 1 "gpc_reg_operand" "")))] + "TARGET_POWERPC64" + " +{ + if (TARGET_ISEL) + emit_insn (gen_absdi2_isel (operands[0], operands[1])); + else + emit_insn (gen_absdi2_internal (operands[0], operands[1])); + DONE; +}") + +(define_insn_and_split "absdi2_internal" [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))) (clobber (match_scratch:DI 2 "=&r,&r"))] - "TARGET_POWERPC64" + "TARGET_POWERPC64 && !TARGET_ISEL" "#" "&& reload_completed" [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) @@ -7213,7 +7249,7 @@ [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))) (clobber (match_scratch:DI 2 "=&r,&r"))] - "TARGET_POWERPC64" + "TARGET_POWERPC64 && !TARGET_ISEL" "#" "&& reload_completed" [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) diff -ruN gcc-4.5-20091027/gcc/config/rs6000/rs6000-protos.h gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000-protos.h --- gcc-4.5-20091027/gcc/config/rs6000/rs6000-protos.h 2009-10-27 10:49:12.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000-protos.h 2009-10-27 11:00:02.000000000 -0500 @@ -90,6 +90,7 @@ extern bool rs6000_output_addr_const_extra (FILE *, rtx); extern enum rtx_code rs6000_reverse_condition (enum machine_mode, enum rtx_code); +extern void rs6000_emit_sISEL (enum machine_mode, rtx[]); extern void rs6000_emit_sCOND (enum machine_mode, rtx[]); extern void rs6000_emit_cbranch (enum machine_mode, rtx[]); extern char * output_cbranch (rtx, const char *, int, rtx); diff -ruN gcc-4.5-20091027/gcc/config.gcc gcc-4.5-e500mc64-20091027/gcc/config.gcc --- gcc-4.5-20091027/gcc/config.gcc 2009-10-27 10:49:28.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config.gcc 2009-10-27 11:00:40.000000000 -0500 @@ -327,7 +327,7 @@ extra_headers="ppc-asm.h altivec.h spe.h ppu_intrinsics.h paired.h spu2vmx.h vec_types.h si2vmx.h" need_64bit_hwint=yes case x$with_cpu in - xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[34567]|xpower6x|xrs64a|xcell|xa2) + xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[34567]|xpower6x|xrs64a|xcell|xa2|xe500mc64) cpu_is_64bit=yes ;; esac @@ -3072,7 +3072,7 @@ | 401 | 403 | 405 | 405fp | 440 | 440fp | 464 | 464fp \ | 476 | 476fp | 505 | 601 | 602 | 603 | 603e | ec603e \ | 604 | 604e | 620 | 630 | 740 | 750 | 7400 | 7450 \ - | a2 | e300c[23] | 854[08] | e500mc \ + | a2 | e300c[23] | 854[08] | e500mc | e500mc64 \ | 801 | 821 | 823 | 860 | 970 | G3 | G4 | G5 | cell) # OK ;; diff -ruN gcc-4.5-20091027/gcc/doc/invoke.texi gcc-4.5-e500mc64-20091027/gcc/doc/invoke.texi --- gcc-4.5-20091027/gcc/doc/invoke.texi 2009-10-27 10:42:17.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/doc/invoke.texi 2009-11-03 12:52:17.000000000 -0600 @@ -14656,10 +14656,10 @@ @samp{603e}, @samp{604}, @samp{604e}, @samp{620}, @samp{630}, @samp{740}, @samp{7400}, @samp{7450}, @samp{750}, @samp{801}, @samp{821}, @samp{823}, @samp{860}, @samp{970}, @samp{8540}, @samp{a2}, @samp{e300c2}, -@samp{e300c3}, @samp{e500mc}, @samp{ec603e}, @samp{G3}, @samp{G4}, @samp{G5}, -@samp{power}, @samp{power2}, @samp{power3}, @samp{power4}, -@samp{power5}, @samp{power5+}, @samp{power6}, @samp{power6x}, @samp{power7}, -@samp{common}, @samp{powerpc}, @samp{powerpc64}, @samp{rios}, +@samp{e300c3}, @samp{e500mc}, @samp{e500mc64}, @samp{ec603e}, @samp{G3}, +@samp{G4}, @samp{G5}, @samp{power}, @samp{power2}, @samp{power3}, +@samp{power4}, @samp{power5}, @samp{power5+}, @samp{power6}, @samp{power6x}, +@samp{power7}, @samp{common}, @samp{powerpc}, @samp{powerpc64}, @samp{rios}, @samp{rios1}, @samp{rios2}, @samp{rsc}, and @samp{rs64}. @option{-mcpu=common} selects a completely generic processor. Code diff -ruN gcc-4.5-20091027/gcc/testsuite/gcc.target/powerpc/ppc-eq0-1.c gcc-4.5-e500mc64-20091027/gcc/testsuite/gcc.target/powerpc/ppc-eq0-1.c --- gcc-4.5-20091027/gcc/testsuite/gcc.target/powerpc/ppc-eq0-1.c 2009-10-27 10:42:56.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/testsuite/gcc.target/powerpc/ppc-eq0-1.c 2009-11-03 10:35:53.000000000 -0600 @@ -7,4 +7,4 @@ return x == 0; } -/* { dg-final { scan-assembler "cntlzw" } } */ +/* { dg-final { scan-assembler "cntlzw|isel" } } */ |
|
|
Re: {RFA] PowerPC e500mc64 core supportEdmar,
The support for the processor itself is okay: the scheduling, the cost model, etc. The change in rs6000_override_options to set rs6000_align_branches is indented incorrectly. The changes to the abs patterns seem superficially okay. I need to review the rs6000_emit_sISEL function more carefully. What is not okay are the changes to (define_expand "floatdidf2" (define_insn "*floatdidf2_fpr" (define_expand "fix_truncdfdi2" (define_insn "*fix_truncdfdi2_fpr" Either e500mc64 is a 64 bit processor or not. Either it sets MASK_POWERPC64 or not. Either it operates in the 32 bit subset or not. Either it follows the Linux ABI or not. Either all processors with E500_SINGLE or E500_DOUBLE feature work this way or not. It cannot operate in 32 bit mode "except for this instruction". If Freescale really wants to use that instruction in 32 bit mode for those operations, use custom assembly in libgcc, then it always will work in future iterations because it always can fall back to default libgcc without the special instructions. Creating ABIs that vary with the processor is a road to hell. If Freescale wants to do that, it can supply private patches to customers or through partners because it is going to be incompatible with the rest of the PowerPC world anyway and require a custom distribution and toolchain. Someone should have been thinking ahead more than one processor generation. David |
|
|
Re: {RFA] PowerPC e500mc64 core supportDavid,
We've reviewed our goals and revised the patches with your comments in mind. We think that this version should address your concerns and welcome your feedback if this is not the case. I am still using the same subversion revision 153598 from 2009-10-27 I re-run the regressions tests for both e500mc and 970 targets under these conditions: --enable-checking --disable-decimal-float --enable-languages=c,c++,fortran Please let us know if you see any further concerns prior to applying. Regards, Edmar 2009-11-03 Edmar Wienskoski edmar@... * config.gcc (cpu_is_64bit): Add new core e500mc64. (powerpc*-*-*): Add new core e500mc64. * config/rs6000/e500mc64.md: New file. * config/rs6000/rs6000.c (processor_costs): Add new costs for e500mc64. (rs6000_override_options): Add e500mc64 case to processor_target_table. Altivec and Spe options not allowed with e500mc64. Disable string instructions for e500mc64. Enable branch targets alignment for both e500mc and e500mc64. Initialize rs6000_cost for e500mc64. (rs6000_emit_sISEL): New function. (rs6000_emit_sCOND): Call rs6000_emit_sISEL for isel targets. (rs6000_emit_int_cmove): Fix mode of 64 bit isel pattern generation. (rs6000_issue_rate): Set issue rate for e500mc64. (rs6000_rtx_costs): Set more accurate cost for mfcr instruction on architectures with isel. * config/rs6000/rs6000-protos.h: Declare new function. * config/rs6000/rs6000.h (processor_type): Add PROCESSOR_PPCE500MC64. (ASM_CPU_SPEC): Add e500mc64. * config/rs6000/rs6000.md (define_attr "cpu"): Add ppce500mc64. Include e500mc64.md. (abssi2_isel): Expand pattern to handle DImode. (nabs<mode>2_isel): New pattern. (absdi2): Change pattern to handle 64 bit isel targets. (absdi2_internal): Exclude isel targets. (nabsdi2): Exclude isel targets. * doc/invoke.texi: Add e500mc64 to list of cpus. 2009-11-03 Edmar Wienskoski edmar@... * gcc.target/powerpc/ppc-eq0-1.c: Adjust testcase for isel targets. diff -ruN gcc-4.5-20091027/gcc/config/rs6000/e500mc64.md gcc-4.5-e500mc64-20091027/gcc/config/rs6000/e500mc64.md --- gcc-4.5-20091027/gcc/config/rs6000/e500mc64.md 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/e500mc64.md 2009-11-06 15:42:17.000000000 -0600 @@ -0,0 +1,191 @@ +;; Pipeline description for Motorola PowerPC e500mc64 core. +;; Copyright (C) 2009 Free Software Foundation, Inc. +;; Contributed by Edmar Wienskoski (edmar@...) +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; <http://www.gnu.org/licenses/>. +;; +;; e500mc64 64-bit SU(2), LSU, FPU, BPU +;; Max issue 3 insns/clock cycle (includes 1 branch) + +(define_automaton "e500mc64_most,e500mc64_long,e500mc64_retire") +(define_cpu_unit "e500mc64_decode_0,e500mc64_decode_1" "e500mc64_most") +(define_cpu_unit "e500mc64_issue_0,e500mc64_issue_1" "e500mc64_most") +(define_cpu_unit "e500mc64_retire_0,e500mc64_retire_1" "e500mc64_retire") + +;; SU. +(define_cpu_unit "e500mc64_su0_stage0,e500mc64_su1_stage0" "e500mc64_most") + +;; MU. +(define_cpu_unit "e500mc64_mu_stage0,e500mc64_mu_stage1" "e500mc64_most") +(define_cpu_unit "e500mc64_mu_stage2,e500mc64_mu_stage3" "e500mc64_most") + +;; Non-pipelined division. +(define_cpu_unit "e500mc64_mu_div" "e500mc64_long") + +;; LSU. +(define_cpu_unit "e500mc64_lsu" "e500mc64_most") + +;; FPU. +(define_cpu_unit "e500mc64_fpu" "e500mc64_most") + +;; Branch unit. +(define_cpu_unit "e500mc64_bu" "e500mc64_most") + +;; The following units are used to make the automata deterministic. +(define_cpu_unit "present_e500mc64_decode_0" "e500mc64_most") +(define_cpu_unit "present_e500mc64_issue_0" "e500mc64_most") +(define_cpu_unit "present_e500mc64_retire_0" "e500mc64_retire") +(define_cpu_unit "present_e500mc64_su0_stage0" "e500mc64_most") + +;; The following sets to make automata deterministic when option ndfa is used. +(presence_set "present_e500mc64_decode_0" "e500mc64_decode_0") +(presence_set "present_e500mc64_issue_0" "e500mc64_issue_0") +(presence_set "present_e500mc64_retire_0" "e500mc64_retire_0") +(presence_set "present_e500mc64_su0_stage0" "e500mc64_su0_stage0") + +;; Some useful abbreviations. +(define_reservation "e500mc64_decode" + "e500mc64_decode_0|e500mc64_decode_1+present_e500mc64_decode_0") +(define_reservation "e500mc64_issue" + "e500mc64_issue_0|e500mc64_issue_1+present_e500mc64_issue_0") +(define_reservation "e500mc64_retire" + "e500mc64_retire_0|e500mc64_retire_1+present_e500mc64_retire_0") +(define_reservation "e500mc64_su_stage0" + "e500mc64_su0_stage0|e500mc64_su1_stage0+present_e500mc64_su0_stage0") + +;; Simple SU insns. +(define_insn_reservation "e500mc64_su" 1 + (and (eq_attr "type" "integer,insert_word,insert_dword,delayed_compare,\ + shift,cntlz,exts") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +(define_insn_reservation "e500mc64_su2" 2 + (and (eq_attr "type" "cmp,compare,delayed_compare,fast_compare,trap") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0,e500mc64_retire") + +(define_insn_reservation "e500mc64_delayed" 2 + (and (eq_attr "type" "var_shift_rotate,var_delayed_compare") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0,e500mc64_retire") + +(define_insn_reservation "e500mc64_two" 2 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ + e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +(define_insn_reservation "e500mc64_three" 3 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ + e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ + e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +;; Multiply. +(define_insn_reservation "e500mc64_multiply" 4 + (and (eq_attr "type" "imul,imul2,imul3,imul_compare") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_mu_stage0,e500mc64_mu_stage1,\ + e500mc64_mu_stage2,e500mc64_mu_stage3+e500mc64_retire") + +;; Divide. We use the average latency time here. +(define_insn_reservation "e500mc64_divide" 14 + (and (eq_attr "type" "idiv") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_mu_stage0+e500mc64_mu_div,\ + e500mc64_mu_div*13") + +;; Branch. +(define_insn_reservation "e500mc64_branch" 1 + (and (eq_attr "type" "jmpreg,branch,isync") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_bu,e500mc64_retire") + +;; CR logical. +(define_insn_reservation "e500mc64_cr_logical" 1 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_bu,e500mc64_retire") + +;; Mfcr. +(define_insn_reservation "e500mc64_mfcr" 4 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su1_stage0,e500mc64_su1_stage0*3+e500mc64_retire") + +;; Mtcrf. +(define_insn_reservation "e500mc64_mtcrf" 1 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su1_stage0+e500mc64_retire") + +;; Mtjmpr. +(define_insn_reservation "e500mc64_mtjmpr" 1 + (and (eq_attr "type" "mtjmpr,mfjmpr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +;; Brinc. +(define_insn_reservation "e500mc64_brinc" 1 + (and (eq_attr "type" "brinc") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +;; Loads. +(define_insn_reservation "e500mc64_load" 3 + (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\ + load_l,sync") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") + +(define_insn_reservation "e500mc64_fpload" 4 + (and (eq_attr "type" "fpload,fpload_ux,fpload_u") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing*2,e500mc64_retire") + +;; Stores. +(define_insn_reservation "e500mc64_store" 3 + (and (eq_attr "type" "store,store_ux,store_u,store_c") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") + +(define_insn_reservation "e500mc64_fpstore" 3 + (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") + +;; The following ignores the retire unit to avoid a large automata. + +;; FP. +(define_insn_reservation "e500mc64_float" 7 + (and (eq_attr "type" "fpsimple,fp,fpcompare,dmul") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_fpu") +; "e500mc64_decode,e500mc64_issue+e500mc64_fpu,nothing*5,e500mc64_retire") + +;; FP divides are not pipelined. +(define_insn_reservation "e500mc64_sdiv" 20 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_fpu,e500mc64_fpu*19") + +(define_insn_reservation "e500mc64_ddiv" 35 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_fpu,e500mc64_fpu*34") diff -ruN gcc-4.5-20091027/gcc/config/rs6000/rs6000.c gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.c --- gcc-4.5-20091027/gcc/config/rs6000/rs6000.c 2009-10-27 10:49:12.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.c 2009-11-09 12:38:35.000000000 -0600 @@ -761,6 +761,25 @@ 1, /* prefetch streams /*/ }; +/* Instruction costs on PPCE500MC64 processors. */ +static const +struct processor_costs ppce500mc64_cost = { + COSTS_N_INSNS (4), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (4), /* mulsi_const9 */ + COSTS_N_INSNS (4), /* muldi */ + COSTS_N_INSNS (14), /* divsi */ + COSTS_N_INSNS (14), /* divdi */ + COSTS_N_INSNS (4), /* fp */ + COSTS_N_INSNS (10), /* dmul */ + COSTS_N_INSNS (36), /* sdiv */ + COSTS_N_INSNS (66), /* ddiv */ + 64, /* cache line size */ + 32, /* l1 cache */ + 128, /* l2 cache */ + 1, /* prefetch streams /*/ +}; + /* Instruction costs on POWER4 and POWER5 processors. */ static const struct processor_costs power4_cost = { @@ -2217,6 +2236,8 @@ {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK}, {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ISEL}, + {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64 + | MASK_PPC_GFXOPT | MASK_ISEL}, {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"970", PROCESSOR_POWER4, POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64}, @@ -2345,7 +2366,7 @@ } if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3 - || rs6000_cpu == PROCESSOR_PPCE500MC) + || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64) { if (TARGET_ALTIVEC) error ("AltiVec not supported in this target"); @@ -2537,7 +2558,8 @@ SUB3TARGET_OVERRIDE_OPTIONS; #endif - if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC) + if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC + || rs6000_cpu == PROCESSOR_PPCE500MC64) { /* The e500 and e500mc do not have string instructions, and we set MASK_STRING above when optimizing for size. */ @@ -2574,7 +2596,9 @@ rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4 || rs6000_cpu == PROCESSOR_POWER5 || rs6000_cpu == PROCESSOR_POWER6 - || rs6000_cpu == PROCESSOR_POWER7); + || rs6000_cpu == PROCESSOR_POWER7 + || rs6000_cpu == PROCESSOR_PPCE500MC + || rs6000_cpu == PROCESSOR_PPCE500MC64); /* Allow debug switches to override the above settings. */ if (TARGET_ALWAYS_HINT > 0) @@ -2776,6 +2800,10 @@ rs6000_cost = &ppce500mc_cost; break; + case PROCESSOR_PPCE500MC64: + rs6000_cost = &ppce500mc64_cost; + break; + case PROCESSOR_POWER4: case PROCESSOR_POWER5: rs6000_cost = &power4_cost; @@ -15433,6 +15461,53 @@ /* Emit the RTL for an sCOND pattern. */ void +rs6000_emit_sISEL (enum machine_mode mode, rtx operands[]) +{ + rtx condition_rtx; + enum machine_mode op_mode; + enum rtx_code cond_code; + rtx result = operands[0]; + + condition_rtx = rs6000_generate_compare (operands[1], mode); + cond_code = GET_CODE (condition_rtx); + + op_mode = GET_MODE (XEXP (operands[1], 0)); + if (op_mode == VOIDmode) + op_mode = GET_MODE (XEXP (operands[1], 1)); + + if (TARGET_POWERPC64 && GET_MODE (result) == DImode) + { + PUT_MODE (condition_rtx, DImode); + if (cond_code == GEU || cond_code == GTU || cond_code == LEU + || cond_code == LTU) + emit_insn (gen_isel_unsigned_di (result, condition_rtx, + force_reg (DImode, const1_rtx), + force_reg (DImode, const0_rtx), + XEXP (condition_rtx, 0))); + else + emit_insn (gen_isel_signed_di (result, condition_rtx, + force_reg (DImode, const1_rtx), + force_reg (DImode, const0_rtx), + XEXP (condition_rtx, 0))); + } + else + { + PUT_MODE (condition_rtx, SImode); + if (cond_code == GEU || cond_code == GTU || cond_code == LEU + || cond_code == LTU) + emit_insn (gen_isel_unsigned_si (result, condition_rtx, + force_reg (SImode, const1_rtx), + force_reg (SImode, const0_rtx), + XEXP (condition_rtx, 0))); + else + emit_insn (gen_isel_signed_si (result, condition_rtx, + force_reg (SImode, const1_rtx), + force_reg (SImode, const0_rtx), + XEXP (condition_rtx, 0))); + } +} + +void rs6000_emit_sCOND (enum machine_mode mode, rtx operands[]) { rtx condition_rtx; @@ -15440,6 +15515,12 @@ enum rtx_code cond_code; rtx result = operands[0]; + if (TARGET_ISEL && (mode == SImode || mode == DImode)) + { + rs6000_emit_sISEL (mode, operands); + return; + } + condition_rtx = rs6000_generate_compare (operands[1], mode); cond_code = GET_CODE (condition_rtx); @@ -16089,7 +16170,7 @@ rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond) { rtx condition_rtx, cr; - enum machine_mode mode = GET_MODE (XEXP (op, 0)); + enum machine_mode mode = GET_MODE (dest); if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode)) return 0; @@ -16097,7 +16178,7 @@ /* We still have to do the compare, because isel doesn't do a compare, it just looks at the CRx bits set by a previous compare instruction. */ - condition_rtx = rs6000_generate_compare (op, SImode); + condition_rtx = rs6000_generate_compare (op, mode); cr = XEXP (condition_rtx, 0); if (mode == SImode) @@ -21952,6 +22033,7 @@ case CPU_PPCE300C2: case CPU_PPCE300C3: case CPU_PPCE500MC: + case CPU_PPCE500MC64: return 2; case CPU_RIOS2: case CPU_PPC476: @@ -24765,7 +24847,10 @@ { if (XEXP (x, 1) == const0_rtx) { - *total = COSTS_N_INSNS (2); + if (TARGET_ISEL) + *total = COSTS_N_INSNS (8); + else + *total = COSTS_N_INSNS (2); return true; } else if (mode == Pmode) @@ -24781,7 +24866,10 @@ case UNORDERED: if (outer_code == SET && (XEXP (x, 1) == const0_rtx)) { - *total = COSTS_N_INSNS (2); + if (TARGET_ISEL) + *total = COSTS_N_INSNS (8); + else + *total = COSTS_N_INSNS (2); return true; } /* CC COMPARE. */ diff -ruN gcc-4.5-20091027/gcc/config/rs6000/rs6000.h gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.h --- gcc-4.5-20091027/gcc/config/rs6000/rs6000.h 2009-10-27 10:49:12.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.h 2009-11-04 10:34:41.000000000 -0600 @@ -158,6 +158,7 @@ %{mcpu=e300c2: -me300} \ %{mcpu=e300c3: -me300} \ %{mcpu=e500mc: -me500mc} \ +%{mcpu=e500mc64: -me500mc64} \ %{maltivec: -maltivec} \ -many" @@ -341,6 +342,7 @@ PROCESSOR_PPCE300C2, PROCESSOR_PPCE300C3, PROCESSOR_PPCE500MC, + PROCESSOR_PPCE500MC64, PROCESSOR_POWER4, PROCESSOR_POWER5, PROCESSOR_POWER6, diff -ruN gcc-4.5-20091027/gcc/config/rs6000/rs6000.md gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.md --- gcc-4.5-20091027/gcc/config/rs6000/rs6000.md 2009-10-27 10:49:12.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000.md 2009-11-06 14:19:45.000000000 -0600 @@ -139,7 +139,7 @@ ;; Processor type -- this attribute must exactly match the processor_type ;; enumeration in rs6000.h. -(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,power4,power5,power6,power7,cell,ppca2" +(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,power4,power5,power6,power7,cell,ppca2" (const (symbol_ref "rs6000_cpu_attr"))) @@ -166,6 +166,7 @@ (include "8540.md") (include "e300c2c3.md") (include "e500mc.md") +(include "e500mc64.md") (include "power4.md") (include "power5.md") (include "power6.md") @@ -2077,23 +2078,42 @@ "TARGET_POWER" "abs %0,%1") -(define_insn_and_split "abssi2_isel" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (abs:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) - (clobber (match_scratch:SI 2 "=&b")) +(define_insn_and_split "abs<mode>2_isel" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (abs:GPR (match_operand:GPR 1 "gpc_reg_operand" "b"))) + (clobber (match_scratch:GPR 2 "=&b")) (clobber (match_scratch:CC 3 "=y"))] "TARGET_ISEL" "#" "&& reload_completed" - [(set (match_dup 2) (neg:SI (match_dup 1))) + [(set (match_dup 2) (neg:GPR (match_dup 1))) (set (match_dup 3) (compare:CC (match_dup 1) (const_int 0))) (set (match_dup 0) - (if_then_else:SI (ge (match_dup 3) - (const_int 0)) - (match_dup 1) - (match_dup 2)))] + (if_then_else:GPR (ge (match_dup 3) + (const_int 0)) + (match_dup 1) + (match_dup 2)))] + "") + +(define_insn_and_split "nabs<mode>2_isel" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (neg:GPR (abs:GPR (match_operand:GPR 1 "gpc_reg_operand" "b")))) + (clobber (match_scratch:GPR 2 "=&b")) + (clobber (match_scratch:CC 3 "=y"))] + "TARGET_ISEL" + "#" + "&& reload_completed" + [(set (match_dup 2) (neg:GPR (match_dup 1))) + (set (match_dup 3) + (compare:CC (match_dup 1) + (const_int 0))) + (set (match_dup 0) + (if_then_else:GPR (ge (match_dup 3) + (const_int 0)) + (match_dup 2) + (match_dup 1)))] "") (define_insn_and_split "abssi2_nopower" @@ -6767,8 +6787,9 @@ (define_insn "*fix_truncdfdi2_fpr" [(set (match_operand:DI 0 "gpc_reg_operand" "=!d#r") (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d")))] - "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT - && TARGET_DOUBLE_FLOAT && TARGET_FPRS && !VECTOR_UNIT_VSX_P (DFmode)" + "(TARGET_POWERPC64 || TARGET_XILINX_FPU) + && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS + && !VECTOR_UNIT_VSX_P (DFmode)" "fctidz %0,%1" [(set_attr "type" "fp")]) @@ -7197,11 +7218,24 @@ ;; PowerPC64 DImode operations. -(define_insn_and_split "absdi2" +(define_expand "absdi2" + [(set (match_operand:DI 0 "gpc_reg_operand" "") + (abs:DI (match_operand:DI 1 "gpc_reg_operand" "")))] + "TARGET_POWERPC64" + " +{ + if (TARGET_ISEL) + emit_insn (gen_absdi2_isel (operands[0], operands[1])); + else + emit_insn (gen_absdi2_internal (operands[0], operands[1])); + DONE; +}") + +(define_insn_and_split "absdi2_internal" [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))) (clobber (match_scratch:DI 2 "=&r,&r"))] - "TARGET_POWERPC64" + "TARGET_POWERPC64 && !TARGET_ISEL" "#" "&& reload_completed" [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) @@ -7213,7 +7247,7 @@ [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))) (clobber (match_scratch:DI 2 "=&r,&r"))] - "TARGET_POWERPC64" + "TARGET_POWERPC64 && !TARGET_ISEL" "#" "&& reload_completed" [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) diff -ruN gcc-4.5-20091027/gcc/config/rs6000/rs6000-protos.h gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000-protos.h --- gcc-4.5-20091027/gcc/config/rs6000/rs6000-protos.h 2009-10-27 10:49:12.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config/rs6000/rs6000-protos.h 2009-10-27 11:00:02.000000000 -0500 @@ -90,6 +90,7 @@ extern bool rs6000_output_addr_const_extra (FILE *, rtx); extern enum rtx_code rs6000_reverse_condition (enum machine_mode, enum rtx_code); +extern void rs6000_emit_sISEL (enum machine_mode, rtx[]); extern void rs6000_emit_sCOND (enum machine_mode, rtx[]); extern void rs6000_emit_cbranch (enum machine_mode, rtx[]); extern char * output_cbranch (rtx, const char *, int, rtx); diff -ruN gcc-4.5-20091027/gcc/config.gcc gcc-4.5-e500mc64-20091027/gcc/config.gcc --- gcc-4.5-20091027/gcc/config.gcc 2009-10-27 10:49:28.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/config.gcc 2009-10-27 11:00:40.000000000 -0500 @@ -327,7 +327,7 @@ extra_headers="ppc-asm.h altivec.h spe.h ppu_intrinsics.h paired.h spu2vmx.h vec_types.h si2vmx.h" need_64bit_hwint=yes case x$with_cpu in - xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[34567]|xpower6x|xrs64a|xcell|xa2) + xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[34567]|xpower6x|xrs64a|xcell|xa2|xe500mc64) cpu_is_64bit=yes ;; esac @@ -3072,7 +3072,7 @@ | 401 | 403 | 405 | 405fp | 440 | 440fp | 464 | 464fp \ | 476 | 476fp | 505 | 601 | 602 | 603 | 603e | ec603e \ | 604 | 604e | 620 | 630 | 740 | 750 | 7400 | 7450 \ - | a2 | e300c[23] | 854[08] | e500mc \ + | a2 | e300c[23] | 854[08] | e500mc | e500mc64 \ | 801 | 821 | 823 | 860 | 970 | G3 | G4 | G5 | cell) # OK ;; diff -ruN gcc-4.5-20091027/gcc/doc/invoke.texi gcc-4.5-e500mc64-20091027/gcc/doc/invoke.texi --- gcc-4.5-20091027/gcc/doc/invoke.texi 2009-10-27 10:42:17.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/doc/invoke.texi 2009-11-03 12:52:17.000000000 -0600 @@ -14656,10 +14656,10 @@ @samp{603e}, @samp{604}, @samp{604e}, @samp{620}, @samp{630}, @samp{740}, @samp{7400}, @samp{7450}, @samp{750}, @samp{801}, @samp{821}, @samp{823}, @samp{860}, @samp{970}, @samp{8540}, @samp{a2}, @samp{e300c2}, -@samp{e300c3}, @samp{e500mc}, @samp{ec603e}, @samp{G3}, @samp{G4}, @samp{G5}, -@samp{power}, @samp{power2}, @samp{power3}, @samp{power4}, -@samp{power5}, @samp{power5+}, @samp{power6}, @samp{power6x}, @samp{power7}, -@samp{common}, @samp{powerpc}, @samp{powerpc64}, @samp{rios}, +@samp{e300c3}, @samp{e500mc}, @samp{e500mc64}, @samp{ec603e}, @samp{G3}, +@samp{G4}, @samp{G5}, @samp{power}, @samp{power2}, @samp{power3}, +@samp{power4}, @samp{power5}, @samp{power5+}, @samp{power6}, @samp{power6x}, +@samp{power7}, @samp{common}, @samp{powerpc}, @samp{powerpc64}, @samp{rios}, @samp{rios1}, @samp{rios2}, @samp{rsc}, and @samp{rs64}. @option{-mcpu=common} selects a completely generic processor. Code diff -ruN gcc-4.5-20091027/gcc/testsuite/gcc.target/powerpc/ppc-eq0-1.c gcc-4.5-e500mc64-20091027/gcc/testsuite/gcc.target/powerpc/ppc-eq0-1.c --- gcc-4.5-20091027/gcc/testsuite/gcc.target/powerpc/ppc-eq0-1.c 2009-10-27 10:42:56.000000000 -0500 +++ gcc-4.5-e500mc64-20091027/gcc/testsuite/gcc.target/powerpc/ppc-eq0-1.c 2009-11-03 10:35:53.000000000 -0600 @@ -7,4 +7,4 @@ return x == 0; } -/* { dg-final { scan-assembler "cntlzw" } } */ +/* { dg-final { scan-assembler "cntlzw|isel" } } */ |
|
|
Re: {RFA] PowerPC e500mc64 core supportOn Wed, Nov 11, 2009 at 12:42 PM, Edmar Wienskoski-RA8797
<edmar@...> wrote: Hi, Edmar This is a lot better. > (rs6000_rtx_costs): Set more accurate cost for mfcr instruction > on architectures with isel. Does this ChangeLog entry mean materializing a truthvalue in a GPR? @@ -24765,7 +24847,10 @@ { if (XEXP (x, 1) == const0_rtx) { - *total = COSTS_N_INSNS (2); + if (TARGET_ISEL) + *total = COSTS_N_INSNS (8); + else + *total = COSTS_N_INSNS (2); return true; } else if (mode == Pmode) @@ -24781,7 +24866,10 @@ case UNORDERED: if (outer_code == SET && (XEXP (x, 1) == const0_rtx)) { - *total = COSTS_N_INSNS (2); + if (TARGET_ISEL) + *total = COSTS_N_INSNS (8); + else + *total = COSTS_N_INSNS (2); return true; } /* CC COMPARE. */ Why are you setting the value to "8"? Current processors that implement isel specify the latency as 1. And e500mc64.md does not define any scheduling information for isel! Thanks, David |
| Free embeddable forum powered by Nabble | Forum Help |