diff --git a/softmmu_template.h b/softmmu_template.h
index 65cce0a..6d86a21 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -108,6 +108,8 @@
 # define helper_be_st_name  glue(glue(helper_be_st, SUFFIX), MMUSUFFIX)
 #endif
 
+#define helper_generic_st_name glue(glue(helper_generic_st, SUFFIX), MMUSUFFIX)
+
 #ifdef TARGET_WORDS_BIGENDIAN
 # define helper_te_ld_name  helper_be_ld_name
 # define helper_te_st_name  helper_be_st_name
@@ -378,12 +380,13 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
                                  iotlbentry->attrs);
 }
 
-static inline void glue(helper_le_st_name, _do_unl_access)(CPUArchState *env,
-                                                           DATA_TYPE val,
-                                                           target_ulong addr,
-                                                           TCGMemOpIdx oi,
-                                                           unsigned mmu_idx,
-                                                           uintptr_t retaddr)
+static inline void glue(helper_generic_st_name, _do_unl_access)(CPUArchState *env,
+                                                                bool little_endian,
+                                                                DATA_TYPE val,
+                                                                target_ulong addr,
+                                                                TCGMemOpIdx oi,
+                                                                unsigned mmu_idx,
+                                                                uintptr_t retaddr)
 {
     int i;
 
@@ -391,12 +394,17 @@ static inline void glue(helper_le_st_name, _do_unl_access)(CPUArchState *env,
         cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
                              mmu_idx, retaddr);
     }
-    /* XXX: not efficient, but simple */
     /* Note: relies on the fact that tlb_fill() does not remove the
      * previous page from the TLB cache.  */
     for (i = DATA_SIZE - 1; i >= 0; i--) {
-        /* Little-endian extract.  */
-        uint8_t val8 = val >> (i * 8);
+        uint8_t val8;
+        if (little_endian) {
+            /* Little-endian extract.  */
+            val8 = val >> (i * 8);
+        } else {
+            /* Big-endian extract.  */
+            val8 = val >> (((DATA_SIZE - 1) * 8) - (i * 8));
+        }
         /* Note the adjustment at the beginning of the function.
            Undo that for the recursion.  */
         glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
@@ -415,8 +423,8 @@ static inline void glue(helper_le_st_name, _do_mmio_access)(CPUArchState *env,
     CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
 
     if ((addr & (DATA_SIZE - 1)) != 0) {
-        glue(helper_le_st_name, _do_unl_access)(env, val, addr, mmu_idx,
-                                                oi, retaddr);
+        glue(helper_generic_st_name, _do_unl_access)(env, true, val, addr,
+                                                     mmu_idx, oi, retaddr);
     }
     /* ??? Note that the io helpers always read data in the target
        byte ordering.  We should push the LE/BE request down into io.  */
@@ -438,8 +446,8 @@ static inline void glue(helper_le_st_name, _do_ram_access)(CPUArchState *env,
     if (DATA_SIZE > 1
         && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
                      >= TARGET_PAGE_SIZE)) {
-        glue(helper_le_st_name, _do_unl_access)(env, val, addr, oi, mmu_idx,
-                                                retaddr);
+        glue(helper_generic_st_name, _do_unl_access)(env, true, val, addr, oi, mmu_idx,
+                                                     retaddr);
         return;
     }
 
@@ -538,32 +546,6 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
 }
 
 #if DATA_SIZE > 1
-static inline void glue(helper_be_st_name, _do_unl_access)(CPUArchState *env,
-                                                           DATA_TYPE val,
-                                                           target_ulong addr,
-                                                           TCGMemOpIdx oi,
-                                                           unsigned mmu_idx,
-                                                           uintptr_t retaddr)
-{
-    int i;
-
-    if ((get_memop(oi) & MO_AMASK) == MO_ALIGN) {
-        cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
-                             mmu_idx, retaddr);
-    }
-    /* XXX: not efficient, but simple */
-    /* Note: relies on the fact that tlb_fill() does not remove the
-     * previous page from the TLB cache.  */
-    for (i = DATA_SIZE - 1; i >= 0; i--) {
-        /* Big-endian extract.  */
-        uint8_t val8 = val >> (((DATA_SIZE - 1) * 8) - (i * 8));
-        /* Note the adjustment at the beginning of the function.
-           Undo that for the recursion.  */
-        glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
-                                        oi, retaddr + GETPC_ADJ);
-    }
-}
-
 static inline void glue(helper_be_st_name, _do_mmio_access)(CPUArchState *env,
                                                             DATA_TYPE val,
                                                             target_ulong addr,
@@ -575,8 +557,8 @@ static inline void glue(helper_be_st_name, _do_mmio_access)(CPUArchState *env,
     CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
 
     if ((addr & (DATA_SIZE - 1)) != 0) {
-        glue(helper_be_st_name, _do_unl_access)(env, val, addr, mmu_idx,
-                                                oi, retaddr);
+        glue(helper_generic_st_name, _do_unl_access)(env, false, val, addr, mmu_idx,
+                                                     oi, retaddr);
     }
     /* ??? Note that the io helpers always read data in the target
        byte ordering.  We should push the LE/BE request down into io.  */
@@ -598,8 +580,8 @@ static inline void glue(helper_be_st_name, _do_ram_access)(CPUArchState *env,
     if (DATA_SIZE > 1
         && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
                      >= TARGET_PAGE_SIZE)) {
-        glue(helper_be_st_name, _do_unl_access)(env, val, addr, oi, mmu_idx,
-                                                retaddr);
+        glue(helper_generic_st_name, _do_unl_access)(env, false, val, addr, oi, mmu_idx,
+                                                     retaddr);
         return;
     }
 
