/[qemu]/qemu/target-mips/op_helper.c
ViewVC logotype

Diff of /qemu/target-mips/op_helper.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.7 by bellard, Sat Nov 26 18:47:20 2005 UTC revision 1.8 by bellard, Mon Dec 5 19:59:36 2005 UTC
# Line 22  Line 22 
22    
23  #define MIPS_DEBUG_DISAS  #define MIPS_DEBUG_DISAS
24    
25    #define GETPC() (__builtin_return_address(0))
26    
27  /*****************************************************************************/  /*****************************************************************************/
28  /* Exceptions processing helpers */  /* Exceptions processing helpers */
29  void cpu_loop_exit(void)  void cpu_loop_exit(void)
# Line 46  void do_raise_exception (uint32_t except Line 48  void do_raise_exception (uint32_t except
48      do_raise_exception_err(exception, 0);      do_raise_exception_err(exception, 0);
49  }  }
50    
51    void do_restore_state (void *pc_ptr)
52    {
53      TranslationBlock *tb;
54      unsigned long pc = (unsigned long) pc_ptr;
55    
56      tb = tb_find_pc (pc);
57      cpu_restore_state (tb, env, pc, NULL);
58    }
59    
60    void do_raise_exception_direct (uint32_t exception)
61    {
62        do_restore_state (GETPC ());
63        do_raise_exception_err (exception, 0);
64    }
65    
66  #define MEMSUFFIX _raw  #define MEMSUFFIX _raw
67  #include "op_helper_mem.c"  #include "op_helper_mem.c"
68  #undef MEMSUFFIX  #undef MEMSUFFIX
# Line 73  static inline void set_HILO (uint64_t HI Line 90  static inline void set_HILO (uint64_t HI
90    
91  void do_mult (void)  void do_mult (void)
92  {  {
93      set_HILO((int64_t)T0 * (int64_t)T1);      set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
94  }  }
95    
96  void do_multu (void)  void do_multu (void)
# Line 85  void do_madd (void) Line 102  void do_madd (void)
102  {  {
103      int64_t tmp;      int64_t tmp;
104    
105      tmp = ((int64_t)T0 * (int64_t)T1);      tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
106      set_HILO((int64_t)get_HILO() + tmp);      set_HILO((int64_t)get_HILO() + tmp);
107  }  }
108    
# Line 101  void do_msub (void) Line 118  void do_msub (void)
118  {  {
119      int64_t tmp;      int64_t tmp;
120    
121      tmp = ((int64_t)T0 * (int64_t)T1);      tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
122      set_HILO((int64_t)get_HILO() - tmp);      set_HILO((int64_t)get_HILO() - tmp);
123  }  }
124    
# Line 353  void do_mtc0 (int reg, int sel) Line 370  void do_mtc0 (int reg, int sel)
370          val = T0 & 0xFFFFF0FF;          val = T0 & 0xFFFFF0FF;
371          old = env->CP0_EntryHi;          old = env->CP0_EntryHi;
372          env->CP0_EntryHi = val;          env->CP0_EntryHi = val;
373            /* If the ASID changes, flush qemu's TLB.  */
374            if ((old & 0xFF) != (val & 0xFF))
375              tlb_flush (env, 1);
376          rn = "EntryHi";          rn = "EntryHi";
377          break;          break;
378      case 11:      case 11:
# Line 525  static void invalidate_tb (int idx) Line 545  static void invalidate_tb (int idx)
545          addr = tlb->PFN[0];          addr = tlb->PFN[0];
546          end = addr + (tlb->end - tlb->VPN);          end = addr + (tlb->end - tlb->VPN);
547          tb_invalidate_page_range(addr, end);          tb_invalidate_page_range(addr, end);
548            /* FIXME: Might be faster to just invalidate the whole "tlb" here
549               and refill it on demand from our simulated TLB.  */
550            addr = tlb->VPN;
551            while (addr < tlb->end) {
552                tlb_flush_page (env, addr);
553                addr += TARGET_PAGE_SIZE;
554            }
555      }      }
556      if (tlb->V[1]) {      if (tlb->V[1]) {
557          addr = tlb->PFN[1];          addr = tlb->PFN[1];
558          end = addr + (tlb->end - tlb->VPN);          end = addr + (tlb->end - tlb->VPN);
559          tb_invalidate_page_range(addr, end);          tb_invalidate_page_range(addr, end);
560            /* FIXME: Might be faster to just invalidate the whole "tlb" here
561               and refill it on demand from our simulated TLB.  */
562            addr = tlb->end;
563            while (addr < tlb->end2) {
564                tlb_flush_page (env, addr);
565                addr += TARGET_PAGE_SIZE;
566            }
567      }      }
568  }  }
569    
# Line 545  static void fill_tb (int idx) Line 579  static void fill_tb (int idx)
579      size = env->CP0_PageMask >> 13;      size = env->CP0_PageMask >> 13;
580      size = 4 * (size + 1);      size = 4 * (size + 1);
581      tlb->end = tlb->VPN + (1 << (8 + size));      tlb->end = tlb->VPN + (1 << (8 + size));
582        tlb->end2 = tlb->end + (1 << (8 + size));
583      tlb->G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1;      tlb->G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1;
584      tlb->V[0] = env->CP0_EntryLo0 & 2;      tlb->V[0] = env->CP0_EntryLo0 & 2;
585      tlb->D[0] = env->CP0_EntryLo0 & 4;      tlb->D[0] = env->CP0_EntryLo0 & 4;
# Line 601  void do_tlbr (void) Line 636  void do_tlbr (void)
636      int size;      int size;
637    
638      tlb = &env->tlb[env->CP0_index & (MIPS_TLB_NB - 1)];      tlb = &env->tlb[env->CP0_index & (MIPS_TLB_NB - 1)];
639    
640        /* If this will change the current ASID, flush qemu's TLB.  */
641        /* FIXME: Could avoid flushing things which match global entries... */
642        if ((env->CP0_EntryHi & 0xFF) != tlb->ASID)
643          tlb_flush (env, 1);
644    
645      env->CP0_EntryHi = tlb->VPN | tlb->ASID;      env->CP0_EntryHi = tlb->VPN | tlb->ASID;
646      size = (tlb->end - tlb->VPN) >> 12;      size = (tlb->end - tlb->VPN) >> 12;
647      env->CP0_PageMask = (size - 1) << 13;      env->CP0_PageMask = (size - 1) << 13;
# Line 664  void do_pmon (int function) Line 705  void do_pmon (int function)
705    
706  #if !defined(CONFIG_USER_ONLY)  #if !defined(CONFIG_USER_ONLY)
707    
708    static void do_unaligned_access (target_ulong addr, int is_write, int is_user, void *retaddr);
709    
710  #define MMUSUFFIX _mmu  #define MMUSUFFIX _mmu
711  #define GETPC() (__builtin_return_address(0))  #define ALIGNED_ONLY
712    
713  #define SHIFT 0  #define SHIFT 0
714  #include "softmmu_template.h"  #include "softmmu_template.h"
# Line 679  void do_pmon (int function) Line 722  void do_pmon (int function)
722  #define SHIFT 3  #define SHIFT 3
723  #include "softmmu_template.h"  #include "softmmu_template.h"
724    
725    static void do_unaligned_access (target_ulong addr, int is_write, int is_user, void *retaddr)
726    {
727        env->CP0_BadVAddr = addr;
728        do_restore_state (retaddr);
729        do_raise_exception ((is_write == 1) ? EXCP_AdES : EXCP_AdEL);
730    }
731    
732  void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)  void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
733  {  {
734      TranslationBlock *tb;      TranslationBlock *tb;

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.8

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26