Commit c570fd169c16f110781f31e0e963542a15229ee9

Authored by ths
1 parent 328a4240

Preliminiary MIPS64 support, disabled by default due to performance impact.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2250 c046a42c-6fe2-441c-8c8c-71466251a162
hw/mips_r4k.c
@@ -11,10 +11,10 @@ @@ -11,10 +11,10 @@
11 11
12 #define BIOS_FILENAME "mips_bios.bin" 12 #define BIOS_FILENAME "mips_bios.bin"
13 //#define BIOS_FILENAME "system.bin" 13 //#define BIOS_FILENAME "system.bin"
14 -#define KERNEL_LOAD_ADDR 0x80010000  
15 -#define INITRD_LOAD_ADDR 0x80800000 14 +#define KERNEL_LOAD_ADDR SIGN_EXTEND32(0x80010000)
  15 +#define INITRD_LOAD_ADDR SIGN_EXTEND32(0x80800000)
16 16
17 -#define VIRT_TO_PHYS_ADDEND (-0x80000000LL) 17 +#define VIRT_TO_PHYS_ADDEND (-SIGN_EXTEND32(0x80000000LL))
18 18
19 static const int ide_iobase[2] = { 0x1f0, 0x170 }; 19 static const int ide_iobase[2] = { 0x1f0, 0x170 };
20 static const int ide_iobase2[2] = { 0x3f6, 0x376 }; 20 static const int ide_iobase2[2] = { 0x3f6, 0x376 };
@@ -74,9 +74,11 @@ void load_kernel (CPUState *env, int ram_size, const char *kernel_filename, @@ -74,9 +74,11 @@ void load_kernel (CPUState *env, int ram_size, const char *kernel_filename,
74 long kernel_size, initrd_size; 74 long kernel_size, initrd_size;
75 75
76 kernel_size = load_elf(kernel_filename, VIRT_TO_PHYS_ADDEND, &entry); 76 kernel_size = load_elf(kernel_filename, VIRT_TO_PHYS_ADDEND, &entry);
77 - if (kernel_size >= 0) 77 + if (kernel_size >= 0) {
  78 + if ((entry & ~0x7fffffffULL) == 0x80000000)
  79 + entry = SIGN_EXTEND32(entry);
78 env->PC = entry; 80 env->PC = entry;
79 - else { 81 + } else {
80 kernel_size = load_image(kernel_filename, 82 kernel_size = load_image(kernel_filename,
81 phys_ram_base + KERNEL_LOAD_ADDR + VIRT_TO_PHYS_ADDEND); 83 phys_ram_base + KERNEL_LOAD_ADDR + VIRT_TO_PHYS_ADDEND);
82 if (kernel_size < 0) { 84 if (kernel_size < 0) {
@@ -103,7 +105,7 @@ void load_kernel (CPUState *env, int ram_size, const char *kernel_filename, @@ -103,7 +105,7 @@ void load_kernel (CPUState *env, int ram_size, const char *kernel_filename,
103 if (initrd_size > 0) { 105 if (initrd_size > 0) {
104 int ret; 106 int ret;
105 ret = sprintf(phys_ram_base + (16 << 20) - 256, 107 ret = sprintf(phys_ram_base + (16 << 20) - 256,
106 - "rd_start=0x%08x rd_size=%li ", 108 + "rd_start=0x" TLSZ " rd_size=%li ",
107 INITRD_LOAD_ADDR, 109 INITRD_LOAD_ADDR,
108 initrd_size); 110 initrd_size);
109 strcpy (phys_ram_base + (16 << 20) - 256 + ret, kernel_cmdline); 111 strcpy (phys_ram_base + (16 << 20) - 256 + ret, kernel_cmdline);
target-mips/cpu.h
@@ -15,6 +15,16 @@ typedef unsigned char uint_fast8_t; @@ -15,6 +15,16 @@ typedef unsigned char uint_fast8_t;
15 typedef unsigned int uint_fast16_t; 15 typedef unsigned int uint_fast16_t;
16 #endif 16 #endif
17 17
  18 +#ifdef MIPS_HAS_MIPS64
  19 +#define SIGN_EXTEND32(val) (((((uint64_t)(val)) & 0xFFFFFFFF) ^ 0x80000000) - 0x80000000)
  20 +/* target_ulong size spec */
  21 +#define TLSZ "%016llx"
  22 +#else
  23 +#define SIGN_EXTEND32(val) (val)
  24 +/* target_ulong size spec */
  25 +#define TLSZ "%08x"
  26 +#endif
  27 +
18 typedef union fpr_t fpr_t; 28 typedef union fpr_t fpr_t;
19 union fpr_t { 29 union fpr_t {
20 float64 fd; /* ieee double precision */ 30 float64 fd; /* ieee double precision */
@@ -55,7 +65,12 @@ struct CPUMIPSState { @@ -55,7 +65,12 @@ struct CPUMIPSState {
55 target_ulong gpr[32]; 65 target_ulong gpr[32];
56 /* Special registers */ 66 /* Special registers */
57 target_ulong PC; 67 target_ulong PC;
58 - uint32_t HI, LO; 68 +#if TARGET_LONG_BITS > HOST_LONG_BITS
  69 + target_ulong t0;
  70 + target_ulong t1;
  71 + target_ulong t2;
  72 +#endif
  73 + target_ulong HI, LO;
59 uint32_t DCR; /* ? */ 74 uint32_t DCR; /* ? */
60 #if defined(MIPS_USES_FPU) 75 #if defined(MIPS_USES_FPU)
61 /* Floating point registers */ 76 /* Floating point registers */
@@ -106,7 +121,7 @@ struct CPUMIPSState { @@ -106,7 +121,7 @@ struct CPUMIPSState {
106 uint32_t CP0_PageGrain; 121 uint32_t CP0_PageGrain;
107 uint32_t CP0_Wired; 122 uint32_t CP0_Wired;
108 uint32_t CP0_HWREna; 123 uint32_t CP0_HWREna;
109 - uint32_t CP0_BadVAddr; 124 + target_ulong CP0_BadVAddr;
110 uint32_t CP0_Count; 125 uint32_t CP0_Count;
111 uint64_t CP0_EntryHi; 126 uint64_t CP0_EntryHi;
112 uint32_t CP0_Compare; 127 uint32_t CP0_Compare;
@@ -145,9 +160,9 @@ struct CPUMIPSState { @@ -145,9 +160,9 @@ struct CPUMIPSState {
145 #define CP0Ca_WP 22 160 #define CP0Ca_WP 22
146 #define CP0Ca_IP 8 161 #define CP0Ca_IP 8
147 #define CP0Ca_EC 2 162 #define CP0Ca_EC 2
148 - uint32_t CP0_EPC; 163 + target_ulong CP0_EPC;
149 uint32_t CP0_PRid; 164 uint32_t CP0_PRid;
150 - uint32_t CP0_EBase; 165 + target_ulong CP0_EBase;
151 uint32_t CP0_Config0; 166 uint32_t CP0_Config0;
152 #define CP0C0_M 31 167 #define CP0C0_M 31
153 #define CP0C0_K23 28 168 #define CP0C0_K23 28
@@ -197,7 +212,7 @@ struct CPUMIPSState { @@ -197,7 +212,7 @@ struct CPUMIPSState {
197 #define CP0C3_MT 2 212 #define CP0C3_MT 2
198 #define CP0C3_SM 1 213 #define CP0C3_SM 1
199 #define CP0C3_TL 0 214 #define CP0C3_TL 0
200 - uint32_t CP0_LLAddr; 215 + target_ulong CP0_LLAddr;
201 uint32_t CP0_WatchLo; 216 uint32_t CP0_WatchLo;
202 uint32_t CP0_WatchHi; 217 uint32_t CP0_WatchHi;
203 uint32_t CP0_XContext; 218 uint32_t CP0_XContext;
@@ -221,13 +236,13 @@ struct CPUMIPSState { @@ -221,13 +236,13 @@ struct CPUMIPSState {
221 #define CP0DB_DDBL 2 236 #define CP0DB_DDBL 2
222 #define CP0DB_DBp 1 237 #define CP0DB_DBp 1
223 #define CP0DB_DSS 0 238 #define CP0DB_DSS 0
224 - uint32_t CP0_DEPC; 239 + target_ulong CP0_DEPC;
225 uint32_t CP0_Performance0; 240 uint32_t CP0_Performance0;
226 uint32_t CP0_TagLo; 241 uint32_t CP0_TagLo;
227 uint32_t CP0_DataLo; 242 uint32_t CP0_DataLo;
228 uint32_t CP0_TagHi; 243 uint32_t CP0_TagHi;
229 uint32_t CP0_DataHi; 244 uint32_t CP0_DataHi;
230 - uint32_t CP0_ErrorEPC; 245 + target_ulong CP0_ErrorEPC;
231 uint32_t CP0_DESAVE; 246 uint32_t CP0_DESAVE;
232 /* Qemu */ 247 /* Qemu */
233 int interrupt_request; 248 int interrupt_request;
target-mips/exec.h
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 3
4 //#define DEBUG_OP 4 //#define DEBUG_OP
5 5
  6 +#include "config.h"
6 #include "mips-defs.h" 7 #include "mips-defs.h"
7 #include "dyngen-exec.h" 8 #include "dyngen-exec.h"
8 9
@@ -16,9 +17,15 @@ typedef int32_t host_int_t; @@ -16,9 +17,15 @@ typedef int32_t host_int_t;
16 typedef uint32_t host_uint_t; 17 typedef uint32_t host_uint_t;
17 #endif 18 #endif
18 19
  20 +#if TARGET_LONG_BITS > HOST_LONG_BITS
  21 +#define T0 (env->t0)
  22 +#define T1 (env->t1)
  23 +#define T2 (env->t2)
  24 +#else
19 register host_uint_t T0 asm(AREG1); 25 register host_uint_t T0 asm(AREG1);
20 register host_uint_t T1 asm(AREG2); 26 register host_uint_t T1 asm(AREG2);
21 register host_uint_t T2 asm(AREG3); 27 register host_uint_t T2 asm(AREG3);
  28 +#endif
22 29
23 #if defined (USE_HOST_FLOAT_REGS) 30 #if defined (USE_HOST_FLOAT_REGS)
24 #error "implement me." 31 #error "implement me."
@@ -58,13 +65,36 @@ static inline void regs_to_env(void) @@ -58,13 +65,36 @@ static inline void regs_to_env(void)
58 { 65 {
59 } 66 }
60 67
61 -#if (HOST_LONG_BITS == 32) 68 +#ifdef MIPS_HAS_MIPS64
  69 +#if TARGET_LONG_BITS > HOST_LONG_BITS
  70 +void do_dsll (void);
  71 +void do_dsll32 (void);
  72 +void do_dsra (void);
  73 +void do_dsra32 (void);
  74 +void do_dsrl (void);
  75 +void do_dsrl32 (void);
  76 +void do_drotr (void);
  77 +void do_drotr32 (void);
  78 +void do_dsllv (void);
  79 +void do_dsrav (void);
  80 +void do_dsrlv (void);
  81 +void do_drotrv (void);
  82 +#endif
  83 +#endif
  84 +
  85 +#if TARGET_LONG_BITS > HOST_LONG_BITS
62 void do_mult (void); 86 void do_mult (void);
63 void do_multu (void); 87 void do_multu (void);
64 void do_madd (void); 88 void do_madd (void);
65 void do_maddu (void); 89 void do_maddu (void);
66 void do_msub (void); 90 void do_msub (void);
67 void do_msubu (void); 91 void do_msubu (void);
  92 +void do_ddiv (void);
  93 +void do_ddivu (void);
  94 +#endif
  95 +#ifdef MIPS_HAS_MIPS64
  96 +void do_dmult (void);
  97 +void do_dmultu (void);
68 #endif 98 #endif
69 void do_mfc0_random(void); 99 void do_mfc0_random(void);
70 void do_mfc0_count(void); 100 void do_mfc0_count(void);
@@ -86,6 +116,12 @@ void do_lwl_raw (uint32_t); @@ -86,6 +116,12 @@ void do_lwl_raw (uint32_t);
86 void do_lwr_raw (uint32_t); 116 void do_lwr_raw (uint32_t);
87 uint32_t do_swl_raw (uint32_t); 117 uint32_t do_swl_raw (uint32_t);
88 uint32_t do_swr_raw (uint32_t); 118 uint32_t do_swr_raw (uint32_t);
  119 +#ifdef MIPS_HAS_MIPS64
  120 +void do_ldl_raw (uint64_t);
  121 +void do_ldr_raw (uint64_t);
  122 +uint64_t do_sdl_raw (uint64_t);
  123 +uint64_t do_sdr_raw (uint64_t);
  124 +#endif
89 #if !defined(CONFIG_USER_ONLY) 125 #if !defined(CONFIG_USER_ONLY)
90 void do_lwl_user (uint32_t); 126 void do_lwl_user (uint32_t);
91 void do_lwl_kernel (uint32_t); 127 void do_lwl_kernel (uint32_t);
@@ -95,6 +131,16 @@ uint32_t do_swl_user (uint32_t); @@ -95,6 +131,16 @@ uint32_t do_swl_user (uint32_t);
95 uint32_t do_swl_kernel (uint32_t); 131 uint32_t do_swl_kernel (uint32_t);
96 uint32_t do_swr_user (uint32_t); 132 uint32_t do_swr_user (uint32_t);
97 uint32_t do_swr_kernel (uint32_t); 133 uint32_t do_swr_kernel (uint32_t);
  134 +#ifdef MIPS_HAS_MIPS64
  135 +void do_ldl_user (uint64_t);
  136 +void do_ldl_kernel (uint64_t);
  137 +void do_ldr_user (uint64_t);
  138 +void do_ldr_kernel (uint64_t);
  139 +uint64_t do_sdl_user (uint64_t);
  140 +uint64_t do_sdl_kernel (uint64_t);
  141 +uint64_t do_sdr_user (uint64_t);
  142 +uint64_t do_sdr_kernel (uint64_t);
  143 +#endif
98 #endif 144 #endif
99 void do_pmon (int function); 145 void do_pmon (int function);
100 146
target-mips/fop_template.c
@@ -96,4 +96,5 @@ SET_RESET(DT0, _DT0) @@ -96,4 +96,5 @@ SET_RESET(DT0, _DT0)
96 SET_RESET(DT1, _DT1) 96 SET_RESET(DT1, _DT1)
97 SET_RESET(DT2, _DT2) 97 SET_RESET(DT2, _DT2)
98 98
  99 +#undef SET_RESET
99 #endif 100 #endif
target-mips/helper.c
@@ -86,7 +86,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical, @@ -86,7 +86,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
86 #endif 86 #endif
87 if (user_mode && address > 0x7FFFFFFFUL) 87 if (user_mode && address > 0x7FFFFFFFUL)
88 return TLBRET_BADADDR; 88 return TLBRET_BADADDR;
89 - if (address < 0x80000000UL) { 89 + if (address < SIGN_EXTEND32(0x80000000UL)) {
90 if (!(env->hflags & MIPS_HFLAG_ERL)) { 90 if (!(env->hflags & MIPS_HFLAG_ERL)) {
91 #ifdef MIPS_USES_R4K_TLB 91 #ifdef MIPS_USES_R4K_TLB
92 ret = map_address(env, physical, prot, address, rw, access_type); 92 ret = map_address(env, physical, prot, address, rw, access_type);
@@ -98,17 +98,17 @@ static int get_physical_address (CPUState *env, target_ulong *physical, @@ -98,17 +98,17 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
98 *physical = address; 98 *physical = address;
99 *prot = PAGE_READ | PAGE_WRITE; 99 *prot = PAGE_READ | PAGE_WRITE;
100 } 100 }
101 - } else if (address < 0xA0000000UL) { 101 + } else if (address < SIGN_EXTEND32(0xA0000000UL)) {
102 /* kseg0 */ 102 /* kseg0 */
103 /* XXX: check supervisor mode */ 103 /* XXX: check supervisor mode */
104 - *physical = address - 0x80000000UL; 104 + *physical = address - SIGN_EXTEND32(0x80000000UL);
105 *prot = PAGE_READ | PAGE_WRITE; 105 *prot = PAGE_READ | PAGE_WRITE;
106 - } else if (address < 0xC0000000UL) { 106 + } else if (address < SIGN_EXTEND32(0xC0000000UL)) {
107 /* kseg1 */ 107 /* kseg1 */
108 /* XXX: check supervisor mode */ 108 /* XXX: check supervisor mode */
109 - *physical = address - 0xA0000000UL; 109 + *physical = address - SIGN_EXTEND32(0xA0000000UL);
110 *prot = PAGE_READ | PAGE_WRITE; 110 *prot = PAGE_READ | PAGE_WRITE;
111 - } else if (address < 0xE0000000UL) { 111 + } else if (address < SIGN_EXTEND32(0xE0000000UL)) {
112 /* kseg2 */ 112 /* kseg2 */
113 #ifdef MIPS_USES_R4K_TLB 113 #ifdef MIPS_USES_R4K_TLB
114 ret = map_address(env, physical, prot, address, rw, access_type); 114 ret = map_address(env, physical, prot, address, rw, access_type);
@@ -129,8 +129,8 @@ static int get_physical_address (CPUState *env, target_ulong *physical, @@ -129,8 +129,8 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
129 } 129 }
130 #if 0 130 #if 0
131 if (logfile) { 131 if (logfile) {
132 - fprintf(logfile, "%08x %d %d => %08x %d (%d)\n", address, rw,  
133 - access_type, *physical, *prot, ret); 132 + fprintf(logfile, TLSZ " %d %d => " TLSZ " %d (%d)\n",
  133 + address, rw, access_type, *physical, *prot, ret);
134 } 134 }
135 #endif 135 #endif
136 136
@@ -171,7 +171,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -171,7 +171,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
171 #if 0 171 #if 0
172 cpu_dump_state(env, logfile, fprintf, 0); 172 cpu_dump_state(env, logfile, fprintf, 0);
173 #endif 173 #endif
174 - fprintf(logfile, "%s pc %08x ad %08x rw %d is_user %d smmu %d\n", 174 + fprintf(logfile, "%s pc " TLSZ " ad " TLSZ " rw %d is_user %d smmu %d\n",
175 __func__, env->PC, address, rw, is_user, is_softmmu); 175 __func__, env->PC, address, rw, is_user, is_softmmu);
176 } 176 }
177 177
@@ -189,7 +189,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -189,7 +189,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
189 ret = get_physical_address(env, &physical, &prot, 189 ret = get_physical_address(env, &physical, &prot,
190 address, rw, access_type); 190 address, rw, access_type);
191 if (logfile) { 191 if (logfile) {
192 - fprintf(logfile, "%s address=%08x ret %d physical %08x prot %d\n", 192 + fprintf(logfile, "%s address=" TLSZ " ret %d physical " TLSZ " prot %d\n",
193 __func__, address, ret, physical, prot); 193 __func__, address, ret, physical, prot);
194 } 194 }
195 if (ret == TLBRET_MATCH) { 195 if (ret == TLBRET_MATCH) {
@@ -255,7 +255,7 @@ void do_interrupt (CPUState *env) @@ -255,7 +255,7 @@ void do_interrupt (CPUState *env)
255 int cause = -1; 255 int cause = -1;
256 256
257 if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { 257 if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
258 - fprintf(logfile, "%s enter: PC %08x EPC %08x cause %d excp %d\n", 258 + fprintf(logfile, "%s enter: PC " TLSZ " EPC " TLSZ " cause %d excp %d\n",
259 __func__, env->PC, env->CP0_EPC, cause, env->exception_index); 259 __func__, env->PC, env->CP0_EPC, cause, env->exception_index);
260 } 260 }
261 if (env->exception_index == EXCP_EXT_INTERRUPT && 261 if (env->exception_index == EXCP_EXT_INTERRUPT &&
@@ -299,7 +299,7 @@ void do_interrupt (CPUState *env) @@ -299,7 +299,7 @@ void do_interrupt (CPUState *env)
299 enter_debug_mode: 299 enter_debug_mode:
300 env->hflags |= MIPS_HFLAG_DM; 300 env->hflags |= MIPS_HFLAG_DM;
301 /* EJTAG probe trap enable is not implemented... */ 301 /* EJTAG probe trap enable is not implemented... */
302 - env->PC = 0xBFC00480; 302 + env->PC = SIGN_EXTEND32(0xBFC00480);
303 break; 303 break;
304 case EXCP_RESET: 304 case EXCP_RESET:
305 cpu_reset(env); 305 cpu_reset(env);
@@ -321,7 +321,7 @@ void do_interrupt (CPUState *env) @@ -321,7 +321,7 @@ void do_interrupt (CPUState *env)
321 } 321 }
322 env->hflags |= MIPS_HFLAG_ERL; 322 env->hflags |= MIPS_HFLAG_ERL;
323 env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); 323 env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
324 - env->PC = 0xBFC00000; 324 + env->PC = SIGN_EXTEND32(0xBFC00000);
325 break; 325 break;
326 case EXCP_MCHECK: 326 case EXCP_MCHECK:
327 cause = 24; 327 cause = 24;
@@ -389,9 +389,9 @@ void do_interrupt (CPUState *env) @@ -389,9 +389,9 @@ void do_interrupt (CPUState *env)
389 env->CP0_Cause &= ~0x80000000; 389 env->CP0_Cause &= ~0x80000000;
390 } 390 }
391 if (env->CP0_Status & (1 << CP0St_BEV)) { 391 if (env->CP0_Status & (1 << CP0St_BEV)) {
392 - env->PC = 0xBFC00200; 392 + env->PC = SIGN_EXTEND32(0xBFC00200);
393 } else { 393 } else {
394 - env->PC = 0x80000000; 394 + env->PC = SIGN_EXTEND32(0x80000000);
395 } 395 }
396 env->hflags |= MIPS_HFLAG_EXL; 396 env->hflags |= MIPS_HFLAG_EXL;
397 env->CP0_Status |= (1 << CP0St_EXL); 397 env->CP0_Status |= (1 << CP0St_EXL);
@@ -407,8 +407,8 @@ void do_interrupt (CPUState *env) @@ -407,8 +407,8 @@ void do_interrupt (CPUState *env)
407 exit(1); 407 exit(1);
408 } 408 }
409 if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { 409 if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) {
410 - fprintf(logfile, "%s: PC %08x EPC %08x cause %d excp %d\n"  
411 - " S %08x C %08x A %08x D %08x\n", 410 + fprintf(logfile, "%s: PC " TLSZ " EPC " TLSZ " cause %d excp %d\n"
  411 + " S %08x C %08x A " TLSZ " D " TLSZ "\n",
412 __func__, env->PC, env->CP0_EPC, cause, env->exception_index, 412 __func__, env->PC, env->CP0_EPC, cause, env->exception_index,
413 env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr, 413 env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr,
414 env->CP0_DEPC); 414 env->CP0_DEPC);
target-mips/mips-defs.h
@@ -14,7 +14,8 @@ @@ -14,7 +14,8 @@
14 14
15 #if (MIPS_CPU == MIPS_R4Kc) 15 #if (MIPS_CPU == MIPS_R4Kc)
16 /* 32 bits target */ 16 /* 32 bits target */
17 -#define TARGET_LONG_BITS 32 17 +#undef MIPS_HAS_MIPS64
  18 +//#define MIPS_HAS_MIPS64 1
18 /* real pages are variable size... */ 19 /* real pages are variable size... */
19 #define TARGET_PAGE_BITS 12 20 #define TARGET_PAGE_BITS 12
20 /* Uses MIPS R4Kx enhancements to MIPS32 architecture */ 21 /* Uses MIPS R4Kx enhancements to MIPS32 architecture */
@@ -69,7 +70,7 @@ @@ -69,7 +70,7 @@
69 (0 << CP0C3_MT) | (0 << CP0C3_SM) | (0 << CP0C3_TL)) 70 (0 << CP0C3_MT) | (0 << CP0C3_SM) | (0 << CP0C3_TL))
70 #elif (MIPS_CPU == MIPS_R4Kp) 71 #elif (MIPS_CPU == MIPS_R4Kp)
71 /* 32 bits target */ 72 /* 32 bits target */
72 -#define TARGET_LONG_BITS 32 73 +#undef MIPS_HAS_MIPS64
73 /* real pages are variable size... */ 74 /* real pages are variable size... */
74 #define TARGET_PAGE_BITS 12 75 #define TARGET_PAGE_BITS 12
75 /* Uses MIPS R4Kx enhancements to MIPS32 architecture */ 76 /* Uses MIPS R4Kx enhancements to MIPS32 architecture */
@@ -79,8 +80,14 @@ @@ -79,8 +80,14 @@
79 #else 80 #else
80 #error "MIPS CPU not defined" 81 #error "MIPS CPU not defined"
81 /* Reminder for other flags */ 82 /* Reminder for other flags */
82 -//#define TARGET_MIPS64 83 +//#undef MIPS_HAS_MIPS64
83 //#define MIPS_USES_FPU 84 //#define MIPS_USES_FPU
84 #endif 85 #endif
85 86
  87 +#ifdef MIPS_HAS_MIPS64
  88 +#define TARGET_LONG_BITS 64
  89 +#else
  90 +#define TARGET_LONG_BITS 32
  91 +#endif
  92 +
86 #endif /* !defined (__QEMU_MIPS_DEFS_H__) */ 93 #endif /* !defined (__QEMU_MIPS_DEFS_H__) */
target-mips/op.c
@@ -140,13 +140,7 @@ CALL_FROM_TB2(func, arg0, arg1); @@ -140,13 +140,7 @@ CALL_FROM_TB2(func, arg0, arg1);
140 #include "op_template.c" 140 #include "op_template.c"
141 #undef REG 141 #undef REG
142 142
143 -#define TN T0  
144 -#include "op_template.c"  
145 -#undef TN  
146 -#define TN T1  
147 -#include "op_template.c"  
148 -#undef TN  
149 -#define TN T2 143 +#define TN
150 #include "op_template.c" 144 #include "op_template.c"
151 #undef TN 145 #undef TN
152 146
@@ -334,7 +328,7 @@ void op_store_LO (void) @@ -334,7 +328,7 @@ void op_store_LO (void)
334 /* Arithmetic */ 328 /* Arithmetic */
335 void op_add (void) 329 void op_add (void)
336 { 330 {
337 - T0 += T1; 331 + T0 = SIGN_EXTEND32((int32_t)T0 + (int32_t)T1);
338 RETURN(); 332 RETURN();
339 } 333 }
340 334
@@ -342,18 +336,19 @@ void op_addo (void) @@ -342,18 +336,19 @@ void op_addo (void)
342 { 336 {
343 target_ulong tmp; 337 target_ulong tmp;
344 338
345 - tmp = T0;  
346 - T0 += T1; 339 + tmp = (int32_t)T0;
  340 + T0 = (int32_t)T0 + (int32_t)T1;
347 if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) { 341 if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
348 - /* operands of same sign, result different sign */ 342 + /* operands of same sign, result different sign */
349 CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); 343 CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
350 } 344 }
  345 + T0 = SIGN_EXTEND32(T0);
351 RETURN(); 346 RETURN();
352 } 347 }
353 348
354 void op_sub (void) 349 void op_sub (void)
355 { 350 {
356 - T0 -= T1; 351 + T0 = SIGN_EXTEND32((int32_t)T0 - (int32_t)T1);
357 RETURN(); 352 RETURN();
358 } 353 }
359 354
@@ -361,26 +356,27 @@ void op_subo (void) @@ -361,26 +356,27 @@ void op_subo (void)
361 { 356 {
362 target_ulong tmp; 357 target_ulong tmp;
363 358
364 - tmp = T0; 359 + tmp = (int32_t)T0;
365 T0 = (int32_t)T0 - (int32_t)T1; 360 T0 = (int32_t)T0 - (int32_t)T1;
366 if (((tmp ^ T1) & (tmp ^ T0)) >> 31) { 361 if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
367 - /* operands of different sign, first operand and result different sign */ 362 + /* operands of different sign, first operand and result different sign */
368 CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); 363 CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
369 } 364 }
  365 + T0 = SIGN_EXTEND32(T0);
370 RETURN(); 366 RETURN();
371 } 367 }
372 368
373 void op_mul (void) 369 void op_mul (void)
374 { 370 {
375 - T0 = (int32_t)T0 * (int32_t)T1; 371 + T0 = SIGN_EXTEND32((int32_t)T0 * (int32_t)T1);
376 RETURN(); 372 RETURN();
377 } 373 }
378 374
379 void op_div (void) 375 void op_div (void)
380 { 376 {
381 if (T1 != 0) { 377 if (T1 != 0) {
382 - env->LO = (int32_t)T0 / (int32_t)T1;  
383 - env->HI = (int32_t)T0 % (int32_t)T1; 378 + env->LO = SIGN_EXTEND32((int32_t)T0 / (int32_t)T1);
  379 + env->HI = SIGN_EXTEND32((int32_t)T0 % (int32_t)T1);
384 } 380 }
385 RETURN(); 381 RETURN();
386 } 382 }
@@ -388,11 +384,91 @@ void op_div (void) @@ -388,11 +384,91 @@ void op_div (void)
388 void op_divu (void) 384 void op_divu (void)
389 { 385 {
390 if (T1 != 0) { 386 if (T1 != 0) {
  387 + env->LO = SIGN_EXTEND32((uint32_t)T0 / (uint32_t)T1);
  388 + env->HI = SIGN_EXTEND32((uint32_t)T0 % (uint32_t)T1);
  389 + }
  390 + RETURN();
  391 +}
  392 +
  393 +#ifdef MIPS_HAS_MIPS64
  394 +/* Arithmetic */
  395 +void op_dadd (void)
  396 +{
  397 + T0 += T1;
  398 + RETURN();
  399 +}
  400 +
  401 +void op_daddo (void)
  402 +{
  403 + target_long tmp;
  404 +
  405 + tmp = T0;
  406 + T0 += T1;
  407 + if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
  408 + /* operands of same sign, result different sign */
  409 + CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
  410 + }
  411 + RETURN();
  412 +}
  413 +
  414 +void op_dsub (void)
  415 +{
  416 + T0 -= T1;
  417 + RETURN();
  418 +}
  419 +
  420 +void op_dsubo (void)
  421 +{
  422 + target_long tmp;
  423 +
  424 + tmp = T0;
  425 + T0 = (int64_t)T0 - (int64_t)T1;
  426 + if (((tmp ^ T1) & (tmp ^ T0)) >> 63) {
  427 + /* operands of different sign, first operand and result different sign */
  428 + CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
  429 + }
  430 + RETURN();
  431 +}
  432 +
  433 +void op_dmul (void)
  434 +{
  435 + T0 = (int64_t)T0 * (int64_t)T1;
  436 + RETURN();
  437 +}
  438 +
  439 +#if TARGET_LONG_BITS > HOST_LONG_BITS
  440 +/* Those might call libgcc functions. */
  441 +void op_ddiv (void)
  442 +{
  443 + do_ddiv();
  444 + RETURN();
  445 +}
  446 +
  447 +void op_ddivu (void)
  448 +{
  449 + do_ddivu();
  450 + RETURN();
  451 +}
  452 +#else
  453 +void op_ddiv (void)
  454 +{
  455 + if (T1 != 0) {
  456 + env->LO = (int64_t)T0 / (int64_t)T1;
  457 + env->HI = (int64_t)T0 % (int64_t)T1;
  458 + }
  459 + RETURN();
  460 +}
  461 +
  462 +void op_ddivu (void)
  463 +{
  464 + if (T1 != 0) {
391 env->LO = T0 / T1; 465 env->LO = T0 / T1;
392 env->HI = T0 % T1; 466 env->HI = T0 % T1;
393 } 467 }
394 RETURN(); 468 RETURN();
395 } 469 }
  470 +#endif
  471 +#endif /* MIPS_HAS_MIPS64 */
396 472
397 /* Logical */ 473 /* Logical */
398 void op_and (void) 474 void op_and (void)
@@ -421,19 +497,19 @@ void op_xor (void) @@ -421,19 +497,19 @@ void op_xor (void)
421 497
422 void op_sll (void) 498 void op_sll (void)
423 { 499 {
424 - T0 = T0 << T1; 500 + T0 = SIGN_EXTEND32((uint32_t)T0 << (uint32_t)T1);
425 RETURN(); 501 RETURN();
426 } 502 }
427 503
428 void op_sra (void) 504 void op_sra (void)
429 { 505 {
430 - T0 = (int32_t)T0 >> T1; 506 + T0 = SIGN_EXTEND32((int32_t)T0 >> (uint32_t)T1);
431 RETURN(); 507 RETURN();
432 } 508 }
433 509
434 void op_srl (void) 510 void op_srl (void)
435 { 511 {
436 - T0 = T0 >> T1; 512 + T0 = SIGN_EXTEND32((uint32_t)T0 >> (uint32_t)T1);
437 RETURN(); 513 RETURN();
438 } 514 }
439 515
@@ -442,8 +518,8 @@ void op_rotr (void) @@ -442,8 +518,8 @@ void op_rotr (void)
442 target_ulong tmp; 518 target_ulong tmp;
443 519
444 if (T1) { 520 if (T1) {
445 - tmp = T0 << (0x20 - T1);  
446 - T0 = (T0 >> T1) | tmp; 521 + tmp = SIGN_EXTEND32((uint32_t)T0 << (0x20 - (uint32_t)T1));
  522 + T0 = SIGN_EXTEND32((uint32_t)T0 >> (uint32_t)T1) | tmp;
447 } else 523 } else
448 T0 = T1; 524 T0 = T1;
449 RETURN(); 525 RETURN();
@@ -451,19 +527,19 @@ void op_rotr (void) @@ -451,19 +527,19 @@ void op_rotr (void)
451 527
452 void op_sllv (void) 528 void op_sllv (void)
453 { 529 {
454 - T0 = T1 << (T0 & 0x1F); 530 + T0 = SIGN_EXTEND32((uint32_t)T1 << ((uint32_t)T0 & 0x1F));
455 RETURN(); 531 RETURN();
456 } 532 }
457 533
458 void op_srav (void) 534 void op_srav (void)
459 { 535 {
460 - T0 = (int32_t)T1 >> (T0 & 0x1F); 536 + T0 = SIGN_EXTEND32((int32_t)T1 >> (T0 & 0x1F));
461 RETURN(); 537 RETURN();
462 } 538 }
463 539
464 void op_srlv (void) 540 void op_srlv (void)
465 { 541 {
466 - T0 = T1 >> (T0 & 0x1F); 542 + T0 = SIGN_EXTEND32((uint32_t)T1 >> (T0 & 0x1F));
467 RETURN(); 543 RETURN();
468 } 544 }
469 545
@@ -473,8 +549,8 @@ void op_rotrv (void) @@ -473,8 +549,8 @@ void op_rotrv (void)
473 549
474 T0 &= 0x1F; 550 T0 &= 0x1F;
475 if (T0) { 551 if (T0) {
476 - tmp = T1 << (0x20 - T0);  
477 - T0 = (T1 >> T0) | tmp; 552 + tmp = SIGN_EXTEND32((uint32_t)T1 << (0x20 - T0));
  553 + T0 = SIGN_EXTEND32((uint32_t)T1 >> T0) | tmp;
478 } else 554 } else
479 T0 = T1; 555 T0 = T1;
480 RETURN(); 556 RETURN();
@@ -484,7 +560,7 @@ void op_clo (void) @@ -484,7 +560,7 @@ void op_clo (void)
484 { 560 {
485 int n; 561 int n;
486 562
487 - if (T0 == (target_ulong)-1) { 563 + if (T0 == ~((target_ulong)0)) {
488 T0 = 32; 564 T0 = 32;
489 } else { 565 } else {
490 for (n = 0; n < 32; n++) { 566 for (n = 0; n < 32; n++) {
@@ -514,67 +590,213 @@ void op_clz (void) @@ -514,67 +590,213 @@ void op_clz (void)
514 RETURN(); 590 RETURN();
515 } 591 }
516 592
517 -/* 64 bits arithmetic */  
518 -#if (HOST_LONG_BITS == 64)  
519 -static inline uint64_t get_HILO (void) 593 +#ifdef MIPS_HAS_MIPS64
  594 +
  595 +#if TARGET_LONG_BITS > HOST_LONG_BITS
  596 +/* Those might call libgcc functions. */
  597 +void op_dsll (void)
520 { 598 {
521 - return ((uint64_t)env->HI << 32) | (uint64_t)env->LO; 599 + CALL_FROM_TB0(do_dsll);
  600 + RETURN();
522 } 601 }
523 602
524 -static inline void set_HILO (uint64_t HILO) 603 +void op_dsll32 (void)
525 { 604 {
526 - env->LO = HILO & 0xFFFFFFFF;  
527 - env->HI = HILO >> 32; 605 + CALL_FROM_TB0(do_dsll32);
  606 + RETURN();
528 } 607 }
529 608
530 -void op_mult (void) 609 +void op_dsra (void)
531 { 610 {
532 - set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); 611 + CALL_FROM_TB0(do_dsra);
533 RETURN(); 612 RETURN();
534 } 613 }
535 614
536 -void op_multu (void) 615 +void op_dsra32 (void)
537 { 616 {
538 - set_HILO((uint64_t)T0 * (uint64_t)T1); 617 + CALL_FROM_TB0(do_dsra32);
539 RETURN(); 618 RETURN();
540 } 619 }
541 620
542 -void op_madd (void) 621 +void op_dsrl (void)
543 { 622 {
544 - int64_t tmp; 623 + CALL_FROM_TB0(do_dsrl);
  624 + RETURN();
  625 +}
545 626
546 - tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);  
547 - set_HILO((int64_t)get_HILO() + tmp); 627 +void op_dsrl32 (void)
  628 +{
  629 + CALL_FROM_TB0(do_dsrl32);
548 RETURN(); 630 RETURN();
549 } 631 }
550 632
551 -void op_maddu (void) 633 +void op_drotr (void)
552 { 634 {
553 - uint64_t tmp; 635 + CALL_FROM_TB0(do_drotr);
  636 + RETURN();
  637 +}
554 638
555 - tmp = ((uint64_t)T0 * (uint64_t)T1);  
556 - set_HILO(get_HILO() + tmp); 639 +void op_drotr32 (void)
  640 +{
  641 + CALL_FROM_TB0(do_drotr32);
557 RETURN(); 642 RETURN();
558 } 643 }
559 644
560 -void op_msub (void) 645 +void op_dsllv (void)
561 { 646 {
562 - int64_t tmp; 647 + CALL_FROM_TB0(do_dsllv);
  648 + RETURN();
  649 +}
563 650
564 - tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);  
565 - set_HILO((int64_t)get_HILO() - tmp); 651 +void op_dsrav (void)
  652 +{
  653 + CALL_FROM_TB0(do_dsrav);
566 RETURN(); 654 RETURN();
567 } 655 }
568 656
569 -void op_msubu (void) 657 +void op_dsrlv (void)
570 { 658 {
571 - uint64_t tmp; 659 + CALL_FROM_TB0(do_dsrlv);
  660 + RETURN();
  661 +}
572 662
573 - tmp = ((uint64_t)T0 * (uint64_t)T1);  
574 - set_HILO(get_HILO() - tmp); 663 +void op_drotrv (void)
  664 +{
  665 + CALL_FROM_TB0(do_drotrv);
575 RETURN(); 666 RETURN();
576 } 667 }
577 -#else 668 +
  669 +#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
  670 +
  671 +void op_dsll (void)
  672 +{
  673 + T0 = T0 << T1;
  674 + RETURN();
  675 +}
  676 +
  677 +void op_dsll32 (void)
  678 +{
  679 + T0 = T0 << (T1 + 32);
  680 + RETURN();
  681 +}
  682 +
  683 +void op_dsra (void)
  684 +{
  685 + T0 = (int64_t)T0 >> T1;
  686 + RETURN();
  687 +}
  688 +
  689 +void op_dsra32 (void)
  690 +{
  691 + T0 = (int64_t)T0 >> (T1 + 32);
  692 + RETURN();
  693 +}
  694 +
  695 +void op_dsrl (void)
  696 +{
  697 + T0 = T0 >> T1;
  698 + RETURN();
  699 +}
  700 +
  701 +void op_dsrl32 (void)
  702 +{
  703 + T0 = T0 >> (T1 + 32);
  704 + RETURN();
  705 +}
  706 +
  707 +void op_drotr (void)
  708 +{
  709 + target_ulong tmp;
  710 +
  711 + if (T1) {
  712 + tmp = T0 << (0x40 - T1);
  713 + T0 = (T0 >> T1) | tmp;
  714 + } else
  715 + T0 = T1;
  716 + RETURN();
  717 +}
  718 +
  719 +void op_drotr32 (void)
  720 +{
  721 + target_ulong tmp;
  722 +
  723 + if (T1) {
  724 + tmp = T0 << (0x40 - (32 + T1));
  725 + T0 = (T0 >> (32 + T1)) | tmp;
  726 + } else
  727 + T0 = T1;
  728 + RETURN();
  729 +}
  730 +
  731 +void op_dsllv (void)
  732 +{
  733 + T0 = T1 << (T0 & 0x3F);
  734 + RETURN();
  735 +}
  736 +
  737 +void op_dsrav (void)
  738 +{
  739 + T0 = (int64_t)T1 >> (T0 & 0x3F);
  740 + RETURN();
  741 +}
  742 +
  743 +void op_dsrlv (void)
  744 +{
  745 + T0 = T1 >> (T0 & 0x3F);
  746 + RETURN();
  747 +}
  748 +
  749 +void op_drotrv (void)
  750 +{
  751 + target_ulong tmp;
  752 +
  753 + T0 &= 0x3F;
  754 + if (T0) {
  755 + tmp = T1 << (0x40 - T0);
  756 + T0 = (T1 >> T0) | tmp;
  757 + } else
  758 + T0 = T1;
  759 + RETURN();
  760 +}
  761 +#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
  762 +
  763 +void op_dclo (void)
  764 +{
  765 + int n;
  766 +
  767 + if (T0 == ~((target_ulong)0)) {
  768 + T0 = 64;
  769 + } else {
  770 + for (n = 0; n < 64; n++) {
  771 + if (!(T0 & (1ULL << 63)))
  772 + break;
  773 + T0 = T0 << 1;
  774 + }
  775 + T0 = n;
  776 + }
  777 + RETURN();
  778 +}
  779 +
  780 +void op_dclz (void)
  781 +{
  782 + int n;
  783 +
  784 + if (T0 == 0) {
  785 + T0 = 64;
  786 + } else {
  787 + for (n = 0; n < 64; n++) {
  788 + if (T0 & (1ULL << 63))
  789 + break;
  790 + T0 = T0 << 1;
  791 + }
  792 + T0 = n;
  793 + }
  794 + RETURN();
  795 +}
  796 +#endif
  797 +
  798 +/* 64 bits arithmetic */
  799 +#if TARGET_LONG_BITS > HOST_LONG_BITS
578 void op_mult (void) 800 void op_mult (void)
579 { 801 {
580 CALL_FROM_TB0(do_mult); 802 CALL_FROM_TB0(do_mult);
@@ -610,6 +832,81 @@ void op_msubu (void) @@ -610,6 +832,81 @@ void op_msubu (void)
610 CALL_FROM_TB0(do_msubu); 832 CALL_FROM_TB0(do_msubu);
611 RETURN(); 833 RETURN();
612 } 834 }
  835 +
  836 +#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
  837 +
  838 +static inline uint64_t get_HILO (void)
  839 +{
  840 + return ((uint64_t)env->HI << 32) | ((uint64_t)(uint32_t)env->LO);
  841 +}
  842 +
  843 +static inline void set_HILO (uint64_t HILO)
  844 +{
  845 + env->LO = SIGN_EXTEND32(HILO & 0xFFFFFFFF);
  846 + env->HI = SIGN_EXTEND32(HILO >> 32);
  847 +}
  848 +
  849 +void op_mult (void)
  850 +{
  851 + set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
  852 + RETURN();
  853 +}
  854 +
  855 +void op_multu (void)
  856 +{
  857 + set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
  858 + RETURN();
  859 +}
  860 +
  861 +void op_madd (void)
  862 +{
  863 + int64_t tmp;
  864 +
  865 + tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
  866 + set_HILO((int64_t)get_HILO() + tmp);
  867 + RETURN();
  868 +}
  869 +
  870 +void op_maddu (void)
  871 +{
  872 + uint64_t tmp;
  873 +
  874 + tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
  875 + set_HILO(get_HILO() + tmp);
  876 + RETURN();
  877 +}
  878 +
  879 +void op_msub (void)
  880 +{
  881 + int64_t tmp;
  882 +
  883 + tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
  884 + set_HILO((int64_t)get_HILO() - tmp);
  885 + RETURN();
  886 +}
  887 +
  888 +void op_msubu (void)
  889 +{
  890 + uint64_t tmp;
  891 +
  892 + tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
  893 + set_HILO(get_HILO() - tmp);
  894 + RETURN();
  895 +}
  896 +#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
  897 +
  898 +#ifdef MIPS_HAS_MIPS64
  899 +void op_dmult (void)
  900 +{
  901 + CALL_FROM_TB0(do_dmult);
  902 + RETURN();
  903 +}
  904 +
  905 +void op_dmultu (void)
  906 +{
  907 + CALL_FROM_TB0(do_dmultu);
  908 + RETURN();
  909 +}
613 #endif 910 #endif
614 911
615 /* Conditional moves */ 912 /* Conditional moves */
@@ -735,7 +1032,7 @@ void op_jnz_T2 (void) @@ -735,7 +1032,7 @@ void op_jnz_T2 (void)
735 /* CP0 functions */ 1032 /* CP0 functions */
736 void op_mfc0_index (void) 1033 void op_mfc0_index (void)
737 { 1034 {
738 - T0 = env->CP0_index; 1035 + T0 = SIGN_EXTEND32(env->CP0_index);
739 RETURN(); 1036 RETURN();
740 } 1037 }
741 1038
@@ -765,25 +1062,25 @@ void op_mfc0_context (void) @@ -765,25 +1062,25 @@ void op_mfc0_context (void)
765 1062
766 void op_mfc0_pagemask (void) 1063 void op_mfc0_pagemask (void)
767 { 1064 {
768 - T0 = env->CP0_PageMask; 1065 + T0 = SIGN_EXTEND32(env->CP0_PageMask);
769 RETURN(); 1066 RETURN();
770 } 1067 }
771 1068
772 void op_mfc0_pagegrain (void) 1069 void op_mfc0_pagegrain (void)
773 { 1070 {
774 - T0 = env->CP0_PageGrain; 1071 + T0 = SIGN_EXTEND32(env->CP0_PageGrain);
775 RETURN(); 1072 RETURN();
776 } 1073 }
777 1074
778 void op_mfc0_wired (void) 1075 void op_mfc0_wired (void)
779 { 1076 {
780 - T0 = env->CP0_Wired; 1077 + T0 = SIGN_EXTEND32(env->CP0_Wired);
781 RETURN(); 1078 RETURN();
782 } 1079 }
783 1080
784 void op_mfc0_hwrena (void) 1081 void op_mfc0_hwrena (void)
785 { 1082 {
786 - T0 = env->CP0_HWREna; 1083 + T0 = SIGN_EXTEND32(env->CP0_HWREna);
787 RETURN(); 1084 RETURN();
788 } 1085 }
789 1086
@@ -807,13 +1104,13 @@ void op_mfc0_entryhi (void) @@ -807,13 +1104,13 @@ void op_mfc0_entryhi (void)
807 1104
808 void op_mfc0_compare (void) 1105 void op_mfc0_compare (void)
809 { 1106 {
810 - T0 = env->CP0_Compare; 1107 + T0 = SIGN_EXTEND32(env->CP0_Compare);
811 RETURN(); 1108 RETURN();
812 } 1109 }
813 1110
814 void op_mfc0_status (void) 1111 void op_mfc0_status (void)
815 { 1112 {
816 - T0 = env->CP0_Status; 1113 + T0 = SIGN_EXTEND32(env->CP0_Status);
817 if (env->hflags & MIPS_HFLAG_UM) 1114 if (env->hflags & MIPS_HFLAG_UM)
818 T0 |= (1 << CP0St_UM); 1115 T0 |= (1 << CP0St_UM);
819 if (env->hflags & MIPS_HFLAG_ERL) 1116 if (env->hflags & MIPS_HFLAG_ERL)
@@ -825,19 +1122,19 @@ void op_mfc0_status (void) @@ -825,19 +1122,19 @@ void op_mfc0_status (void)
825 1122
826 void op_mfc0_intctl (void) 1123 void op_mfc0_intctl (void)
827 { 1124 {
828 - T0 = env->CP0_IntCtl; 1125 + T0 = SIGN_EXTEND32(env->CP0_IntCtl);
829 RETURN(); 1126 RETURN();
830 } 1127 }
831 1128
832 void op_mfc0_srsctl (void) 1129 void op_mfc0_srsctl (void)
833 { 1130 {
834 - T0 = env->CP0_SRSCtl; 1131 + T0 = SIGN_EXTEND32(env->CP0_SRSCtl);
835 RETURN(); 1132 RETURN();
836 } 1133 }
837 1134
838 void op_mfc0_cause (void) 1135 void op_mfc0_cause (void)
839 { 1136 {
840 - T0 = env->CP0_Cause; 1137 + T0 = SIGN_EXTEND32(env->CP0_Cause);
841 RETURN(); 1138 RETURN();
842 } 1139 }
843 1140
@@ -849,7 +1146,7 @@ void op_mfc0_epc (void) @@ -849,7 +1146,7 @@ void op_mfc0_epc (void)
849 1146
850 void op_mfc0_prid (void) 1147 void op_mfc0_prid (void)
851 { 1148 {
852 - T0 = env->CP0_PRid; 1149 + T0 = SIGN_EXTEND32(env->CP0_PRid);
853 RETURN(); 1150 RETURN();
854 } 1151 }
855 1152
@@ -861,25 +1158,25 @@ void op_mfc0_ebase (void) @@ -861,25 +1158,25 @@ void op_mfc0_ebase (void)
861 1158
862 void op_mfc0_config0 (void) 1159 void op_mfc0_config0 (void)
863 { 1160 {
864 - T0 = env->CP0_Config0; 1161 + T0 = SIGN_EXTEND32(env->CP0_Config0);
865 RETURN(); 1162 RETURN();
866 } 1163 }
867 1164
868 void op_mfc0_config1 (void) 1165 void op_mfc0_config1 (void)
869 { 1166 {
870 - T0 = env->CP0_Config1; 1167 + T0 = SIGN_EXTEND32(env->CP0_Config1);
871 RETURN(); 1168 RETURN();
872 } 1169 }
873 1170
874 void op_mfc0_config2 (void) 1171 void op_mfc0_config2 (void)
875 { 1172 {
876 - T0 = env->CP0_Config2; 1173 + T0 = SIGN_EXTEND32(env->CP0_Config2);
877 RETURN(); 1174 RETURN();
878 } 1175 }
879 1176
880 void op_mfc0_config3 (void) 1177 void op_mfc0_config3 (void)
881 { 1178 {
882 - T0 = env->CP0_Config3; 1179 + T0 = SIGN_EXTEND32(env->CP0_Config3);
883 RETURN(); 1180 RETURN();
884 } 1181 }
885 1182
@@ -891,13 +1188,13 @@ void op_mfc0_lladdr (void) @@ -891,13 +1188,13 @@ void op_mfc0_lladdr (void)
891 1188
892 void op_mfc0_watchlo0 (void) 1189 void op_mfc0_watchlo0 (void)
893 { 1190 {
894 - T0 = env->CP0_WatchLo; 1191 + T0 = SIGN_EXTEND32(env->CP0_WatchLo);
895 RETURN(); 1192 RETURN();
896 } 1193 }
897 1194
898 void op_mfc0_watchhi0 (void) 1195 void op_mfc0_watchhi0 (void)
899 { 1196 {
900 - T0 = env->CP0_WatchHi; 1197 + T0 = SIGN_EXTEND32(env->CP0_WatchHi);
901 RETURN(); 1198 RETURN();
902 } 1199 }
903 1200
@@ -915,7 +1212,7 @@ void op_mfc0_framemask (void) @@ -915,7 +1212,7 @@ void op_mfc0_framemask (void)
915 1212
916 void op_mfc0_debug (void) 1213 void op_mfc0_debug (void)
917 { 1214 {
918 - T0 = env->CP0_Debug; 1215 + T0 = SIGN_EXTEND32(env->CP0_Debug);
919 if (env->hflags & MIPS_HFLAG_DM) 1216 if (env->hflags & MIPS_HFLAG_DM)
920 T0 |= 1 << CP0DB_DM; 1217 T0 |= 1 << CP0DB_DM;
921 RETURN(); 1218 RETURN();
@@ -929,31 +1226,31 @@ void op_mfc0_depc (void) @@ -929,31 +1226,31 @@ void op_mfc0_depc (void)
929 1226
930 void op_mfc0_performance0 (void) 1227 void op_mfc0_performance0 (void)
931 { 1228 {
932 - T0 = env->CP0_Performance0; 1229 + T0 = SIGN_EXTEND32(env->CP0_Performance0);
933 RETURN(); 1230 RETURN();
934 } 1231 }
935 1232
936 void op_mfc0_taglo (void) 1233 void op_mfc0_taglo (void)
937 { 1234 {
938 - T0 = env->CP0_TagLo; 1235 + T0 = SIGN_EXTEND32(env->CP0_TagLo);
939 RETURN(); 1236 RETURN();
940 } 1237 }
941 1238
942 void op_mfc0_datalo (void) 1239 void op_mfc0_datalo (void)
943 { 1240 {
944 - T0 = env->CP0_DataLo; 1241 + T0 = SIGN_EXTEND32(env->CP0_DataLo);
945 RETURN(); 1242 RETURN();
946 } 1243 }
947 1244
948 void op_mfc0_taghi (void) 1245 void op_mfc0_taghi (void)
949 { 1246 {
950 - T0 = env->CP0_TagHi; 1247 + T0 = SIGN_EXTEND32(env->CP0_TagHi);
951 RETURN(); 1248 RETURN();
952 } 1249 }
953 1250
954 void op_mfc0_datahi (void) 1251 void op_mfc0_datahi (void)
955 { 1252 {
956 - T0 = env->CP0_DataHi; 1253 + T0 = SIGN_EXTEND32(env->CP0_DataHi);
957 RETURN(); 1254 RETURN();
958 } 1255 }
959 1256
@@ -965,7 +1262,7 @@ void op_mfc0_errorepc (void) @@ -965,7 +1262,7 @@ void op_mfc0_errorepc (void)
965 1262
966 void op_mfc0_desave (void) 1263 void op_mfc0_desave (void)
967 { 1264 {
968 - T0 = env->CP0_DESAVE; 1265 + T0 = SIGN_EXTEND32(env->CP0_DESAVE);
969 RETURN(); 1266 RETURN();
970 } 1267 }
971 1268
@@ -979,7 +1276,7 @@ void op_mtc0_entrylo0 (void) @@ -979,7 +1276,7 @@ void op_mtc0_entrylo0 (void)
979 { 1276 {
980 /* Large physaddr not implemented */ 1277 /* Large physaddr not implemented */
981 /* 1k pages not implemented */ 1278 /* 1k pages not implemented */
982 - env->CP0_EntryLo0 = T0 & 0x3FFFFFFFUL; 1279 + env->CP0_EntryLo0 = T0 & SIGN_EXTEND32(0x3FFFFFFFUL);
983 RETURN(); 1280 RETURN();
984 } 1281 }
985 1282
@@ -987,7 +1284,7 @@ void op_mtc0_entrylo1 (void) @@ -987,7 +1284,7 @@ void op_mtc0_entrylo1 (void)
987 { 1284 {
988 /* Large physaddr not implemented */ 1285 /* Large physaddr not implemented */
989 /* 1k pages not implemented */ 1286 /* 1k pages not implemented */
990 - env->CP0_EntryLo1 = T0 & 0x3FFFFFFFUL; 1287 + env->CP0_EntryLo1 = T0 & SIGN_EXTEND32(0x3FFFFFFFUL);
991 RETURN(); 1288 RETURN();
992 } 1289 }
993 1290
@@ -1037,7 +1334,7 @@ void op_mtc0_entryhi (void) @@ -1037,7 +1334,7 @@ void op_mtc0_entryhi (void)
1037 1334
1038 /* 1k pages not implemented */ 1335 /* 1k pages not implemented */
1039 /* Ignore MIPS64 TLB for now */ 1336 /* Ignore MIPS64 TLB for now */
1040 - val = T0 & 0xFFFFE0FF; 1337 + val = T0 & SIGN_EXTEND32(0xFFFFE0FF);
1041 old = env->CP0_EntryHi; 1338 old = env->CP0_EntryHi;
1042 env->CP0_EntryHi = val; 1339 env->CP0_EntryHi = val;
1043 /* If the ASID changes, flush qemu's TLB. */ 1340 /* If the ASID changes, flush qemu's TLB. */
@@ -1056,7 +1353,7 @@ void op_mtc0_status (void) @@ -1056,7 +1353,7 @@ void op_mtc0_status (void)
1056 { 1353 {
1057 uint32_t val, old, mask; 1354 uint32_t val, old, mask;
1058 1355
1059 - val = T0 & 0xFA78FF01; 1356 + val = T0 & SIGN_EXTEND32(0xFA78FF01);
1060 old = env->CP0_Status; 1357 old = env->CP0_Status;
1061 if (T0 & (1 << CP0St_UM)) 1358 if (T0 & (1 << CP0St_UM))
1062 env->hflags |= MIPS_HFLAG_UM; 1359 env->hflags |= MIPS_HFLAG_UM;
@@ -1107,7 +1404,7 @@ void op_mtc0_cause (void) @@ -1107,7 +1404,7 @@ void op_mtc0_cause (void)
1107 { 1404 {
1108 uint32_t val, old; 1405 uint32_t val, old;
1109 1406
1110 - val = (env->CP0_Cause & 0xB000F87C) | (T0 & 0x000C00300); 1407 + val = (env->CP0_Cause & 0xB000F87C) | (T0 & 0x00C00300);
1111 old = env->CP0_Cause; 1408 old = env->CP0_Cause;
1112 env->CP0_Cause = val; 1409 env->CP0_Cause = val;
1113 #if 0 1410 #if 0
@@ -1134,7 +1431,7 @@ void op_mtc0_ebase (void) @@ -1134,7 +1431,7 @@ void op_mtc0_ebase (void)
1134 { 1431 {
1135 /* vectored interrupts not implemented */ 1432 /* vectored interrupts not implemented */
1136 /* Multi-CPU not implemented */ 1433 /* Multi-CPU not implemented */
1137 - env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000); 1434 + env->CP0_EBase = SIGN_EXTEND32(0x80000000) | (T0 & 0x3FFFF000);
1138 RETURN(); 1435 RETURN();
1139 } 1436 }
1140 1437
@@ -1204,7 +1501,7 @@ void op_mtc0_performance0 (void) @@ -1204,7 +1501,7 @@ void op_mtc0_performance0 (void)
1204 1501
1205 void op_mtc0_taglo (void) 1502 void op_mtc0_taglo (void)
1206 { 1503 {
1207 - env->CP0_TagLo = T0 & 0xFFFFFCF6; 1504 + env->CP0_TagLo = T0 & SIGN_EXTEND32(0xFFFFFCF6);
1208 RETURN(); 1505 RETURN();
1209 } 1506 }
1210 1507
@@ -1787,7 +2084,7 @@ void op_ext(void) @@ -1787,7 +2084,7 @@ void op_ext(void)
1787 unsigned int pos = PARAM1; 2084 unsigned int pos = PARAM1;
1788 unsigned int size = PARAM2; 2085 unsigned int size = PARAM2;
1789 2086
1790 - T0 = (T1 >> pos) & ((1 << size) - 1); 2087 + T0 = ((uint32_t)T1 >> pos) & ((1 << size) - 1);
1791 RETURN(); 2088 RETURN();
1792 } 2089 }
1793 2090
@@ -1797,7 +2094,7 @@ void op_ins(void) @@ -1797,7 +2094,7 @@ void op_ins(void)
1797 unsigned int size = PARAM2; 2094 unsigned int size = PARAM2;
1798 target_ulong mask = ((1 << size) - 1) << pos; 2095 target_ulong mask = ((1 << size) - 1) << pos;
1799 2096
1800 - T0 = (T2 & ~mask) | ((T1 << pos) & mask); 2097 + T0 = (T2 & ~mask) | (((uint32_t)T1 << pos) & mask);
1801 RETURN(); 2098 RETURN();
1802 } 2099 }
1803 2100
@@ -1807,6 +2104,26 @@ void op_wsbh(void) @@ -1807,6 +2104,26 @@ void op_wsbh(void)
1807 RETURN(); 2104 RETURN();
1808 } 2105 }
1809 2106
  2107 +#ifdef MIPS_HAS_MIPS64
  2108 +void op_dext(void)
  2109 +{
  2110 + unsigned int pos = PARAM1;
  2111 + unsigned int size = PARAM2;
  2112 +
  2113 + T0 = (T1 >> pos) & ((1 << size) - 1);
  2114 + RETURN();
  2115 +}
  2116 +
  2117 +void op_dins(void)
  2118 +{
  2119 + unsigned int pos = PARAM1;
  2120 + unsigned int size = PARAM2;
  2121 + target_ulong mask = ((1 << size) - 1) << pos;
  2122 +
  2123 + T0 = (T2 & ~mask) | ((T1 << pos) & mask);
  2124 + RETURN();
  2125 +}
  2126 +
1810 void op_dsbh(void) 2127 void op_dsbh(void)
1811 { 2128 {
1812 T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL); 2129 T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
@@ -1818,6 +2135,7 @@ void op_dshd(void) @@ -1818,6 +2135,7 @@ void op_dshd(void)
1818 T0 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL); 2135 T0 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
1819 RETURN(); 2136 RETURN();
1820 } 2137 }
  2138 +#endif
1821 2139
1822 void op_seb(void) 2140 void op_seb(void)
1823 { 2141 {
target-mips/op_helper.c
@@ -74,8 +74,92 @@ void do_raise_exception_direct (uint32_t exception) @@ -74,8 +74,92 @@ void do_raise_exception_direct (uint32_t exception)
74 #undef MEMSUFFIX 74 #undef MEMSUFFIX
75 #endif 75 #endif
76 76
  77 +#ifdef MIPS_HAS_MIPS64
  78 +#if TARGET_LONG_BITS > HOST_LONG_BITS
  79 +/* Those might call libgcc functions. */
  80 +void do_dsll (void)
  81 +{
  82 + T0 = T0 << T1;
  83 +}
  84 +
  85 +void do_dsll32 (void)
  86 +{
  87 + T0 = T0 << (T1 + 32);
  88 +}
  89 +
  90 +void do_dsra (void)
  91 +{
  92 + T0 = (int64_t)T0 >> T1;
  93 +}
  94 +
  95 +void do_dsra32 (void)
  96 +{
  97 + T0 = (int64_t)T0 >> (T1 + 32);
  98 +}
  99 +
  100 +void do_dsrl (void)
  101 +{
  102 + T0 = T0 >> T1;
  103 +}
  104 +
  105 +void do_dsrl32 (void)
  106 +{
  107 + T0 = T0 >> (T1 + 32);
  108 +}
  109 +
  110 +void do_drotr (void)
  111 +{
  112 + target_ulong tmp;
  113 +
  114 + if (T1) {
  115 + tmp = T0 << (0x40 - T1);
  116 + T0 = (T0 >> T1) | tmp;
  117 + } else
  118 + T0 = T1;
  119 +}
  120 +
  121 +void do_drotr32 (void)
  122 +{
  123 + target_ulong tmp;
  124 +
  125 + if (T1) {
  126 + tmp = T0 << (0x40 - (32 + T1));
  127 + T0 = (T0 >> (32 + T1)) | tmp;
  128 + } else
  129 + T0 = T1;
  130 +}
  131 +
  132 +void do_dsllv (void)
  133 +{
  134 + T0 = T1 << (T0 & 0x3F);
  135 +}
  136 +
  137 +void do_dsrav (void)
  138 +{
  139 + T0 = (int64_t)T1 >> (T0 & 0x3F);
  140 +}
  141 +
  142 +void do_dsrlv (void)
  143 +{
  144 + T0 = T1 >> (T0 & 0x3F);
  145 +}
  146 +
  147 +void do_drotrv (void)
  148 +{
  149 + target_ulong tmp;
  150 +
  151 + T0 &= 0x3F;
  152 + if (T0) {
  153 + tmp = T1 << (0x40 - T0);
  154 + T0 = (T1 >> T0) | tmp;
  155 + } else
  156 + T0 = T1;
  157 +}
  158 +#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
  159 +#endif /* MIPS_HAS_MIPS64 */
  160 +
77 /* 64 bits arithmetic for 32 bits hosts */ 161 /* 64 bits arithmetic for 32 bits hosts */
78 -#if (HOST_LONG_BITS == 32) 162 +#if TARGET_LONG_BITS > HOST_LONG_BITS
79 static inline uint64_t get_HILO (void) 163 static inline uint64_t get_HILO (void)
80 { 164 {
81 return ((uint64_t)env->HI << 32) | (uint64_t)env->LO; 165 return ((uint64_t)env->HI << 32) | (uint64_t)env->LO;
@@ -83,8 +167,8 @@ static inline uint64_t get_HILO (void) @@ -83,8 +167,8 @@ static inline uint64_t get_HILO (void)
83 167
84 static inline void set_HILO (uint64_t HILO) 168 static inline void set_HILO (uint64_t HILO)
85 { 169 {
86 - env->LO = HILO & 0xFFFFFFFF;  
87 - env->HI = HILO >> 32; 170 + env->LO = SIGN_EXTEND32(HILO & 0xFFFFFFFF);
  171 + env->HI = SIGN_EXTEND32(HILO >> 32);
88 } 172 }
89 173
90 void do_mult (void) 174 void do_mult (void)
@@ -94,7 +178,7 @@ void do_mult (void) @@ -94,7 +178,7 @@ void do_mult (void)
94 178
95 void do_multu (void) 179 void do_multu (void)
96 { 180 {
97 - set_HILO((uint64_t)T0 * (uint64_t)T1); 181 + set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
98 } 182 }
99 183
100 void do_madd (void) 184 void do_madd (void)
@@ -109,7 +193,7 @@ void do_maddu (void) @@ -109,7 +193,7 @@ void do_maddu (void)
109 { 193 {
110 uint64_t tmp; 194 uint64_t tmp;
111 195
112 - tmp = ((uint64_t)T0 * (uint64_t)T1); 196 + tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
113 set_HILO(get_HILO() + tmp); 197 set_HILO(get_HILO() + tmp);
114 } 198 }
115 199
@@ -125,11 +209,41 @@ void do_msubu (void) @@ -125,11 +209,41 @@ void do_msubu (void)
125 { 209 {
126 uint64_t tmp; 210 uint64_t tmp;
127 211
128 - tmp = ((uint64_t)T0 * (uint64_t)T1); 212 + tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
129 set_HILO(get_HILO() - tmp); 213 set_HILO(get_HILO() - tmp);
130 } 214 }
131 #endif 215 #endif
132 216
  217 +#ifdef MIPS_HAS_MIPS64
  218 +void do_dmult (void)
  219 +{
  220 + /* XXX */
  221 + set_HILO((int64_t)T0 * (int64_t)T1);
  222 +}
  223 +
  224 +void do_dmultu (void)
  225 +{
  226 + /* XXX */
  227 + set_HILO((uint64_t)T0 * (uint64_t)T1);
  228 +}
  229 +
  230 +void do_ddiv (void)
  231 +{
  232 + if (T1 != 0) {
  233 + env->LO = (int64_t)T0 / (int64_t)T1;
  234 + env->HI = (int64_t)T0 % (int64_t)T1;
  235 + }
  236 +}
  237 +
  238 +void do_ddivu (void)
  239 +{
  240 + if (T1 != 0) {
  241 + env->LO = T0 / T1;
  242 + env->HI = T0 % T1;
  243 + }
  244 +}
  245 +#endif
  246 +
133 #if defined(CONFIG_USER_ONLY) 247 #if defined(CONFIG_USER_ONLY)
134 void do_mfc0_random (void) 248 void do_mfc0_random (void)
135 { 249 {
@@ -191,12 +305,12 @@ void cpu_mips_tlb_flush (CPUState *env, int flush_global) @@ -191,12 +305,12 @@ void cpu_mips_tlb_flush (CPUState *env, int flush_global)
191 /* CP0 helpers */ 305 /* CP0 helpers */
192 void do_mfc0_random (void) 306 void do_mfc0_random (void)
193 { 307 {
194 - T0 = cpu_mips_get_random(env); 308 + T0 = SIGN_EXTEND32(cpu_mips_get_random(env));
195 } 309 }
196 310
197 void do_mfc0_count (void) 311 void do_mfc0_count (void)
198 { 312 {
199 - T0 = cpu_mips_get_count(env); 313 + T0 = SIGN_EXTEND32(cpu_mips_get_count(env));
200 } 314 }
201 315
202 void do_mtc0_status_debug(uint32_t old, uint32_t val) 316 void do_mtc0_status_debug(uint32_t old, uint32_t val)
@@ -319,7 +433,7 @@ static void fill_tlb (int idx) @@ -319,7 +433,7 @@ static void fill_tlb (int idx)
319 433
320 /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */ 434 /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */
321 tlb = &env->tlb[idx]; 435 tlb = &env->tlb[idx];
322 - tlb->VPN = env->CP0_EntryHi & 0xFFFFE000; 436 + tlb->VPN = env->CP0_EntryHi & SIGN_EXTEND32(0xFFFFE000);
323 tlb->ASID = env->CP0_EntryHi & 0xFF; 437 tlb->ASID = env->CP0_EntryHi & 0xFF;
324 size = env->CP0_PageMask >> 13; 438 size = env->CP0_PageMask >> 13;
325 size = 4 * (size + 1); 439 size = 4 * (size + 1);
@@ -364,7 +478,7 @@ void do_tlbp (void) @@ -364,7 +478,7 @@ void do_tlbp (void)
364 uint8_t ASID; 478 uint8_t ASID;
365 int i; 479 int i;
366 480
367 - tag = env->CP0_EntryHi & 0xFFFFE000; 481 + tag = env->CP0_EntryHi & SIGN_EXTEND32(0xFFFFE000);
368 ASID = env->CP0_EntryHi & 0xFF; 482 ASID = env->CP0_EntryHi & 0xFF;
369 for (i = 0; i < MIPS_TLB_NB; i++) { 483 for (i = 0; i < MIPS_TLB_NB; i++) {
370 tlb = &env->tlb[i]; 484 tlb = &env->tlb[i];
@@ -418,16 +532,16 @@ void do_tlbr (void) @@ -418,16 +532,16 @@ void do_tlbr (void)
418 532
419 #endif /* !CONFIG_USER_ONLY */ 533 #endif /* !CONFIG_USER_ONLY */
420 534
421 -void op_dump_ldst (const unsigned char *func) 535 +void dump_ldst (const unsigned char *func)
422 { 536 {
423 if (loglevel) 537 if (loglevel)
424 - fprintf(logfile, "%s => %08x %08x\n", __func__, T0, T1); 538 + fprintf(logfile, "%s => " TLSZ " " TLSZ "\n", __func__, T0, T1);
425 } 539 }
426 540
427 void dump_sc (void) 541 void dump_sc (void)
428 { 542 {
429 if (loglevel) { 543 if (loglevel) {
430 - fprintf(logfile, "%s %08x at %08x (%08x)\n", __func__, 544 + fprintf(logfile, "%s " TLSZ " at " TLSZ " (" TLSZ ")\n", __func__,
431 T1, T0, env->CP0_LLAddr); 545 T1, T0, env->CP0_LLAddr);
432 } 546 }
433 } 547 }
@@ -435,7 +549,7 @@ void dump_sc (void) @@ -435,7 +549,7 @@ void dump_sc (void)
435 void debug_eret (void) 549 void debug_eret (void)
436 { 550 {
437 if (loglevel) { 551 if (loglevel) {
438 - fprintf(logfile, "ERET: pc %08x EPC %08x ErrorEPC %08x (%d)\n", 552 + fprintf(logfile, "ERET: pc " TLSZ " EPC " TLSZ " ErrorEPC " TLSZ " (%d)\n",
439 env->PC, env->CP0_EPC, env->CP0_ErrorEPC, 553 env->PC, env->CP0_EPC, env->CP0_ErrorEPC,
440 env->hflags & MIPS_HFLAG_ERL ? 1 : 0); 554 env->hflags & MIPS_HFLAG_ERL ? 1 : 0);
441 } 555 }
@@ -454,13 +568,13 @@ void do_pmon (int function) @@ -454,13 +568,13 @@ void do_pmon (int function)
454 break; 568 break;
455 case 3: 569 case 3:
456 case 12: 570 case 12:
457 - printf("%c", env->gpr[4] & 0xFF); 571 + printf("%c", (char)(env->gpr[4] & 0xFF));
458 break; 572 break;
459 case 17: 573 case 17:
460 break; 574 break;
461 case 158: 575 case 158:
462 { 576 {
463 - unsigned char *fmt = (void *)env->gpr[4]; 577 + unsigned char *fmt = (void *)(unsigned long)env->gpr[4];
464 printf("%s", fmt); 578 printf("%s", fmt);
465 } 579 }
466 break; 580 break;
target-mips/op_helper_mem.c
@@ -10,9 +10,6 @@ void glue(do_lwl, MEMSUFFIX) (uint32_t tmp) @@ -10,9 +10,6 @@ void glue(do_lwl, MEMSUFFIX) (uint32_t tmp)
10 target_ulong sav = T0; 10 target_ulong sav = T0;
11 #endif 11 #endif
12 12
13 - /* XXX: this is valid only in big-endian mode  
14 - * should be reverted for little-endian...  
15 - */  
16 switch (GET_LMASK(T0)) { 13 switch (GET_LMASK(T0)) {
17 case 0: 14 case 0:
18 T0 = tmp; 15 T0 = tmp;
@@ -42,9 +39,6 @@ void glue(do_lwr, MEMSUFFIX) (uint32_t tmp) @@ -42,9 +39,6 @@ void glue(do_lwr, MEMSUFFIX) (uint32_t tmp)
42 target_ulong sav = T0; 39 target_ulong sav = T0;
43 #endif 40 #endif
44 41
45 - /* XXX: this is valid only in big-endian mode  
46 - * should be reverted for little-endian...  
47 - */  
48 switch (GET_LMASK(T0)) { 42 switch (GET_LMASK(T0)) {
49 case 0: 43 case 0:
50 T0 = (tmp >> 24) | (T1 & 0xFFFFFF00); 44 T0 = (tmp >> 24) | (T1 & 0xFFFFFF00);
@@ -71,15 +65,9 @@ void glue(do_lwr, MEMSUFFIX) (uint32_t tmp) @@ -71,15 +65,9 @@ void glue(do_lwr, MEMSUFFIX) (uint32_t tmp)
71 uint32_t glue(do_swl, MEMSUFFIX) (uint32_t tmp) 65 uint32_t glue(do_swl, MEMSUFFIX) (uint32_t tmp)
72 { 66 {
73 #if defined (DEBUG_OP) 67 #if defined (DEBUG_OP)
74 - target_ulong sav; 68 + target_ulong sav = tmp;
75 #endif 69 #endif
76 70
77 -#if defined (DEBUG_OP)  
78 - sav = tmp;  
79 -#endif  
80 - /* XXX: this is valid only in big-endian mode  
81 - * should be reverted for little-endian...  
82 - */  
83 switch (GET_LMASK(T0)) { 71 switch (GET_LMASK(T0)) {
84 case 0: 72 case 0:
85 tmp = T1; 73 tmp = T1;
@@ -107,15 +95,9 @@ uint32_t glue(do_swl, MEMSUFFIX) (uint32_t tmp) @@ -107,15 +95,9 @@ uint32_t glue(do_swl, MEMSUFFIX) (uint32_t tmp)
107 uint32_t glue(do_swr, MEMSUFFIX) (uint32_t tmp) 95 uint32_t glue(do_swr, MEMSUFFIX) (uint32_t tmp)
108 { 96 {
109 #if defined (DEBUG_OP) 97 #if defined (DEBUG_OP)
110 - target_ulong sav; 98 + target_ulong sav = tmp;
111 #endif 99 #endif
112 100
113 -#if defined (DEBUG_OP)  
114 - sav = tmp;  
115 -#endif  
116 - /* XXX: this is valid only in big-endian mode  
117 - * should be reverted for little-endian...  
118 - */  
119 switch (GET_LMASK(T0)) { 101 switch (GET_LMASK(T0)) {
120 case 0: 102 case 0:
121 tmp = (tmp & 0x00FFFFFF) | (T1 << 24); 103 tmp = (tmp & 0x00FFFFFF) | (T1 << 24);
@@ -139,3 +121,179 @@ uint32_t glue(do_swr, MEMSUFFIX) (uint32_t tmp) @@ -139,3 +121,179 @@ uint32_t glue(do_swr, MEMSUFFIX) (uint32_t tmp)
139 RETURN(); 121 RETURN();
140 return tmp; 122 return tmp;
141 } 123 }
  124 +
  125 +#ifdef MIPS_HAS_MIPS64
  126 +
  127 +# ifdef TARGET_WORDS_BIGENDIAN
  128 +#define GET_LMASK64(v) ((v) & 4)
  129 +#else
  130 +#define GET_LMASK64(v) (((v) & 4) ^ 4)
  131 +#endif
  132 +
  133 +void glue(do_ldl, MEMSUFFIX) (uint64_t tmp)
  134 +{
  135 +#if defined (DEBUG_OP)
  136 + target_ulong sav = T0;
  137 +#endif
  138 +
  139 + switch (GET_LMASK64(T0)) {
  140 + case 0:
  141 + T0 = tmp;
  142 + break;
  143 + case 1:
  144 + T0 = (tmp << 8) | (T1 & 0x00000000000000FFULL);
  145 + break;
  146 + case 2:
  147 + T0 = (tmp << 16) | (T1 & 0x000000000000FFFFULL);
  148 + break;
  149 + case 3:
  150 + T0 = (tmp << 24) | (T1 & 0x0000000000FFFFFFULL);
  151 + break;
  152 + case 4:
  153 + T0 = (tmp << 32) | (T1 & 0x00000000FFFFFFFFULL);
  154 + break;
  155 + case 5:
  156 + T0 = (tmp << 40) | (T1 & 0x000000FFFFFFFFFFULL);
  157 + break;
  158 + case 6:
  159 + T0 = (tmp << 48) | (T1 & 0x0000FFFFFFFFFFFFULL);
  160 + break;
  161 + case 7:
  162 + T0 = (tmp << 56) | (T1 & 0x00FFFFFFFFFFFFFFULL);
  163 + break;
  164 + }
  165 +#if defined (DEBUG_OP)
  166 + if (logfile) {
  167 + fprintf(logfile, "%s: %08x - %08x %08x => %08x\n",
  168 + __func__, sav, tmp, T1, T0);
  169 + }
  170 +#endif
  171 + RETURN();
  172 +}
  173 +
  174 +void glue(do_ldr, MEMSUFFIX) (uint64_t tmp)
  175 +{
  176 +#if defined (DEBUG_OP)
  177 + target_ulong sav = T0;
  178 +#endif
  179 +
  180 + switch (GET_LMASK64(T0)) {
  181 + case 0:
  182 + T0 = (tmp >> 56) | (T1 & 0xFFFFFFFFFFFFFF00ULL);
  183 + break;
  184 + case 1:
  185 + T0 = (tmp >> 48) | (T1 & 0xFFFFFFFFFFFF0000ULL);
  186 + break;
  187 + case 2:
  188 + T0 = (tmp >> 40) | (T1 & 0xFFFFFFFFFF000000ULL);
  189 + break;
  190 + case 3:
  191 + T0 = (tmp >> 32) | (T1 & 0xFFFFFFFF00000000ULL);
  192 + break;
  193 + case 4:
  194 + T0 = (tmp >> 24) | (T1 & 0xFFFFFF0000000000ULL);
  195 + break;
  196 + case 5:
  197 + T0 = (tmp >> 16) | (T1 & 0xFFFF000000000000ULL);
  198 + break;
  199 + case 6:
  200 + T0 = (tmp >> 8) | (T1 & 0xFF00000000000000ULL);
  201 + break;
  202 + case 7:
  203 + T0 = tmp;
  204 + break;
  205 + }
  206 +#if defined (DEBUG_OP)
  207 + if (logfile) {
  208 + fprintf(logfile, "%s: %08x - %08x %08x => %08x\n",
  209 + __func__, sav, tmp, T1, T0);
  210 + }
  211 +#endif
  212 + RETURN();
  213 +}
  214 +
  215 +uint64_t glue(do_sdl, MEMSUFFIX) (uint64_t tmp)
  216 +{
  217 +#if defined (DEBUG_OP)
  218 + target_ulong sav = tmp;
  219 +#endif
  220 +
  221 + switch (GET_LMASK64(T0)) {
  222 + case 0:
  223 + tmp = T1;
  224 + break;
  225 + case 1:
  226 + tmp = (tmp & 0xFF00000000000000ULL) | (T1 >> 8);
  227 + break;
  228 + case 2:
  229 + tmp = (tmp & 0xFFFF000000000000ULL) | (T1 >> 16);
  230 + break;
  231 + case 3:
  232 + tmp = (tmp & 0xFFFFFF0000000000ULL) | (T1 >> 24);
  233 + break;
  234 + case 4:
  235 + tmp = (tmp & 0xFFFFFFFF00000000ULL) | (T1 >> 32);
  236 + break;
  237 + case 5:
  238 + tmp = (tmp & 0xFFFFFFFFFF000000ULL) | (T1 >> 40);
  239 + break;
  240 + case 6:
  241 + tmp = (tmp & 0xFFFFFFFFFFFF0000ULL) | (T1 >> 48);
  242 + break;
  243 + case 7:
  244 + tmp = (tmp & 0xFFFFFFFFFFFFFF00ULL) | (T1 >> 56);
  245 + break;
  246 + }
  247 +#if defined (DEBUG_OP)
  248 + if (logfile) {
  249 + fprintf(logfile, "%s: %08x - %08x %08x => %08x\n",
  250 + __func__, T0, sav, T1, tmp);
  251 + }
  252 +#endif
  253 + RETURN();
  254 + return tmp;
  255 +}
  256 +
  257 +uint64_t glue(do_sdr, MEMSUFFIX) (uint64_t tmp)
  258 +{
  259 +#if defined (DEBUG_OP)
  260 + target_ulong sav = tmp;
  261 +#endif
  262 +
  263 + switch (GET_LMASK64(T0)) {
  264 + case 0:
  265 + tmp = (tmp & 0x00FFFFFFFFFFFFFFULL) | (T1 << 56);
  266 + break;
  267 + case 1:
  268 + tmp = (tmp & 0x0000FFFFFFFFFFFFULL) | (T1 << 48);
  269 + break;
  270 + case 2:
  271 + tmp = (tmp & 0x000000FFFFFFFFFFULL) | (T1 << 40);
  272 + break;
  273 + case 3:
  274 + tmp = (tmp & 0x00000000FFFFFFFFULL) | (T1 << 32);
  275 + break;
  276 + case 4:
  277 + tmp = (tmp & 0x0000000000FFFFFFULL) | (T1 << 24);
  278 + break;
  279 + case 5:
  280 + tmp = (tmp & 0x000000000000FFFFULL) | (T1 << 16);
  281 + break;
  282 + case 6:
  283 + tmp = (tmp & 0x00000000000000FFULL) | (T1 << 8);
  284 + break;
  285 + case 7:
  286 + tmp = T1;
  287 + break;
  288 + }
  289 +#if defined (DEBUG_OP)
  290 + if (logfile) {
  291 + fprintf(logfile, "%s: %08x - %08x %08x => %08x\n",
  292 + __func__, T0, sav, T1, tmp);
  293 + }
  294 +#endif
  295 + RETURN();
  296 + return tmp;
  297 +}
  298 +
  299 +#endif /* MIPS_HAS_MIPS64 */
target-mips/op_mem.c
@@ -75,6 +75,7 @@ void glue(op_sw, MEMSUFFIX) (void) @@ -75,6 +75,7 @@ void glue(op_sw, MEMSUFFIX) (void)
75 75
76 /* "half" load and stores. We must do the memory access inline, 76 /* "half" load and stores. We must do the memory access inline,
77 or fault handling won't work. */ 77 or fault handling won't work. */
  78 +/* XXX: This is broken, CP0_BADVADDR has the wrong (aligned) value. */
78 void glue(op_lwl, MEMSUFFIX) (void) 79 void glue(op_lwl, MEMSUFFIX) (void)
79 { 80 {
80 uint32_t tmp = glue(ldl, MEMSUFFIX)(T0 & ~3); 81 uint32_t tmp = glue(ldl, MEMSUFFIX)(T0 & ~3);
@@ -125,6 +126,72 @@ void glue(op_sc, MEMSUFFIX) (void) @@ -125,6 +126,72 @@ void glue(op_sc, MEMSUFFIX) (void)
125 RETURN(); 126 RETURN();
126 } 127 }
127 128
  129 +#ifdef MIPS_HAS_MIPS64
  130 +void glue(op_ld, MEMSUFFIX) (void)
  131 +{
  132 + T0 = glue(ldq, MEMSUFFIX)(T0);
  133 + RETURN();
  134 +}
  135 +
  136 +void glue(op_sd, MEMSUFFIX) (void)
  137 +{
  138 + glue(stq, MEMSUFFIX)(T0, T1);
  139 + RETURN();
  140 +}
  141 +
  142 +/* "half" load and stores. We must do the memory access inline,
  143 + or fault handling won't work. */
  144 +void glue(op_ldl, MEMSUFFIX) (void)
  145 +{
  146 + target_long tmp = glue(ldq, MEMSUFFIX)(T0 & ~7);
  147 + CALL_FROM_TB1(glue(do_ldl, MEMSUFFIX), tmp);
  148 + RETURN();
  149 +}
  150 +
  151 +void glue(op_ldr, MEMSUFFIX) (void)
  152 +{
  153 + target_long tmp = glue(ldq, MEMSUFFIX)(T0 & ~7);
  154 + CALL_FROM_TB1(glue(do_ldr, MEMSUFFIX), tmp);
  155 + RETURN();
  156 +}
  157 +
  158 +void glue(op_sdl, MEMSUFFIX) (void)
  159 +{
  160 + target_long tmp = glue(ldq, MEMSUFFIX)(T0 & ~7);
  161 + tmp = CALL_FROM_TB1(glue(do_sdl, MEMSUFFIX), tmp);
  162 + glue(stq, MEMSUFFIX)(T0 & ~7, tmp);
  163 + RETURN();
  164 +}
  165 +
  166 +void glue(op_sdr, MEMSUFFIX) (void)
  167 +{
  168 + target_long tmp = glue(ldq, MEMSUFFIX)(T0 & ~7);
  169 + tmp = CALL_FROM_TB1(glue(do_sdr, MEMSUFFIX), tmp);
  170 + glue(stq, MEMSUFFIX)(T0 & ~7, tmp);
  171 + RETURN();
  172 +}
  173 +
  174 +void glue(op_lld, MEMSUFFIX) (void)
  175 +{
  176 + T1 = T0;
  177 + T0 = glue(ldq, MEMSUFFIX)(T0);
  178 + env->CP0_LLAddr = T1;
  179 + RETURN();
  180 +}
  181 +
  182 +void glue(op_scd, MEMSUFFIX) (void)
  183 +{
  184 + CALL_FROM_TB0(dump_sc);
  185 + if (T0 == env->CP0_LLAddr) {
  186 + glue(stq, MEMSUFFIX)(T0, T1);
  187 + T0 = 1;
  188 + } else {
  189 + T0 = 0;
  190 + }
  191 + RETURN();
  192 +}
  193 +#endif /* MIPS_HAS_MIPS64 */
  194 +
128 #ifdef MIPS_USES_FPU 195 #ifdef MIPS_USES_FPU
129 void glue(op_lwc1, MEMSUFFIX) (void) 196 void glue(op_lwc1, MEMSUFFIX) (void)
130 { 197 {
target-mips/op_template.c
@@ -51,15 +51,21 @@ void glue(op_load_gpr_T2_gpr, REG) (void) @@ -51,15 +51,21 @@ void glue(op_load_gpr_T2_gpr, REG) (void)
51 #endif 51 #endif
52 52
53 #if defined (TN) 53 #if defined (TN)
54 -void glue(op_set_, TN) (void)  
55 -{  
56 - TN = PARAM1;  
57 - RETURN();  
58 -} 54 +#define SET_RESET(treg, tregname) \
  55 + void glue(op_set, tregname)(void) \
  56 + { \
  57 + treg = PARAM1; \
  58 + RETURN(); \
  59 + } \
  60 + void glue(op_reset, tregname)(void) \
  61 + { \
  62 + treg = 0; \
  63 + RETURN(); \
  64 + } \
59 65
60 -void glue (op_reset_, TN) (void)  
61 -{  
62 - TN = 0;  
63 - RETURN();  
64 -} 66 +SET_RESET(T0, _T0)
  67 +SET_RESET(T1, _T1)
  68 +SET_RESET(T2, _T2)
  69 +
  70 +#undef SET_RESET
65 #endif 71 #endif
target-mips/translate.c
@@ -31,6 +31,7 @@ @@ -31,6 +31,7 @@
31 #include "disas.h" 31 #include "disas.h"
32 32
33 //#define MIPS_DEBUG_DISAS 33 //#define MIPS_DEBUG_DISAS
  34 +//#define MIPS_DEBUG_SIGN_EXTENSIONS
34 //#define MIPS_SINGLE_STEP 35 //#define MIPS_SINGLE_STEP
35 36
36 #ifdef USE_DIRECT_JUMP 37 #ifdef USE_DIRECT_JUMP
@@ -502,7 +503,7 @@ enum { @@ -502,7 +503,7 @@ enum {
502 #define MIPS_DEBUG(fmt, args...) \ 503 #define MIPS_DEBUG(fmt, args...) \
503 do { \ 504 do { \
504 if (loglevel & CPU_LOG_TB_IN_ASM) { \ 505 if (loglevel & CPU_LOG_TB_IN_ASM) { \
505 - fprintf(logfile, "%08x: %08x " fmt "\n", \ 506 + fprintf(logfile, TLSZ ": %08x " fmt "\n", \
506 ctx->pc, ctx->opcode , ##args); \ 507 ctx->pc, ctx->opcode , ##args); \
507 } \ 508 } \
508 } while (0) 509 } while (0)
@@ -621,6 +622,8 @@ OP_LD_TABLE(dr); @@ -621,6 +622,8 @@ OP_LD_TABLE(dr);
621 OP_ST_TABLE(d); 622 OP_ST_TABLE(d);
622 OP_ST_TABLE(dl); 623 OP_ST_TABLE(dl);
623 OP_ST_TABLE(dr); 624 OP_ST_TABLE(dr);
  625 +OP_LD_TABLE(ld);
  626 +OP_ST_TABLE(cd);
624 #endif 627 #endif
625 OP_LD_TABLE(w); 628 OP_LD_TABLE(w);
626 OP_LD_TABLE(wu); 629 OP_LD_TABLE(wu);
@@ -1417,7 +1420,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, @@ -1417,7 +1420,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1417 case OPC_J: 1420 case OPC_J:
1418 case OPC_JAL: 1421 case OPC_JAL:
1419 /* Jump to immediate */ 1422 /* Jump to immediate */
1420 - btarget = ((ctx->pc + 4) & 0xF0000000) | offset; 1423 + btarget = ((ctx->pc + 4) & SIGN_EXTEND32(0xF0000000)) | offset;
1421 break; 1424 break;
1422 case OPC_JR: 1425 case OPC_JR:
1423 case OPC_JALR: 1426 case OPC_JALR:
@@ -2927,21 +2930,21 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op, @@ -2927,21 +2930,21 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
2927 switch (op) { 2930 switch (op) {
2928 case OPC_BC1F: 2931 case OPC_BC1F:
2929 gen_op_bc1f(); 2932 gen_op_bc1f();
2930 - MIPS_DEBUG("bc1f %08x", btarget); 2933 + MIPS_DEBUG("bc1f " TLSZ, btarget);
2931 goto not_likely; 2934 goto not_likely;
2932 case OPC_BC1FL: 2935 case OPC_BC1FL:
2933 gen_op_bc1f(); 2936 gen_op_bc1f();
2934 - MIPS_DEBUG("bc1fl %08x", btarget); 2937 + MIPS_DEBUG("bc1fl " TLSZ, btarget);
2935 goto likely; 2938 goto likely;
2936 case OPC_BC1T: 2939 case OPC_BC1T:
2937 gen_op_bc1t(); 2940 gen_op_bc1t();
2938 - MIPS_DEBUG("bc1t %08x", btarget); 2941 + MIPS_DEBUG("bc1t " TLSZ, btarget);
2939 not_likely: 2942 not_likely:
2940 ctx->hflags |= MIPS_HFLAG_BC; 2943 ctx->hflags |= MIPS_HFLAG_BC;
2941 break; 2944 break;
2942 case OPC_BC1TL: 2945 case OPC_BC1TL:
2943 gen_op_bc1t(); 2946 gen_op_bc1t();
2944 - MIPS_DEBUG("bc1tl %08x", btarget); 2947 + MIPS_DEBUG("bc1tl " TLSZ, btarget);
2945 likely: 2948 likely:
2946 ctx->hflags |= MIPS_HFLAG_BL; 2949 ctx->hflags |= MIPS_HFLAG_BL;
2947 break; 2950 break;
@@ -2952,7 +2955,7 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op, @@ -2952,7 +2955,7 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
2952 } 2955 }
2953 gen_op_set_bcond(); 2956 gen_op_set_bcond();
2954 2957
2955 - MIPS_DEBUG("enter ds: cond %02x target %08x", 2958 + MIPS_DEBUG("enter ds: cond %02x target " TLSZ,
2956 ctx->hflags, btarget); 2959 ctx->hflags, btarget);
2957 ctx->btarget = btarget; 2960 ctx->btarget = btarget;
2958 2961
@@ -3351,30 +3354,6 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) @@ -3351,30 +3354,6 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
3351 /* SmartMIPS extension to MIPS32 */ 3354 /* SmartMIPS extension to MIPS32 */
3352 3355
3353 #ifdef MIPS_HAS_MIPS64 3356 #ifdef MIPS_HAS_MIPS64
3354 -static void gen_arith64 (DisasContext *ctx, uint32_t opc)  
3355 -{  
3356 - if (func == 0x02 && rd == 0) {  
3357 - /* NOP */  
3358 - return;  
3359 - }  
3360 - if (rs == 0 || rt == 0) {  
3361 - gen_op_reset_T0();  
3362 - gen_op_save64();  
3363 - } else {  
3364 - gen_op_load_gpr_T0(rs);  
3365 - gen_op_load_gpr_T1(rt);  
3366 - gen_op_save64();  
3367 - if (func & 0x01)  
3368 - gen_op_mul64u();  
3369 - else  
3370 - gen_op_mul64s();  
3371 - }  
3372 - if (func & 0x02)  
3373 - gen_op_add64();  
3374 - else  
3375 - gen_op_sub64();  
3376 -}  
3377 -  
3378 /* Coprocessor 3 (FPU) */ 3357 /* Coprocessor 3 (FPU) */
3379 3358
3380 /* MDMX extension to MIPS64 */ 3359 /* MDMX extension to MIPS64 */
@@ -3407,7 +3386,7 @@ static void decode_opc (DisasContext *ctx) @@ -3407,7 +3386,7 @@ static void decode_opc (DisasContext *ctx)
3407 3386
3408 if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) { 3387 if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
3409 /* Handle blikely not taken case */ 3388 /* Handle blikely not taken case */
3410 - MIPS_DEBUG("blikely condition (%08x)", ctx->pc + 4); 3389 + MIPS_DEBUG("blikely condition (" TLSZ ")", ctx->pc + 4);
3411 gen_blikely(ctx); 3390 gen_blikely(ctx);
3412 } 3391 }
3413 op = MASK_OP_MAJOR(ctx->opcode); 3392 op = MASK_OP_MAJOR(ctx->opcode);
@@ -4011,7 +3990,7 @@ void fpu_dump_state(CPUState *env, FILE *f, @@ -4011,7 +3990,7 @@ void fpu_dump_state(CPUState *env, FILE *f,
4011 void dump_fpu (CPUState *env) 3990 void dump_fpu (CPUState *env)
4012 { 3991 {
4013 if (loglevel) { 3992 if (loglevel) {
4014 - fprintf(logfile, "pc=0x%08x HI=0x%08x LO=0x%08x ds %04x %08x %d\n", 3993 + fprintf(logfile, "pc=0x" TLSZ " HI=0x" TLSZ " LO=0x" TLSZ " ds %04x " TLSZ " %d\n",
4015 env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond); 3994 env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
4016 fpu_dump_state(env, logfile, fprintf, 0); 3995 fpu_dump_state(env, logfile, fprintf, 0);
4017 } 3996 }
@@ -4019,6 +3998,39 @@ void dump_fpu (CPUState *env) @@ -4019,6 +3998,39 @@ void dump_fpu (CPUState *env)
4019 3998
4020 #endif /* MIPS_USES_FPU */ 3999 #endif /* MIPS_USES_FPU */
4021 4000
  4001 +#if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
  4002 +/* Debug help: The architecture requires 32bit code to maintain proper
  4003 + sign-extened values on 64bit machines. */
  4004 +
  4005 +#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
  4006 +
  4007 +void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
  4008 + int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
  4009 + int flags)
  4010 +{
  4011 + int i;
  4012 +
  4013 + if (!SIGN_EXT_P(env->PC))
  4014 + cpu_fprintf(f, "BROKEN: pc=0x" TLSZ "\n", env->PC);
  4015 + if (!SIGN_EXT_P(env->HI))
  4016 + cpu_fprintf(f, "BROKEN: HI=0x" TLSZ "\n", env->HI);
  4017 + if (!SIGN_EXT_P(env->LO))
  4018 + cpu_fprintf(f, "BROKEN: LO=0x" TLSZ "\n", env->LO);
  4019 + if (!SIGN_EXT_P(env->btarget))
  4020 + cpu_fprintf(f, "BROKEN: btarget=0x" TLSZ "\n", env->btarget);
  4021 +
  4022 + for (i = 0; i < 32; i++) {
  4023 + if (!SIGN_EXT_P(env->gpr[i]))
  4024 + cpu_fprintf(f, "BROKEN: %s=0x" TLSZ "\n", regnames[i], env->gpr[i]);
  4025 + }
  4026 +
  4027 + if (!SIGN_EXT_P(env->CP0_EPC))
  4028 + cpu_fprintf(f, "BROKEN: EPC=0x" TLSZ "\n", env->CP0_EPC);
  4029 + if (!SIGN_EXT_P(env->CP0_LLAddr))
  4030 + cpu_fprintf(f, "BROKEN: LLAddr=0x" TLSZ "\n", env->CP0_LLAddr);
  4031 +}
  4032 +#endif
  4033 +
4022 void cpu_dump_state (CPUState *env, FILE *f, 4034 void cpu_dump_state (CPUState *env, FILE *f,
4023 int (*cpu_fprintf)(FILE *f, const char *fmt, ...), 4035 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
4024 int flags) 4036 int flags)
@@ -4026,12 +4038,12 @@ void cpu_dump_state (CPUState *env, FILE *f, @@ -4026,12 +4038,12 @@ void cpu_dump_state (CPUState *env, FILE *f,
4026 uint32_t c0_status; 4038 uint32_t c0_status;
4027 int i; 4039 int i;
4028 4040
4029 - cpu_fprintf(f, "pc=0x%08x HI=0x%08x LO=0x%08x ds %04x %08x %d\n", 4041 + cpu_fprintf(f, "pc=0x" TLSZ " HI=0x" TLSZ " LO=0x" TLSZ " ds %04x " TLSZ " %d\n",
4030 env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond); 4042 env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
4031 for (i = 0; i < 32; i++) { 4043 for (i = 0; i < 32; i++) {
4032 if ((i & 3) == 0) 4044 if ((i & 3) == 0)
4033 cpu_fprintf(f, "GPR%02d:", i); 4045 cpu_fprintf(f, "GPR%02d:", i);
4034 - cpu_fprintf(f, " %s %08x", regnames[i], env->gpr[i]); 4046 + cpu_fprintf(f, " %s " TLSZ, regnames[i], env->gpr[i]);
4035 if ((i & 3) == 3) 4047 if ((i & 3) == 3)
4036 cpu_fprintf(f, "\n"); 4048 cpu_fprintf(f, "\n");
4037 } 4049 }
@@ -4044,14 +4056,17 @@ void cpu_dump_state (CPUState *env, FILE *f, @@ -4044,14 +4056,17 @@ void cpu_dump_state (CPUState *env, FILE *f,
4044 if (env->hflags & MIPS_HFLAG_EXL) 4056 if (env->hflags & MIPS_HFLAG_EXL)
4045 c0_status |= (1 << CP0St_EXL); 4057 c0_status |= (1 << CP0St_EXL);
4046 4058
4047 - cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x%08x\n", 4059 + cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TLSZ "\n",
4048 c0_status, env->CP0_Cause, env->CP0_EPC); 4060 c0_status, env->CP0_Cause, env->CP0_EPC);
4049 - cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%08x\n", 4061 + cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TLSZ "\n",
4050 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr); 4062 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
4051 #ifdef MIPS_USES_FPU 4063 #ifdef MIPS_USES_FPU
4052 if (c0_status & (1 << CP0St_CU1)) 4064 if (c0_status & (1 << CP0St_CU1))
4053 fpu_dump_state(env, f, cpu_fprintf, flags); 4065 fpu_dump_state(env, f, cpu_fprintf, flags);
4054 #endif 4066 #endif
  4067 +#if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
  4068 + cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
  4069 +#endif
4055 } 4070 }
4056 4071
4057 CPUMIPSState *cpu_mips_init (void) 4072 CPUMIPSState *cpu_mips_init (void)
@@ -4082,14 +4097,14 @@ void cpu_reset (CPUMIPSState *env) @@ -4082,14 +4097,14 @@ void cpu_reset (CPUMIPSState *env)
4082 } else { 4097 } else {
4083 env->CP0_ErrorEPC = env->PC; 4098 env->CP0_ErrorEPC = env->PC;
4084 } 4099 }
4085 - env->PC = 0xBFC00000; 4100 + env->PC = SIGN_EXTEND32(0xBFC00000);
4086 #if defined (MIPS_USES_R4K_TLB) 4101 #if defined (MIPS_USES_R4K_TLB)
4087 env->CP0_random = MIPS_TLB_NB - 1; 4102 env->CP0_random = MIPS_TLB_NB - 1;
4088 env->tlb_in_use = MIPS_TLB_NB; 4103 env->tlb_in_use = MIPS_TLB_NB;
4089 #endif 4104 #endif
4090 env->CP0_Wired = 0; 4105 env->CP0_Wired = 0;
4091 /* SMP not implemented */ 4106 /* SMP not implemented */
4092 - env->CP0_EBase = 0x80000000; 4107 + env->CP0_EBase = SIGN_EXTEND32(0x80000000);
4093 env->CP0_Config0 = MIPS_CONFIG0; 4108 env->CP0_Config0 = MIPS_CONFIG0;
4094 env->CP0_Config1 = MIPS_CONFIG1; 4109 env->CP0_Config1 = MIPS_CONFIG1;
4095 env->CP0_Config2 = MIPS_CONFIG2; 4110 env->CP0_Config2 = MIPS_CONFIG2;