diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7413d675803edc9f8ed7506379469b6382b1d548..ef6c2cac0c9de4bdfa39d934a13638e8cd5b3507 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+Mon Sep 30 21:33:23 CEST 2002  Jan Hubicka  <jh@suse.cz>
+
+	* reload.c (push_reload): Handle subregs and secondary memory.
+	* reload1.c (gen_reload): Likewise.
+
+	* jump.c (reg_or_subregno): New function.
+	* rtl.h (reg_or_subregno): Declare
+	* unroll.c (find_splittable_givs): Handle subregs.
+
 2002-09-30  Mark Mitchell  <mark@codesourcery.com>
 
 	* store-layout.c (finish_record_layout): Add free_p parameter.
diff --git a/gcc/jump.c b/gcc/jump.c
index 5fef7b7311f5edb338e13797b623ca0eeecf731a..3b75110253b505db9458f61e627ffd250936ffef 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -2410,3 +2410,15 @@ true_regnum (x)
     }
   return -1;
 }
+
+/* Return regno of the register REG and handle subregs too.  */
+unsigned int
+reg_or_subregno (reg)
+     rtx reg;
+{
+  if (REG_P (reg))
+    return REGNO (reg);
+  if (GET_CODE (reg) == SUBREG)
+    return REGNO (SUBREG_REG (reg));
+  abort ();
+}
diff --git a/gcc/reload.c b/gcc/reload.c
index ba5d075a988df4d3a3f45d7d3398bb0657b589ec..2b4272265126aaa5e7014f04075d425ad9168e6e 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -1285,9 +1285,9 @@ push_reload (in, out, inloc, outloc, class,
 
 #ifdef SECONDARY_MEMORY_NEEDED
       /* If a memory location is needed for the copy, make one.  */
-      if (in != 0 && GET_CODE (in) == REG
-	  && REGNO (in) < FIRST_PSEUDO_REGISTER
-	  && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (in)),
+      if (in != 0 && (GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
+	  && reg_or_subregno (in) < FIRST_PSEUDO_REGISTER
+	  && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (reg_or_subregno (in)),
 				      class, inmode))
 	get_secondary_mem (in, inmode, opnum, type);
 #endif
@@ -1315,9 +1315,10 @@ push_reload (in, out, inloc, outloc, class,
       n_reloads++;
 
 #ifdef SECONDARY_MEMORY_NEEDED
-      if (out != 0 && GET_CODE (out) == REG
-	  && REGNO (out) < FIRST_PSEUDO_REGISTER
-	  && SECONDARY_MEMORY_NEEDED (class, REGNO_REG_CLASS (REGNO (out)),
+      if (out != 0 && (GET_CODE (out) == REG || GET_CODE (out) == SUBREG)
+	  && reg_or_subregno (out) < FIRST_PSEUDO_REGISTER
+	  && SECONDARY_MEMORY_NEEDED (class,
+				      REGNO_REG_CLASS (reg_or_subregno (out)),
 				      outmode))
 	get_secondary_mem (out, outmode, opnum, type);
 #endif
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 726a4bfcd15e90af3332ac11d3c6c339d5eb5580..ea703f162eaca88a9e638e0537f39677252e1b48 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -7532,10 +7532,12 @@ gen_reload (out, in, opnum, type)
 
 #ifdef SECONDARY_MEMORY_NEEDED
   /* If we need a memory location to do the move, do it that way.  */
-  else if (GET_CODE (in) == REG && REGNO (in) < FIRST_PSEUDO_REGISTER
-	   && GET_CODE (out) == REG && REGNO (out) < FIRST_PSEUDO_REGISTER
-	   && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (in)),
-				       REGNO_REG_CLASS (REGNO (out)),
+  else if ((GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
+	   && reg_or_subregno (in) < FIRST_PSEUDO_REGISTER
+	   && (GET_CODE (out) == REG || GET_CODE (out) == SUBREG)
+	   && reg_or_subregno (out) < FIRST_PSEUDO_REGISTER
+	   && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (reg_or_subregno (in)),
+				       REGNO_REG_CLASS (reg_or_subregno (out)),
 				       GET_MODE (out)))
     {
       /* Get the memory to use and rewrite both registers to its mode.  */
diff --git a/gcc/rtl.h b/gcc/rtl.h
index e2afd90ad43b65e3cd72a1142457b1937217d6cf..d4147c221c0a598f1e6a4e444a4e99ba49a27eb9 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1943,6 +1943,7 @@ extern int invert_jump_1		PARAMS ((rtx, rtx));
 extern int invert_jump			PARAMS ((rtx, rtx, int));
 extern int rtx_renumbered_equal_p	PARAMS ((rtx, rtx));
 extern int true_regnum			PARAMS ((rtx));
+extern unsigned int reg_or_subregno	PARAMS ((rtx));
 extern int redirect_jump_1		PARAMS ((rtx, rtx));
 extern int redirect_jump		PARAMS ((rtx, rtx, int));
 extern void rebuild_jump_labels		PARAMS ((rtx));
diff --git a/gcc/unroll.c b/gcc/unroll.c
index 126b586808d2ca8ab0dacfa9aca628e348bf64c4..a1b0287304323bee9344d91df3f2d2af1d0b0841 100644
--- a/gcc/unroll.c
+++ b/gcc/unroll.c
@@ -2822,7 +2822,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
 		  value = tem;
 		}
 
-	      splittable_regs[REGNO (v->new_reg)] = value;
+	      splittable_regs[reg_or_subregno (v->new_reg)] = value;
 	    }
 	  else
 	    continue;
@@ -2856,7 +2856,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
 	  if (! v->ignore)
 	    count = REG_IV_CLASS (ivs, REGNO (v->src_reg))->biv_count;
 
-	  splittable_regs_updates[REGNO (v->new_reg)] = count;
+	  splittable_regs_updates[reg_or_subregno (v->new_reg)] = count;
 	}
 
       result++;