Index: config/msp430/msp430.md
===================================================================
--- config/msp430/msp430.md	(revision 226084)
+++ config/msp430/msp430.md	(working copy)
@@ -196,16 +196,17 @@
   "@
   MOV.B\t%1, %0
   MOV%X0.B\t%1, %0"
 )
 
 (define_insn "movhi"
-  [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,rm")
-	(match_operand:HI 1 "msp_general_operand" "riYs,rmi"))]
+  [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=r,rYs,rm")
+	(match_operand:HI 1 "msp_general_operand" "N,riYs,rmi"))]
   ""
   "@
+  MOV.B\t%1, %0
   MOV.W\t%1, %0
   MOV%X0.W\t%1, %0"
 )
 
 (define_expand "movsi"
   [(set (match_operand:SI 0 "nonimmediate_operand")
@@ -239,16 +240,18 @@
 	(match_operand:HI 5 "general_operand"))]
   "msp430_split_movsi (operands);"
 )
 
 ;; Some MOVX.A cases can be done with MOVA, this is only a few of them.
 (define_insn "movpsi"
-  [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,Ya,rm")
-	(match_operand:PSI 1 "msp_general_operand" "riYa,r,rmi"))]
+  [(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,r,r,Ya,rm")
+	(match_operand:PSI 1 "msp_general_operand" "N,O,riYa,r,rmi"))]
   ""
   "@
+  MOV.B\t%1, %0
+  MOV.W\t%1, %0
   MOVA\t%1, %0
   MOVA\t%1, %0
   MOVX.A\t%1, %0")
 
 ; This pattern is identical to the truncsipsi2 pattern except
 ; that it uses a SUBREG instead of a TRUNC.  It is needed in
@@ -497,17 +500,18 @@
   "@
    BIC%x0%b0\t%1, %0
    BIC%X0%b0\t%1, %0"
 )
 
 (define_insn "and<mode>3"
-  [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=rYs,rm")
-	(and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0")
-		 (match_operand:QHI 2 "msp_general_operand" "riYs,rmi")))]
+  [(set (match_operand:QHI 0 "msp_nonimmediate_operand" "=r,rYs,rm")
+	(and:QHI (match_operand:QHI 1 "msp_nonimmediate_operand" "%0,0,0")
+		 (match_operand:QHI 2 "msp_general_operand" "N,riYs,rmi")))]
   ""
   "@
