Revision c570fd16 target-mips/op_helper.c
b/target-mips/op_helper.c | ||
---|---|---|
74 | 74 |
#undef MEMSUFFIX |
75 | 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 | 161 |
/* 64 bits arithmetic for 32 bits hosts */ |
78 |
#if (HOST_LONG_BITS == 32)
|
|
162 |
#if TARGET_LONG_BITS > HOST_LONG_BITS
|
|
79 | 163 |
static inline uint64_t get_HILO (void) |
80 | 164 |
{ |
81 | 165 |
return ((uint64_t)env->HI << 32) | (uint64_t)env->LO; |
... | ... | |
83 | 167 |
|
84 | 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 | 174 |
void do_mult (void) |
... | ... | |
94 | 178 |
|
95 | 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 | 184 |
void do_madd (void) |
... | ... | |
109 | 193 |
{ |
110 | 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 | 197 |
set_HILO(get_HILO() + tmp); |
114 | 198 |
} |
115 | 199 |
|
... | ... | |
125 | 209 |
{ |
126 | 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 | 213 |
set_HILO(get_HILO() - tmp); |
130 | 214 |
} |
131 | 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 | 247 |
#if defined(CONFIG_USER_ONLY) |
134 | 248 |
void do_mfc0_random (void) |
135 | 249 |
{ |
... | ... | |
191 | 305 |
/* CP0 helpers */ |
192 | 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 | 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 | 316 |
void do_mtc0_status_debug(uint32_t old, uint32_t val) |
... | ... | |
319 | 433 |
|
320 | 434 |
/* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */ |
321 | 435 |
tlb = &env->tlb[idx]; |
322 |
tlb->VPN = env->CP0_EntryHi & 0xFFFFE000;
|
|
436 |
tlb->VPN = env->CP0_EntryHi & SIGN_EXTEND32(0xFFFFE000);
|
|
323 | 437 |
tlb->ASID = env->CP0_EntryHi & 0xFF; |
324 | 438 |
size = env->CP0_PageMask >> 13; |
325 | 439 |
size = 4 * (size + 1); |
... | ... | |
364 | 478 |
uint8_t ASID; |
365 | 479 |
int i; |
366 | 480 |
|
367 |
tag = env->CP0_EntryHi & 0xFFFFE000;
|
|
481 |
tag = env->CP0_EntryHi & SIGN_EXTEND32(0xFFFFE000);
|
|
368 | 482 |
ASID = env->CP0_EntryHi & 0xFF; |
369 | 483 |
for (i = 0; i < MIPS_TLB_NB; i++) { |
370 | 484 |
tlb = &env->tlb[i]; |
... | ... | |
418 | 532 |
|
419 | 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 | 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 | 541 |
void dump_sc (void) |
428 | 542 |
{ |
429 | 543 |
if (loglevel) { |
430 |
fprintf(logfile, "%s %08x at %08x (%08x)\n", __func__,
|
|
544 |
fprintf(logfile, "%s " TLSZ " at " TLSZ " (" TLSZ ")\n", __func__,
|
|
431 | 545 |
T1, T0, env->CP0_LLAddr); |
432 | 546 |
} |
433 | 547 |
} |
... | ... | |
435 | 549 |
void debug_eret (void) |
436 | 550 |
{ |
437 | 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 | 553 |
env->PC, env->CP0_EPC, env->CP0_ErrorEPC, |
440 | 554 |
env->hflags & MIPS_HFLAG_ERL ? 1 : 0); |
441 | 555 |
} |
... | ... | |
454 | 568 |
break; |
455 | 569 |
case 3: |
456 | 570 |
case 12: |
457 |
printf("%c", env->gpr[4] & 0xFF);
|
|
571 |
printf("%c", (char)(env->gpr[4] & 0xFF));
|
|
458 | 572 |
break; |
459 | 573 |
case 17: |
460 | 574 |
break; |
461 | 575 |
case 158: |
462 | 576 |
{ |
463 |
unsigned char *fmt = (void *)env->gpr[4]; |
|
577 |
unsigned char *fmt = (void *)(unsigned long)env->gpr[4];
|
|
464 | 578 |
printf("%s", fmt); |
465 | 579 |
} |
466 | 580 |
break; |
Also available in: Unified diff