if (!REG_P (operands[0]))
        operands[1] = force_reg (DImode, operands[1]);
     }
+  if (REG_P (operands[0]) && REGNO (operands[0]) < FIRST_VIRTUAL_REGISTER
+      && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
+    {
+      /* Avoid LDRD's into an odd-numbered register pair in ARM state
+        when expanding function calls.  */
+      gcc_assert (can_create_pseudo_p ());
+      if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
+       {
+         /* Perform load into legal reg pair first, then move.  */
+         rtx reg = gen_reg_rtx (DImode);
+         emit_insn (gen_movdi (reg, operands[1]));
+         operands[1] = reg;
+       }
+      emit_move_insn (gen_lowpart (SImode, operands[0]),
+                     gen_lowpart (SImode, operands[1]));
+      emit_move_insn (gen_highpart (SImode, operands[0]),
+                     gen_highpart (SImode, operands[1]));
+      DONE;
+    }
+  else if (REG_P (operands[1]) && REGNO (operands[1]) < FIRST_VIRTUAL_REGISTER
+          && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
+    {
+      /* Avoid STRD's from an odd-numbered register pair in ARM state
+        when expanding function prologue.  */
+      gcc_assert (can_create_pseudo_p ());
+      rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
+                      ? gen_reg_rtx (DImode)
+                      : operands[0];
+      emit_move_insn (gen_lowpart (SImode, split_dest),
+                     gen_lowpart (SImode, operands[1]));
+      emit_move_insn (gen_highpart (SImode, split_dest),
+                     gen_highpart (SImode, operands[1]));
+      if (split_dest != operands[0])
+       emit_insn (gen_movdi (operands[0], split_dest));
+      DONE;
+    }
   "
 )