(comment before extendhisi2): Remove the lie.
authorTorbjorn Granlund <tege@gnu.org>
Sat, 26 Sep 1992 22:36:47 +0000 (22:36 +0000)
committerTorbjorn Granlund <tege@gnu.org>
Sat, 26 Sep 1992 22:36:47 +0000 (22:36 +0000)
(zero_extendhisi2): Rewrite to work if op0 == op1.  Use
gen_lowpart in preparation code.
(extendqisi2, extendhisi2): Likewise.
(extendqihi2): Expand.
(restorehi): Rewrite for correctness, efficiency, and
clarity. Avoid generating insns involving truncate.  Generate
needed pseudos in preparation statements.
(storehi): Likewise.
(storeinthi): Likewise.
(movhi): Call gen_storehi, gen_restorehi, gen_storeinthi according
their new definitions.  Use force_reg to put address in register.

From-SVN: r2255

gcc/config/arm/arm.md

index 039266b..ef27cc5 100644 (file)
@@ -41,8 +41,8 @@
 
 (define_insn "addsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
-        (plus:SI (match_operand:SI 1 "register_operand" "r,r")
-                 (match_operand:SI 2 "general_operand" "r,n")))]
+       (plus:SI (match_operand:SI 1 "register_operand" "r,r")
+                (match_operand:SI 2 "general_operand" "r,n")))]
   ""
   "*
   switch (which_alternative)