+   AND%x0.B\t%2, %0
    AND%x0%b0\t%2, %0
    AND%X0%b0\t%2, %0"
 )
 
 (define_insn "ior<mode>3"
   [(set (match_operand:QHI          0 "msp_nonimmediate_operand" "=rYs,rm")
@@ -546,17 +550,19 @@
   "@
    SXT%X0\t%0
    SXT%X0\t%0"
 )
 
 (define_insn "zero_extendqihi2"
-  [(set (match_operand:HI                 0 "msp_nonimmediate_operand" "=rYs,m")
-	(zero_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
+  [(set (match_operand:HI                 0 "msp_nonimmediate_operand" "=rYs,r,r,m")
+	(zero_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,rYs,m,0")))]
   ""
   "@
    AND\t#0xff, %0
+   MOV.B\t%1, %0
+   MOV%X0.B\t%1, %0
    AND%X0\t#0xff, %0"
 )
 
 ;; Eliminate extraneous zero-extends mysteriously created by gcc.
 (define_peephole2
   [(set (match_operand:HI 0 "register_operand")
@@ -599,12 +605,20 @@
 )
 
 ;; Look for cases where integer/pointer conversions are suboptimal due
 ;; to missing patterns, despite us not having opcodes for these
 ;; patterns.  Doing these manually allows for alternate optimization
 ;; paths.
+
+(define_insn "zero_extendqisi2"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
+	(zero_extend:SI (subreg:HI (match_operand:QI 1 "nonimmediate_operand" "rm") 0)))]
+  "msp430x"
+  "MOV.B\t%1,%L0 { CLR\t%H0"
+)
+
 (define_insn "zero_extendhisi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
 	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")))]
   "msp430x"
   "@
   MOV.W\t#0,%H0
@@ -731,12 +745,15 @@
 (define_expand "ashlhi3"
   [(set (match_operand:HI            0 "nonimmediate_operand")
 	(ashift:HI (match_operand:HI 1 "general_operand")
 		   (match_operand:HI 2 "general_operand")))]
   ""
   {
+    if (GET_CODE (operands[1]) == SUBREG
+        && REG_P (XEXP (operands[1], 0)))
+      operands[1] = force_reg (HImode, operands[1]);
     if (msp430x
         && REG_P (operands[0])
         && REG_P (operands[1])
         && CONST_INT_P (operands[2]))
       emit_insn (gen_430x_shift_left (operands[0], operands[1], operands[2]));
     else		 
@@ -797,12 +814,15 @@
 (define_expand "ashrhi3"
   [(set (match_operand:HI              0 "nonimmediate_operand")
 	(ashiftrt:HI (match_operand:HI 1 "general_operand")
 		     (match_operand:HI 2 "general_operand")))]
   ""
   {
+    if (GET_CODE (operands[1]) == SUBREG
+        && REG_P (XEXP (operands[1], 0)))
+      operands[1] = force_reg (HImode, operands[1]);
     if (msp430x
         && REG_P (operands[0])
         && REG_P (operands[1])
         && CONST_INT_P (operands[2]))
       emit_insn (gen_430x_arithmetic_shift_right (operands[0], operands[1], operands[2]));
     else		 
@@ -879,12 +899,15 @@
 (define_expand "lshrhi3"
   [(set (match_operand:HI              0 "nonimmediate_operand")
 	(lshiftrt:HI (match_operand:HI 1 "general_operand")
 		     (match_operand:HI 2 "general_operand")))]
   ""
   {
+    if (GET_CODE (operands[1]) == SUBREG
+        && REG_P (XEXP (operands[1], 0)))
+      operands[1] = force_reg (HImode, operands[1]);
     if (msp430x
         && REG_P (operands[0])
         && REG_P (operands[1])
         && CONST_INT_P (operands[2]))
       emit_insn (gen_430x_logical_shift_right (operands[0], operands[1], operands[2]));
     else		 
Index: config/msp430/constraints.md
===================================================================
--- config/msp430/constraints.md	(revision 226084)
+++ config/msp430/constraints.md	(working copy)
@@ -36,12 +36,22 @@
 
 (define_constraint "M"
   "Integer constant 1-4."
   (and (match_code "const_int")
        (match_test "IN_RANGE (ival, 1, 4)")))
 
+(define_constraint "N"
+  "Integer constant 0-255."
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, 0, 255)")))
+
+(define_constraint "O"
+  "Integer constant 256-65535."
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, 256, 65535)")))
+
 ;; We do not allow arbitrary constants, eg symbols or labels,
 ;; because their address may be above the 16-bit address limit
 ;; supported by the offset used in the MOVA instruction.
 (define_constraint "Ya"
   "Memory reference, any type, but restricted range of constants"
   (and (match_code "mem")
Index: config/msp430/t-msp430
===================================================================
--- config/msp430/t-msp430	(revision 226084)
+++ config/msp430/t-msp430	(working copy)
@@ -252,13 +252,13 @@ MULTILIB_MATCHES += mcpu?msp430=mmcu?msp
 MULTILIB_EXCEPTIONS = mcpu=msp430/mlarge
 
 
 # Multilibs for different types of hardware multiply support:
 
 MULTILIB_OPTIONS   += mhwmult=none/mhwmult=32bit/mhwmult=f5series
-MULTILIB_DIRNAMES  +=        nomul/        32mul/        f5mul
+MULTILIB_DIRNAMES  +=        nomul         32mul         f5mul
 
 MULTILIB_EXCEPTIONS += mcpu=msp430/mlarge/mhwmult=none
 MULTILIB_EXCEPTIONS += mcpu=msp430/mlarge/mhwmult=32bit
 MULTILIB_EXCEPTIONS += mcpu=msp430/mlarge/mhwmult=f5series
 MULTILIB_EXCEPTIONS += mcpu=msp430/mhwmult=f5series
 
Index: config/msp430/msp430.h
===================================================================
--- config/msp430/msp430.h	(revision 226084)
+++ config/msp430/msp430.h	(working copy)
@@ -163,13 +163,13 @@ extern bool msp430x;
 #define FUNCTION_MODE 			HImode
 #define CASE_VECTOR_MODE		Pmode
 #define HAS_LONG_COND_BRANCH		0
 #define HAS_LONG_UNCOND_BRANCH		0
 
 #define LOAD_EXTEND_OP(M)		ZERO_EXTEND
-/*#define WORD_REGISTER_OPERATIONS	1*/
+#define WORD_REGISTER_OPERATIONS	1
 
 #define MOVE_MAX 			8
 #define STARTING_FRAME_OFFSET		0
 
 #define INCOMING_RETURN_ADDR_RTX \
   msp430_incoming_return_addr_rtx ()
