This seems to work, with a suitable extendhipsi2 pattern for m32c:

Index: expr.c
===================================================================
--- expr.c      (revision 140759)
+++ expr.c      (working copy)
@@ -8455,12 +8459,34 @@ expand_expr_real_1 (tree exp, rtx target
              if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
                op0 = force_operand (op0, target);
              return REDUCE_BIT_FIELD (op0);
            }
        }
 
+      if (code == POINTER_PLUS_EXPR
+         || TYPE_PRECISION (TREE_OPERAND (exp, 1)) < TYPE_PRECISION 
(TREE_OPERAND (exp, 0)))
+       {
+         rtx reg;
+         enum machine_mode imode, omode;
+
+         expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+                          subtarget, &op0, &op1, 0);
+
+         if (op0 == const0_rtx)
+           return op1;
+         if (op1 == const0_rtx)
+           return op0;
+
+         imode = GET_MODE (op1);
+         omode = GET_MODE (op0);
+         reg = gen_reg_rtx (omode);
+         emit_move_insn (reg, gen_rtx_fmt_e (SIGN_EXTEND, omode, op1));
+         op1 = reg;
+         goto binop2;
+       }
+
       /* No sense saving up arithmetic to be done
         if it's all in the wrong mode to form part of an address.
         And force_operand won't know whether to sign-extend or
         zero-extend.  */
       if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
          || mode != ptr_mode)

Reply via email to