@@ -56,8 +56,8 @@
 
 (define_insn "addsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
-        (plus:SF (match_operand:SF 1 "register_operand" "f")
-                 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
+       (plus:SF (match_operand:SF 1 "register_operand" "f")
+                (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
   ""
   "*
   return (arm_output_asm_insn (\"adfs\\t%0, %1, %2\", operands));
@@ -65,8 +65,8 @@
 
 (define_insn "adddf3"
   [(set (match_operand:DF 0 "register_operand" "=f")
-        (plus:DF (match_operand:DF 1 "register_operand" "f")
-                 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
+       (plus:DF (match_operand:DF 1 "register_operand" "f")
+                (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
   ""
   "*
   return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));
@@ -84,8 +84,8 @@
 
 (define_insn "subsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
-        (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
-                  (match_operand:SI 2 "general_operand" "r,n,r")))]
+       (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
+                 (match_operand:SI 2 "general_operand" "r,n,r")))]
   ""
   "*
   switch (which_alternative)
 
 (define_insn "subsf3"
   [(set (match_operand:SF 0 "register_operand" "=f,f")
-        (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
-                  (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
+       (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
+                 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
   ""
   "*
   switch (which_alternative)
 
 (define_insn "subdf3"
   [(set (match_operand:DF 0 "register_operand" "=f,f")
-        (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
+       (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
       (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
   ""
   "*
 ;; The `&' is too strict, but at least generates correct code.
 (define_insn "mulsi3"
   [(set (match_operand:SI 0 "register_operand" "=&r")
-        (mult:SI (match_operand:SI 1 "register_operand" "%r")
-                 (match_operand:SI 2 "register_operand" "r")))]
+       (mult:SI (match_operand:SI 1 "register_operand" "%r")
+                (match_operand:SI 2 "register_operand" "r")))]
   ""
   "*
   if (REGNO (operands[0]) == REGNO (operands[1]))
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=&r")
-        (plus:SI
-          (mult:SI (match_operand:SI 1 "register_operand" "%r")
-                   (match_operand:SI 2 "register_operand" "r"))
-          (match_operand:SI 3 "register_operand" "r")))]
+       (plus:SI
+         (mult:SI (match_operand:SI 1 "register_operand" "%r")
+                  (match_operand:SI 2 "register_operand" "r"))
+         (match_operand:SI 3 "register_operand" "r")))]
   ""
   "*
   if (REGNO (operands[0]) == REGNO (operands[1]))
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=&r")
-        (plus:SI
-          (match_operand:SI 3 "register_operand" "r")
-          (mult:SI (match_operand:SI 1 "register_operand" "%r")
-                   (match_operand:SI 2 "register_operand" "r"))))]
+       (plus:SI
+         (match_operand:SI 3 "register_operand" "r")
+         (mult:SI (match_operand:SI 1 "register_operand" "%r")
+                  (match_operand:SI 2 "register_operand" "r"))))]
   ""
   "*
   if (REGNO (operands[0]) == REGNO (operands[1]))
 
 (define_insn "mulsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
-        (mult:SF (match_operand:SF 1 "register_operand" "f")
-                 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
+       (mult:SF (match_operand:SF 1 "register_operand" "f")
+                (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
   ""
   "*return (arm_output_asm_insn (\"mufs\\t%0, %1, %2\", operands));")
 
 (define_insn "muldf3"
   [(set (match_operand:DF 0 "register_operand" "=f")
-        (mult:DF (match_operand:DF 1 "register_operand" "f")
-                 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
+       (mult:DF (match_operand:DF 1 "register_operand" "f")
+                (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
   ""
   "*
   return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands));
 
 (define_insn "divsf3"
   [(set (match_operand:SF 0 "register_operand" "=f,f")
-        (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
-                (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
+       (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
+               (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
   ""
   "*
   switch (which_alternative)
 
 (define_insn "divdf3"
   [(set (match_operand:DF 0 "register_operand" "=f,f")
-        (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
-                (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
+       (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
+               (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
   ""
   "*
   switch (which_alternative)
 
 (define_insn "modsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
-        (mod:SF (match_operand:SF 1 "register_operand" "f")
-                (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
+       (mod:SF (match_operand:SF 1 "register_operand" "f")
+               (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
   ""
   "*
   return (arm_output_asm_insn (\"rmfs\\t%0, %1, %2\", operands));
 
 (define_insn "moddf3"
   [(set (match_operand:DF 0 "register_operand" "=f")
-        (mod:DF (match_operand:DF 1 "register_operand" "f")
-                (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
+       (mod:DF (match_operand:DF 1 "register_operand" "f")
+               (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
   ""
   "*
   return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands));
 
 (define_insn "andsi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
-        (and:SI (match_operand:SI 1 "register_operand" "r")
-                (match_operand:SI 2 "arm_rhs_operand" "rI")))]
+       (and:SI (match_operand:SI 1 "register_operand" "r")
+               (match_operand:SI 2 "arm_rhs_operand" "rI")))]
   ""
   "*
   return (arm_output_asm_insn (\"and\\t%0, %1, %2\", operands));
 
 (define_insn "andcbsi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
-        (and:SI (match_operand:SI 1 "register_operand" "r")
-                (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
+       (and:SI (match_operand:SI 1 "register_operand" "r")
+               (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
   ""
   "*
   return (arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands));
 
 (define_insn "iorsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
-        (ior:SI (match_operand:SI 1 "register_operand" "r,r")
-                (match_operand:SI 2 "nonmemory_operand" "r,n")))]
+       (ior:SI (match_operand:SI 1 "register_operand" "r,r")
+               (match_operand:SI 2 "nonmemory_operand" "r,n")))]
   ""
   "*
   switch (which_alternative)
 
 (define_insn "xorsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
-        (xor:SI (match_operand:SI 1 "register_operand" "r,r")
-                (match_operand:SI 2 "nonmemory_operand" "r,n")))]
+       (xor:SI (match_operand:SI 1 "register_operand" "r,r")
+               (match_operand:SI 2 "nonmemory_operand" "r,n")))]
   ""
   "*
   switch (which_alternative)
     case 1:
       return (output_multi_immediate (operands,
                                      \"eor\\t%0, %1, %2\", \"eor\\t%0, %0, %2\",
-                                     2, INTVAL (operands[2])));
+                                     2, INTVAL (operands[2])));
     }
 ")
 \f
 
 (define_insn "ashlsi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
-        (ashift:SI (match_operand:SI 1 "register_operand" "r")
-                   (match_operand:SI 2 "general_operand" "rn")))]
+       (ashift:SI (match_operand:SI 1 "register_operand" "r")
+                  (match_operand:SI 2 "general_operand" "rn")))]
   ""
   "*
   return (output_shifted_move (ASHIFT, operands));
 
 (define_insn "ashrsi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
-        (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
-                     (match_operand:SI 2 "general_operand" "rn")))]
+       (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
+                    (match_operand:SI 2 "general_operand" "rn")))]
   ""
   "*
   return (output_shifted_move (ASHIFTRT, operands));
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
-        (lshift:SI (match_operand:SI 1 "register_operand" "r")
-                   (match_operand:SI 2 "general_operand" "rn")))]
+       (lshift:SI (match_operand:SI 1 "register_operand" "r")
+                  (match_operand:SI 2 "general_operand" "rn")))]
   ""
   "*
   return (output_shifted_move (LSHIFT, operands));
 
 (define_insn "lshrsi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
-        (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
-                     (match_operand:SI 2 "general_operand" "rn")))]
+       (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+                    (match_operand:SI 2 "general_operand" "rn")))]
   ""
   "*
   return (output_shifted_move (LSHIFTRT, operands));
 
 (define_insn "rotrsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
-        (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
-                     (match_operand:SI 2 "general_operand" "r,n")))]
+       (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
+                    (match_operand:SI 2 "general_operand" "r,n")))]
   ""
   "*
   switch (which_alternative)
       return (arm_output_asm_insn (\"mov\\t%0, %1,ror %2\", operands));
     case 1:
       if (INTVAL(operands[2]) > 31)
-        operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 32);
+       operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 32);
       return (arm_output_asm_insn (\"mov\\t%0, %1,ror%2\", operands));
     }
 ")
 
 (define_insn "negdi2"
   [(set (match_operand:DI 0 "di_operand" "=r")
-        (neg:DI (match_operand:DI 1 "di_operand" "r")))]
+       (neg:DI (match_operand:DI 1 "di_operand" "r")))]
   ""
   "*
   arm_output_asm_insn (\"rsb\\t%0, %1, #0\", operands);
 
 (define_insn "negsi2"
   [(set (match_operand:SI 0 "register_operand" "=r")
-        (neg:SI (match_operand:SI 1 "register_operand" "r")))]
+       (neg:SI (match_operand:SI 1 "register_operand" "r")))]
   ""
   "*
   return (arm_output_asm_insn (\"rsb\\t%0, %1, #0\", operands));
 
 (define_insn "negsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
-        (neg:SF (match_operand:SF 1 "register_operand" "f")))]
+       (neg:SF (match_operand:SF 1 "register_operand" "f")))]
   ""
   "*
   return (arm_output_asm_insn (\"mnfs\\t%0, %1\", operands));
 
 (define_insn "negdf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
-        (neg:DF (match_operand:DF 1 "register_operand" "f")))]
+       (neg:DF (match_operand:DF 1 "register_operand" "f")))]
   ""
   "*
   return (arm_output_asm_insn (\"mnfd\\t%0, %1\", operands));
 
 (define_insn "abssf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
-         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
+        (abs:SF (match_operand:SF 1 "register_operand" "f")))]
   ""
   "*
   return (arm_output_asm_insn (\"abss\\t%0, %1\", operands));
 
 (define_insn "absdf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
-        (abs:DF (match_operand:DF 1 "register_operand" "f")))]
+       (abs:DF (match_operand:DF 1 "register_operand" "f")))]
   ""
   "*
   return (arm_output_asm_insn (\"absd\\t%0, %1\", operands));
 
 (define_insn "sqrtsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
-        (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
+       (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
   ""
   "*
   return (arm_output_asm_insn (\"sqts\\t%0, %1\", operands));
 
 (define_insn "sqrtdf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
-        (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
+       (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
   ""
   "*
   return (arm_output_asm_insn (\"sqtd\\t%0, %1\", operands));
 
 (define_insn "one_cmplsi2"
   [(set (match_operand:SI 0 "register_operand" "=r")
-        (not:SI (match_operand:SI 1 "register_operand" "r")))]
+       (not:SI (match_operand:SI 1 "register_operand" "r")))]
   ""
   "*
   return (arm_output_asm_insn (\"mvn\\t%0, %1\", operands));
 
 (define_insn "floatsisf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
-        (float:SF (match_operand:SI 1 "register_operand" "r")))]
+       (float:SF (match_operand:SI 1 "register_operand" "r")))]
   ""
   "*
   return (arm_output_asm_insn (\"flts\\t%0, %1\", operands));
 
 (define_insn "floatsidf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
-        (float:DF (match_operand:SI 1 "register_operand" "r")))]
+       (float:DF (match_operand:SI 1 "register_operand" "r")))]
   ""
   "*
   return (arm_output_asm_insn (\"fltd\\t%0, %1\", operands));
 
 (define_insn "truncdfsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
-        (float_truncate:SF
-            (match_operand:DF 1 "register_operand" "f")))]
+       (float_truncate:SF
+        (match_operand:DF 1 "register_operand" "f")))]
   ""
   "*
   return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands));
 ;; Zero extension instructions.
 
 (define_expand "zero_extendhisi2"
-  [(set (match_operand:SI 0 "register_operand" "")
+  [(set (match_dup 2)
        (ashift:SI (match_operand:HI 1 "register_operand" "")
                   (const_int 16)))
-   (set (match_dup 0)
-       (lshiftrt:SI (match_dup 0) (const_int 16)))]
+   (set (match_operand:SI 0 "register_operand" "")
+       (lshiftrt:SI (match_dup 2)
+                    (const_int 16)))]
   ""
   "
-  if (GET_CODE (operands[1]) == SUBREG)
-      operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
-                             SUBREG_WORD (operands[1]));
-  else
-      operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
-")
+{ operands[1] = gen_lowpart (SImode, operands[1]);
+  operands[2] = gen_reg_rtx (SImode); }")
 
 (define_insn "zero_extendqihi2"
   [(set (match_operand:HI 0 "register_operand" "=r")
-        (zero_extend:HI
+       (zero_extend:HI
         (match_operand:QI 1 "register_operand" "r")))]
   ""
   "*
 
 (define_insn "zero_extendqisi2"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
-        (zero_extend:SI
+       (zero_extend:SI
         (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
   ""
   "*
     }
 ")
 
-;; Note that the ones starting from HImode come before those for QImode so
-;; that a constant operand will match HImode, not QImode.
-
 (define_expand "extendhisi2"
-  [(set (match_operand:SI 0 "register_operand" "")
+  [(set (match_dup 2)
        (ashift:SI (match_operand:HI 1 "register_operand" "")
                   (const_int 16)))
-   (set (match_dup 0)
-       (ashiftrt:SI (match_dup 0) (const_int 16)))]
+   (set (match_operand:SI 0 "register_operand" "")
+       (ashiftrt:SI (match_dup 2)
+                    (const_int 16)))]
   ""
   "
-  if (GET_CODE (operands[1]) == SUBREG)
-      operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
-                             SUBREG_WORD (operands[1]));
-  else
-      operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
-")
-
-;; XXX Is this ever used?
+{ operands[1] = gen_lowpart (SImode, operands[1]);
+  operands[2] = gen_reg_rtx (SImode); }")
 
-(define_insn "extendqihi2"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-       (sign_extend:SI
-        (match_operand:QI 1 "register_operand" "r")))]
+(define_expand "extendqihi2"
+  [(set (match_dup 2)
+       (ashift:SI (match_operand:QI 1 "register_operand" "")
+                  (const_int 24)))
+   (set (match_operand:HI 0 "register_operand" "")
+       (ashiftrt:SI (match_dup 2)
+                    (const_int 24)))]
   ""
-  "*
-  arm_output_asm_insn (\"mov\\t%0, %1, lsl#24\\t@ extendqihi\", operands);
-  return (arm_output_asm_insn (\"mov\\t%0, %0, asr#24\", operands));
-")
-
+  "
+{ operands[0] = gen_lowpart (SImode, operands[0]);
+  operands[1] = gen_lowpart (SImode, operands[1]);
+  operands[2] = gen_reg_rtx (SImode); }")
 
 (define_expand "extendqisi2"
-  [(set (match_operand:SI 0 "register_operand" "")
+  [(set (match_dup 2)
        (ashift:SI (match_operand:QI 1 "register_operand" "")
                   (const_int 24)))
-   (set (match_dup 0)
-       (ashiftrt:SI (match_dup 0) (const_int 24)))]
+   (set (match_operand:SI 0 "register_operand" "")
+       (ashiftrt:SI (match_dup 2)
+                    (const_int 24)))]
   ""
   "
-  if (GET_CODE (operands[1]) == SUBREG)
-      operands[1] = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
-                             SUBREG_WORD(operands[1]));
-  else
-      operands[1] = gen_rtx (SUBREG, SImode, operands[1], 0);
-")
+{ operands[1] = gen_lowpart (SImode, operands[1]);
+  operands[2] = gen_reg_rtx (SImode); }")
 
 (define_insn "extendsfdf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
-        (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
+       (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
   ""
   "*
   return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands));
 
 (define_insn "movdi"
   [(set (match_operand:DI 0 "di_operand" "=r,r,r,o,r")
-        (match_operand:DI 1 "di_operand" "r,n,o,r,F"))]
+       (match_operand:DI 1 "di_operand" "r,n,o,r,F"))]
   ""
   "*
   return (output_move_double (operands));
 
 (define_insn "movsi"
   [(set (match_operand:SI 0 "general_operand" "=r,r,r,m")
-        (match_operand:SI 1 "general_operand"  "r,n,m,r"))]
+       (match_operand:SI 1 "general_operand"  "r,n,m,r"))]
   ""
   "*
   switch (which_alternative)
       return (output_mov_immediate (operands));
     case 2:
       if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
-          &&  CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
+         &&  CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
        return (arm_output_llc (operands));
       else
-        return (arm_output_asm_insn (\"ldr\\t%0, %1\", operands));
+       return (arm_output_asm_insn (\"ldr\\t%0, %1\", operands));
     case 3:
       return (arm_output_asm_insn (\"str\\t%1, %0\", operands));
     }
 ;; storehi is not allowed.
 
 (define_expand "restorehi"
-  [(set (mem:QI (match_operand:SI 1 "address_operand" ""))
-       (truncate:QI (match_operand:HI 0 "register_operand" "")))
-   (set (reg:HI 10)
-       (ashiftrt:HI (match_dup 0) (const_int 8)))
+  [(set (mem:QI (match_operand 1 "" ""))
+       (match_dup 2))
+   (set (reg:SI 10)
+       (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
    (set (mem:QI (plus:SI (match_dup 1) (const_int 1)))
-       (truncate:QI (reg:HI 10)))]
-  "" "")
+       (reg:QI 10))]
+  ""
+  "
+{
+  operands[2] = gen_lowpart (QImode, operands[0]);
+  operands[0] = gen_lowpart (SImode, operands[0]);
+}")
 
 ;; Subroutine to store a half word from a register into memory.
 ;; Operand 0 is the source register (HImode)
-;; Operand 1 is the destination address (SImode)
-;; Operand 2 is a temporary (SImode).
-;; Operand 3 is a temporary (SImode).
-;; Operand 4 is a temporary (SImode).
+;; Operand 1 is the destination address in a register (SImode)
 
 (define_expand "storehi"
-  [;; compute the address into a register
-   (set (match_operand:SI 2 "register_operand" "")
-        (match_operand:SI 1 "address_operand" ""))
-   ;; get the half word into a full word register
-   (set (match_operand:SI 3 "register_operand" "")
-        (match_operand:HI 0 "register_operand" ""))
-   ;; store the low byte
-   (set (mem:QI (match_dup 2))
-        (truncate:QI (match_dup 3)))
+  [;; store the low byte
+   (set (mem:QI (match_operand 1 "" "")) (match_dup 3))
    ;; extract the high byte
-   (set (match_operand:SI 4 "register_operand" "")
-        (ashiftrt:SI (match_dup 3) (const_int 8)))
+   (set (match_dup 2)
+       (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
    ;; store the high byte
-   (set (mem:QI (plus (match_dup 2) (const_int 1)))
-        (truncate:QI (match_dup 4)))]
+   (set (mem:QI (plus (match_dup 1) (const_int 1)))
+       (subreg:QI (match_dup 2) 0))]   ;explicit subreg safe
   ""
   "
+{ operands[3] = gen_lowpart (QImode, operands[0]);
   operands[0] = gen_lowpart (SImode, operands[0]);
-")
+  operands[2] = gen_reg_rtx (SImode); }")
 
 ;; Subroutine to store a half word integer constant into memory.
 ;; Operand 0 is the constant
-;; Operand 1 is the destination address (SImode)
-;; Operand 2 is a temporary (SImode).
-;; Operand 3 is a temporary (QImode).
-;; Operand 4 is a temporary (QImode).
-;; Operand 5 is a local CONST_INT.
+;; Operand 1 is the destination address in a register (SImode)
 
 (define_expand "storeinthi"
-  [;; compute the address into a register
-   (set (match_operand:SI 2 "register_operand" "")
-        (match_operand:SI 1 "address_operand" ""))
-   ;; load the low byte
-   (set (match_operand:QI 3 "register_operand" "")
-        (match_operand:SI 0 "" ""))
-   ;; store the low byte
-   (set (mem:QI (match_dup 2))
-        (match_dup 3))
-   ;; load the high byte
-   (set (match_operand:QI 4 "register_operand" "")
-        (match_dup 5))
+  [;; store the low byte
+   (set (mem:QI (match_operand 1 "" "")) (match_operand 0 "" ""))
    ;; store the high byte
-   (set (mem:QI (plus (match_dup 2) (const_int 1)))
-        (match_dup 4))]
+   (set (mem:QI (plus (match_dup 1) (const_int 1)))
+       (match_dup 2))]
   ""
   "
     {
-      int value = INTVAL(operands[0]);
+      int value = INTVAL (operands[0]);
 
-      operands[0] = gen_rtx(CONST_INT, VOIDmode, value & 255);
-      operands[5] = gen_rtx(CONST_INT, VOIDmode,(value>>8) & 255);
+      operands[0] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode, value & 255));
+      operands[2] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode,(value>>8) & 255));
     }
 ")
 
 (define_expand "movhi"
   [(set (match_operand:HI 0 "general_operand" "")
-        (match_operand:HI 1 "general_operand" ""))]
+       (match_operand:HI 1 "general_operand" ""))]
   ""
   "
 {
     {
       if (GET_CODE (operands[0]) == MEM)
        {
-         if (GET_CODE (operands[1]) == MEM)
-           operands[1] = copy_to_reg (operands[1]);
-
          if (GET_CODE (operands[1]) == CONST_INT)
            {
-             insn = gen_storeinthi (operands[1], XEXP (operands[0], 0),
-                                    gen_reg_rtx (SImode),
-                                    gen_reg_rtx (QImode),
-                                    gen_reg_rtx (QImode));
+             insn = gen_storeinthi (operands[1], force_reg (SImode, XEXP (operands[0], 0)));
            }
          else
            {
-             insn = gen_storehi (operands[1], XEXP (operands[0], 0),
-                                 gen_reg_rtx (SImode),
-                                 gen_reg_rtx (SImode),
-                                 gen_reg_rtx (SImode));
+             if (GET_CODE (operands[1]) == MEM)
+               operands[1] = copy_to_reg (operands[1]);
+             insn = gen_storehi (operands[1], force_reg (SImode, XEXP (operands[0], 0)));
            }
        }
 #if 0
 
 (define_insn ""
   [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
-        (match_operand:HI 1 "general_operand"  "r,n,m,r"))]
+       (match_operand:HI 1 "general_operand"  "r,n,m,r"))]
   ""
   "*
   switch (which_alternative)
 
 (define_insn "movqi"
   [(set (match_operand:QI 0 "general_operand" "=r,r,r,m")
-        (match_operand:QI 1 "general_operand" "r,n,m,r"))]
+       (match_operand:QI 1 "general_operand" "r,n,m,r"))]
   ""
   "*
   switch (which_alternative)
     case 3:
       return (arm_output_asm_insn (\"strb\\t%1, %0\", operands));
     }
-  
 ")
 
 (define_insn "movsf"
   [(set (match_operand:SF 0 "general_operand" "=f,f,m,f,r,r")
-        (match_operand:SF 1 "general_operand" "fG,m,f,r,f,r"))]
+       (match_operand:SF 1 "general_operand" "fG,m,f,r,f,r"))]
   ""
   "*
   switch (which_alternative)
 
 (define_insn "movdf"
   [(set (match_operand:DF 0 "general_operand" "=f,f,m,f,r,r")
-        (match_operand:DF 1 "general_operand" "fG,m,f,r,f,r"))]
+       (match_operand:DF 1 "general_operand" "fG,m,f,r,f,r"))]
   ""
   "*
   switch (which_alternative)
 
 (define_insn "cmpsi"
   [(set (cc0)
-        (compare (match_operand:SI 0 "register_operand" "r")
+       (compare (match_operand:SI 0 "register_operand" "r")
                 (match_operand:SI 1 "arm_rhs_operand" "rI")))]
   ""
   "*
 
 (define_insn ""
   [(set (cc0)
-        (compare (match_operand:SI 0 "register_operand" "r")
-                 (neg:SI (match_operand:SI 1 "arm_rhs_operand" "rI"))))]
+       (compare (match_operand:SI 0 "register_operand" "r")
+                (neg:SI (match_operand:SI 1 "arm_rhs_operand" "rI"))))]
   ""
   "*
   return (arm_output_asm_insn (\"cmn\\t%0, %1\", operands));
 
 (define_insn "cmpsf"
   [(set (cc0)
-        (compare (match_operand:SF 0 "register_operand" "f")
+       (compare (match_operand:SF 0 "register_operand" "f")
                 (match_operand:SF 1 "fpu_rhs_operand" "fG")))]
   ""
   "*
 
 (define_insn "cmpdf"
   [(set (cc0)
-        (compare (match_operand:DF 0 "register_operand" "f")
+       (compare (match_operand:DF 0 "register_operand" "f")
                 (match_operand:DF 1 "fpu_rhs_operand" "fG")))]
   ""
   "*
 
 (define_insn "beq"
   [(set (pc)
-        (if_then_else (eq (cc0) (const_int 0))
+       (if_then_else (eq (cc0) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
 
 (define_insn "bne"
   [(set (pc)
-        (if_then_else (ne (cc0) (const_int 0))
+       (if_then_else (ne (cc0) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
 
 (define_insn "bgt"
   [(set (pc)
-        (if_then_else (gt (cc0) (const_int 0))
+       (if_then_else (gt (cc0) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
 
 (define_insn "ble"
   [(set (pc)
-        (if_then_else (le (cc0) (const_int 0))
+       (if_then_else (le (cc0) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
 
 (define_insn "bge"
   [(set (pc)
-        (if_then_else (ge (cc0) (const_int 0))
+       (if_then_else (ge (cc0) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
 
 (define_insn "blt"
   [(set (pc)
-        (if_then_else (lt (cc0) (const_int 0))
+       (if_then_else (lt (cc0) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
 
 (define_insn "bgtu"
   [(set (pc)
-        (if_then_else (gtu (cc0) (const_int 0))
+       (if_then_else (gtu (cc0) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
 
 (define_insn "bleu"
   [(set (pc)
-        (if_then_else (leu (cc0) (const_int 0))
+       (if_then_else (leu (cc0) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
 
 (define_insn "bgeu"
   [(set (pc)
-        (if_then_else (geu (cc0) (const_int 0))
+       (if_then_else (geu (cc0) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
 
 (define_insn "bltu"
   [(set (pc)
-        (if_then_else (ltu (cc0) (const_int 0))
+       (if_then_else (ltu (cc0) (const_int 0))
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
 
 (define_insn ""
   [(set (pc)
-        (if_then_else (eq (cc0) (const_int 0))
+       (if_then_else (eq (cc0) (const_int 0))
                      (pc)
                      (label_ref (match_operand 0 "" ""))))]
   ""
 
 (define_insn ""
   [(set (pc)
-        (if_then_else (ne (cc0) (const_int 0))
+       (if_then_else (ne (cc0) (const_int 0))
                      (pc)
                      (label_ref (match_operand 0 "" ""))))]
   ""
 
 (define_insn ""
   [(set (pc)
-        (if_then_else (gt (cc0) (const_int 0))
+       (if_then_else (gt (cc0) (const_int 0))
                      (pc)
                      (label_ref (match_operand 0 "" ""))))]
   ""
 
 (define_insn ""
   [(set (pc)
-        (if_then_else (le (cc0) (const_int 0))
+       (if_then_else (le (cc0) (const_int 0))
                      (pc)
                      (label_ref (match_operand 0 "" ""))))]
   ""
 
 (define_insn ""
   [(set (pc)
-        (if_then_else (ge (cc0) (const_int 0))
+       (if_then_else (ge (cc0) (const_int 0))
                      (pc)
                      (label_ref (match_operand 0 "" ""))))]
   ""
 
 (define_insn ""
   [(set (pc)
-        (if_then_else (lt (cc0) (const_int 0))
+       (if_then_else (lt (cc0) (const_int 0))
                      (pc)
                      (label_ref (match_operand 0 "" ""))))]
   ""
 
 (define_insn ""
   [(set (pc)
-        (if_then_else (gtu (cc0) (const_int 0))
+       (if_then_else (gtu (cc0) (const_int 0))
                      (pc)
                      (label_ref (match_operand 0 "" ""))))]
   ""
 
 (define_insn ""
   [(set (pc)
-        (if_then_else (leu (cc0) (const_int 0))
+       (if_then_else (leu (cc0) (const_int 0))
                      (pc)
                      (label_ref (match_operand 0 "" ""))))]
   ""
 
 (define_insn ""
   [(set (pc)
-        (if_then_else (geu (cc0) (const_int 0))
+       (if_then_else (geu (cc0) (const_int 0))
                      (pc)
                      (label_ref (match_operand 0 "" ""))))]
   ""
 
 (define_insn ""
   [(set (pc)
-        (if_then_else (ltu (cc0) (const_int 0))
+       (if_then_else (ltu (cc0) (const_int 0))
                      (pc)
                      (label_ref (match_operand 0 "" ""))))]
   ""
 
 (define_insn "jump"
   [(set (pc)
-        (label_ref (match_operand 0 "" "")))]
+       (label_ref (match_operand 0 "" "")))]
   ""
   "*
   return (arm_output_asm_insn (\"b\\t%l0\", operands));
 
 (define_insn "call"
   [(call (match_operand 0 "memory_operand" "m")
-         (match_operand 1 "general_operand" "g"))
+        (match_operand 1 "general_operand" "g"))
    (clobber (reg:SI 14))]
   ""
   "*
 
 (define_insn "call_value"
   [(set (match_operand 0 "" "=rf")
-        (call (match_operand 1 "memory_operand" "m")
-        (match_operand 2 "general_operand" "g")))
+       (call (match_operand 1 "memory_operand" "m")
+       (match_operand 2 "general_operand" "g")))
    (clobber (reg:SI 14))]
   ""
   "*
 
 (define_insn ""
   [(call (mem:SI (match_operand:SI 0 "" "i"))
-         (match_operand:SI 1 "general_operand" "g"))
+        (match_operand:SI 1 "general_operand" "g"))
    (clobber (reg:SI 14))]
   "GET_CODE (operands[0]) == SYMBOL_REF"
   "*
 
 (define_insn ""
   [(set (match_operand 0 "register_operand" "=rf")
-        (call (mem:SI (match_operand:SI 1 "" "i"))
-        (match_operand:SI 2 "general_operand" "g")))
+       (call (mem:SI (match_operand:SI 1 "" "i"))
+       (match_operand:SI 2 "general_operand" "g")))
    (clobber (reg:SI 14))]
   "GET_CODE(operands[1]) == SYMBOL_REF"
   "*
 
 (define_insn "tablejump"
   [(set (pc)
-        (match_operand:SI 0 "register_operand" "r"))
+       (match_operand:SI 0 "register_operand" "r"))
    (use (label_ref (match_operand 1 "" "")))]
   ""
   "*
 
 (define_insn "indirect_jump"
   [(set (pc)
-        (match_operand:SI 0 "register_operand" "r"))]
+       (match_operand:SI 0 "register_operand" "r"))]
   ""
   "*
   return (arm_output_asm_insn (\"mov\\tpc, %0\\t@ indirect jump\", operands));