]> Pileus Git - ~andy/linux/blobdiff - arch/mips/mm/pg-r4k.c
[MIPS] TX49: Fix use of CDEX build_store_reg()
[~andy/linux] / arch / mips / mm / pg-r4k.c
index b7c749232ffef80bb50c131f2853965aa7e72396..dc795be62807d1d1bf22af966ad961d0918794bf 100644 (file)
@@ -243,11 +243,10 @@ static void __init __build_store_reg(int reg)
 
 static inline void build_store_reg(int reg)
 {
-       if (cpu_has_prefetch)
-               if (reg)
-                       build_dst_pref(pref_offset_copy);
-               else
-                       build_dst_pref(pref_offset_clear);
+       int pref_off = cpu_has_prefetch ?
+               (reg ? pref_offset_copy : pref_offset_clear) : 0;
+       if (pref_off)
+               build_dst_pref(pref_off);
        else if (cpu_has_cache_cdex_s)
                build_cdex_s();
        else if (cpu_has_cache_cdex_p)
@@ -270,6 +269,20 @@ static inline void build_addiu_a2_a0(unsigned long offset)
        emit_instruction(mi);
 }
 
+static inline void build_addiu_a2(unsigned long offset)
+{
+       union mips_instruction mi;
+
+       BUG_ON(offset > 0x7fff);
+
+       mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
+       mi.i_format.rs         = 6;             /* $a2 */
+       mi.i_format.rt         = 6;             /* $a2 */
+       mi.i_format.simmediate = offset;
+
+       emit_instruction(mi);
+}
+
 static inline void build_addiu_a1(unsigned long offset)
 {
        union mips_instruction mi;
@@ -333,6 +346,7 @@ static inline void build_jr_ra(void)
 void __init build_clear_page(void)
 {
        unsigned int loop_start;
+       unsigned long off;
 
        epc = (unsigned int *) &clear_page_array;
        instruction_pending = 0;
@@ -369,7 +383,12 @@ void __init build_clear_page(void)
                }
        }
 
-       build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
+        off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0);
+       if (off > 0x7fff) {
+               build_addiu_a2_a0(off >> 1);
+               build_addiu_a2(off >> 1);
+       } else
+               build_addiu_a2_a0(off);
 
        if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
                build_insn_word(0x3c01a000);    /* lui     $at, 0xa000  */
@@ -420,12 +439,18 @@ dest = label();
 void __init build_copy_page(void)
 {
        unsigned int loop_start;
+       unsigned long off;
 
        epc = (unsigned int *) &copy_page_array;
        store_offset = load_offset = 0;
        instruction_pending = 0;
 
-       build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
+       off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0);
+       if (off > 0x7fff) {
+               build_addiu_a2_a0(off >> 1);
+               build_addiu_a2(off >> 1);
+       } else
+               build_addiu_a2_a0(off);
 
        if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
                build_insn_word(0x3c01a000);    /* lui     $at, 0xa000  */