This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: {RFA] PowerPC e500mc64 core support


David,

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@freescale.com

	* 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@freescale.com

	* 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@freescale.com)
+;;
+;; 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" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]