diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3c3ba0ed321d0ac4e4fb699ed40c9f9900f2c0d4..c1f8098c70bbbc116355e540c2955b8800b4baea 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2012-07-04  Oleg Endo  <olegendo@gcc.gnu.org>
+
+	* config/sh/predicates.md (zero_extend_operand): New predicate.
+	* config/sh/sh.md (zero_extendhisi2): Simplify by using new
+	zero_extend_operand predicate.
+	(zero_extendqisi2): Likewise.
+
 2012-07-04  Uros Bizjak  <ubizjak@gmail.com>
 
 	PR middle-end/53321
diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index 3e7efd3504483d7a156a2b93c71f8087564fe72d..4d793b19c5250cd1a6d519c4103541b403544016 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -368,6 +368,13 @@
 	  : nonimmediate_operand) (op, mode);
 })
 
+;; Returns 1 if the operand can be used in a zero_extend.
+(define_predicate "zero_extend_operand"
+  (ior (and (match_test "TARGET_SHMEDIA")
+	    (match_operand 0 "general_extend_operand"))
+       (and (match_test "! TARGET_SHMEDIA")
+	    (match_operand 0 "arith_reg_operand"))))
+
 ;; Returns 1 if OP can be source of a simple move operation. Same as
 ;; general_operand, but a LABEL_REF is valid, PRE_DEC is invalid as
 ;; are subregs of system registers.
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 1dda1943cba7065f3193e2c1397cec57e694f232..980aa6f30b1b47ef85e12ce1dd038400a3a3cdb7 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -4725,13 +4725,8 @@ label:
 	      (const_string "ignore")))])
 
 (define_expand "zero_extendhisi2"
-  [(set (match_operand:SI 0 "arith_reg_operand" "")
-	(zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
-  ""
-{
-  if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
-    operands[1] = copy_to_mode_reg (HImode, operands[1]);
-})
+  [(set (match_operand:SI 0 "arith_reg_dest" "")
+	(zero_extend:SI (match_operand:HI 1 "zero_extend_operand" "")))])
 
 (define_insn "*zero_extendhisi2_compact"
   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
@@ -4770,13 +4765,8 @@ label:
 })
 
 (define_expand "zero_extendqisi2"
-  [(set (match_operand:SI 0 "arith_reg_operand" "")
-	(zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
-  ""
-{
-  if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
-    operands[1] = copy_to_mode_reg (QImode, operands[1]);
-})
+  [(set (match_operand:SI 0 "arith_reg_dest" "")
+	(zero_extend:SI (match_operand:QI 1 "zero_extend_operand" "")))])
 
 (define_insn "*zero_extendqisi2_compact"
   [(set (match_operand:SI 0 "arith_reg_dest" "=r")