1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4
5 mips3.c
6 Core implementation for the portable MIPS III/IV emulator.
7 Written by Aaron Giles
8
9 ***************************************************************************/
10
11 #include <cmath>
12 #include "emu.h"
13 #include "debugger.h"
14 #include "mips3.h"
15 #include "mips3com.h"
16 #include "mips3dsm.h"
17 #include "ps2vu.h"
18 #include <cmath>
19
20 #define ENABLE_OVERFLOWS (0)
21 #define ENABLE_EE_ELF_LOADER (0)
22 #define ENABLE_EE_DECI2 (0)
23
24 /***************************************************************************
25 HELPER MACROS
26 ***************************************************************************/
27
28 #define RSVAL32 ((uint32_t)m_core->r[RSREG])
29 #define RTVAL32 ((uint32_t)m_core->r[RTREG])
30 #define RDVAL32 ((uint32_t)m_core->r[RDREG])
31
32 #define RSVAL64 (m_core->r[RSREG])
33 #define RTVAL64 (m_core->r[RTREG])
34 #define RDVAL64 (m_core->r[RDREG])
35
36 #define FRVALS_FR0 (((float *)&m_core->cpr[1][FRREG & 0x1E])[BYTE_XOR_LE(FRREG & 1)])
37 #define FTVALS_FR0 (((float *)&m_core->cpr[1][FTREG & 0x1E])[BYTE_XOR_LE(FTREG & 1)])
38 #define FSVALS_FR0 (((float *)&m_core->cpr[1][FSREG & 0x1E])[BYTE_XOR_LE(FSREG & 1)])
39 #define FDVALS_FR0 (((float *)&m_core->cpr[1][FDREG & 0x1E])[BYTE_XOR_LE(FDREG & 1)])
40 #define FTVALW_FR0 (((uint32_t *)&m_core->cpr[1][FTREG & 0x1E])[BYTE_XOR_LE(FTREG & 1)])
41 #define FSVALW_FR0 (((uint32_t *)&m_core->cpr[1][FSREG & 0x1E])[BYTE_XOR_LE(FSREG & 1)])
42 #define FDVALW_FR0 (((uint32_t *)&m_core->cpr[1][FDREG & 0x1E])[BYTE_XOR_LE(FDREG & 1)])
43
44 #define FRVALD_FR0 (*(double *)&m_core->cpr[1][FRREG & 0x1E])
45 #define FTVALD_FR0 (*(double *)&m_core->cpr[1][FTREG & 0x1E])
46 #define FSVALD_FR0 (*(double *)&m_core->cpr[1][FSREG & 0x1E])
47 #define FDVALD_FR0 (*(double *)&m_core->cpr[1][FDREG & 0x1E])
48 #define FTVALL_FR0 (*(uint64_t *)&m_core->cpr[1][FTREG & 0x1E])
49 #define FSVALL_FR0 (*(uint64_t *)&m_core->cpr[1][FSREG & 0x1E])
50 #define FDVALL_FR0 (*(uint64_t *)&m_core->cpr[1][FDREG & 0x1E])
51
52 #define FRVALS_FR1 (((float *)&m_core->cpr[1][FRREG])[BYTE_XOR_LE(0)])
53 #define FTVALS_FR1 (((float *)&m_core->cpr[1][FTREG])[BYTE_XOR_LE(0)])
54 #define FSVALS_FR1 (((float *)&m_core->cpr[1][FSREG])[BYTE_XOR_LE(0)])
55 #define FDVALS_FR1 (((float *)&m_core->cpr[1][FDREG])[BYTE_XOR_LE(0)])
56 #define FSVALW_FR1 (((uint32_t *)&m_core->cpr[1][FSREG])[BYTE_XOR_LE(0)])
57 #define FDVALW_FR1 (((uint32_t *)&m_core->cpr[1][FDREG])[BYTE_XOR_LE(0)])
58
59 #define FRVALD_FR1 (*(double *)&m_core->cpr[1][FRREG])
60 #define FTVALD_FR1 (*(double *)&m_core->cpr[1][FTREG])
61 #define FSVALD_FR1 (*(double *)&m_core->cpr[1][FSREG])
62 #define FDVALD_FR1 (*(double *)&m_core->cpr[1][FDREG])
63 #define FSVALL_FR1 (*(uint64_t *)&m_core->cpr[1][FSREG])
64 #define FDVALL_FR1 (*(uint64_t *)&m_core->cpr[1][FDREG])
65
66 #define ADDPC(x) m_nextpc = m_core->pc + ((x) << 2)
67 #define ABSPC(x) m_nextpc = (m_core->pc & 0xf0000000) | ((x) << 2)
68 #define ABSPCL(x,l) { m_nextpc = (m_core->pc & 0xf0000000) | ((x) << 2); m_core->r[l] = (int32_t)(m_core->pc + 4); }
69 #define SETPC(x) m_nextpc = (x)
70 #define SETPCL(x,l) { m_nextpc = (x); m_core->r[l] = (int32_t)(m_core->pc + 4); }
71
72 #define HIVAL (uint32_t)m_core->r[REG_HI]
73 #define LOVAL (uint32_t)m_core->r[REG_LO]
74 #define HIVAL64 m_core->r[REG_HI]
75 #define LOVAL64 m_core->r[REG_LO]
76 #define SR m_core->cpr[0][COP0_Status]
77 #define CAUSE m_core->cpr[0][COP0_Cause]
78
79 #define GET_FCC(n) (m_cf[1][n])
80 #define SET_FCC(n,v) (m_cf[1][n] = (v))
81
82 #define IS_FR0 (!(SR & SR_FR))
83 #define IS_FR1 (SR & SR_FR)
84
85 /* size of the execution code cache */
86 #define DRC_CACHE_SIZE (32 * 1024 * 1024)
87
88
89
90 static const uint8_t fcc_shift[8] = { 23, 25, 26, 27, 28, 29, 30, 31 };
91
92 /* lookup table for FP modes */
93 static const uint8_t fpmode_source[4] =
94 {
95 uml::ROUND_ROUND,
96 uml::ROUND_TRUNC,
97 uml::ROUND_CEIL,
98 uml::ROUND_FLOOR
99 };
100
101 /***************************************************************************
102 MEMORY ACCESSORS
103 ***************************************************************************/
104
105 #define ROPCODE(pc) m_lr32(pc)
106
107
108 DEFINE_DEVICE_TYPE(R4000BE, r4000be_device, "r4000be", "MIPS R4000 (big)")
109 DEFINE_DEVICE_TYPE(R4000LE, r4000le_device, "r4000le", "MIPS R4000 (little)")
110 DEFINE_DEVICE_TYPE(R4400BE, r4400be_device, "r4400be", "MIPS R4400 (big)")
111 DEFINE_DEVICE_TYPE(R4400LE, r4400le_device, "r4400le", "MIPS R4400 (little)")
112 DEFINE_DEVICE_TYPE(VR4300BE, vr4300be_device, "vr4300be", "NEC VR4300 (big)")
113 DEFINE_DEVICE_TYPE(VR4300LE, vr4300le_device, "vr4300le", "NEC VR4300 (little)")
114 DEFINE_DEVICE_TYPE(VR4310BE, vr4310be_device, "vr4310be", "NEC VR4310 (big)")
115 DEFINE_DEVICE_TYPE(VR4310LE, vr4310le_device, "vr4310le", "NEC VR4310 (little)")
116 DEFINE_DEVICE_TYPE(R4600BE, r4600be_device, "r4600be", "MIPS R4600 (big)")
117 DEFINE_DEVICE_TYPE(R4600LE, r4600le_device, "r4600le", "MIPS R4600 (little)")
118 DEFINE_DEVICE_TYPE(R4650BE, r4650be_device, "r4650be", "MIPS IDT R4650 (big)")
119 DEFINE_DEVICE_TYPE(R4650LE, r4650le_device, "r4650le", "MIPS IDT R4650 (little)")
120 DEFINE_DEVICE_TYPE(R4700BE, r4700be_device, "r4700be", "MIPS R4700 (big)")
121 DEFINE_DEVICE_TYPE(R4700LE, r4700le_device, "r4700le", "MIPS R4700 (little)")
122 DEFINE_DEVICE_TYPE(TX4925BE, tx4925be_device, "tx4925be", "Toshiba TX4925 (big)")
123 DEFINE_DEVICE_TYPE(TX4925LE, tx4925le_device, "tx4925le", "Toshiba TX4925 (little)")
124 DEFINE_DEVICE_TYPE(R5000BE, r5000be_device, "r5000be", "MIPS R5000 (big)")
125 DEFINE_DEVICE_TYPE(R5000LE, r5000le_device, "r5000le", "MIPS R5000 (little)")
126 DEFINE_DEVICE_TYPE(VR5500BE, vr5500be_device, "vr5500be", "NEC VR5500 (big)")
127 DEFINE_DEVICE_TYPE(VR5500LE, vr5500le_device, "vr5500le", "NEC VR5500 (little)")
128 DEFINE_DEVICE_TYPE(R5900LE, r5900le_device, "r5900le", "Emotion Engine Core")
129 DEFINE_DEVICE_TYPE(QED5271BE, qed5271be_device, "qed5271be", "MIPS QED5271 (big)")
130 DEFINE_DEVICE_TYPE(QED5271LE, qed5271le_device, "qed5271le", "MIPS QED5271 (little)")
131 DEFINE_DEVICE_TYPE(RM7000BE, rm7000be_device, "rm7000be", "MIPS RM7000 (big)")
132 DEFINE_DEVICE_TYPE(RM7000LE, rm7000le_device, "rm7000le", "MIPS RM7000 (little)")
133
134
135 // VR4300 and VR5432 have 4 fewer PFN bits, and only 32 TLB entries
mips3_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,uint32_t clock,mips3_flavor flavor,endianness_t endianness,uint32_t data_bits)136 mips3_device::mips3_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, mips3_flavor flavor, endianness_t endianness, uint32_t data_bits)
137 : cpu_device(mconfig, type, tag, owner, clock)
138 , device_vtlb_interface(mconfig, *this, AS_PROGRAM)
139 , m_core(nullptr)
140 , m_dcache(nullptr)
141 , m_icache(nullptr)
142 , m_program_config("program", endianness, data_bits, 32, 0, 32, MIPS3_MIN_PAGE_SHIFT)
143 , m_flavor(flavor)
144 , m_ppc(0)
145 , m_nextpc(0)
146 , m_pcbase(0)
147 , m_delayslot(false)
148 , m_op(0)
149 , m_interrupt_cycles(0)
150 , m_badcop_value(0)
151 , m_lwl(endianness == ENDIANNESS_BIG ? &mips3_device::lwl_be : &mips3_device::lwl_le)
152 , m_lwr(endianness == ENDIANNESS_BIG ? &mips3_device::lwr_be : &mips3_device::lwr_le)
153 , m_swl(endianness == ENDIANNESS_BIG ? &mips3_device::swl_be : &mips3_device::swl_le)
154 , m_swr(endianness == ENDIANNESS_BIG ? &mips3_device::swr_be : &mips3_device::swr_le)
155 , m_ldl(endianness == ENDIANNESS_BIG ? &mips3_device::ldl_be : &mips3_device::ldl_le)
156 , m_ldr(endianness == ENDIANNESS_BIG ? &mips3_device::ldr_be : &mips3_device::ldr_le)
157 , m_sdl(endianness == ENDIANNESS_BIG ? &mips3_device::sdl_be : &mips3_device::sdl_le)
158 , m_sdr(endianness == ENDIANNESS_BIG ? &mips3_device::sdr_be : &mips3_device::sdr_le)
159 , m_data_bits(data_bits)
160 , c_system_clock(0)
161 , m_pfnmask(flavor == MIPS3_TYPE_VR4300 ? 0x000fffff : 0x00ffffff)
162 , m_tlbentries(flavor == MIPS3_TYPE_VR4300 ? 32 : MIPS3_MAX_TLB_ENTRIES)
163 , m_bigendian(endianness == ENDIANNESS_BIG)
164 , m_byte_xor(data_bits == 64 ? (m_bigendian ? BYTE8_XOR_BE(0) : BYTE8_XOR_LE(0)) : (m_bigendian ? BYTE4_XOR_BE(0) : BYTE4_XOR_LE(0)))
165 , m_word_xor(data_bits == 64 ? (m_bigendian ? WORD2_XOR_BE(0) : WORD2_XOR_LE(0)) : (m_bigendian ? WORD_XOR_BE(0) : WORD_XOR_LE(0)))
166 , m_dword_xor(data_bits == 64 ? (m_bigendian ? DWORD_XOR_BE(0) : DWORD_XOR_LE(0)) : 0)
167 , c_icache_size(0)
168 , c_dcache_size(0)
169 , c_secondary_cache_line_size(0)
170 , m_fastram_select(0)
171 , m_debugger_temp(0)
172 , m_drc_cache(DRC_CACHE_SIZE + sizeof(internal_mips3_state) + 0x800000)
173 , m_drcuml(nullptr)
174 , m_drcfe(nullptr)
175 , m_drcoptions(0)
176 , m_drc_cache_dirty(0)
177 , m_entry(nullptr)
178 , m_nocode(nullptr)
179 , m_out_of_cycles(nullptr)
180 , m_tlb_mismatch(nullptr)
181 , m_hotspot_select(0)
182 {
183 memset(m_fpmode, 0, sizeof(m_fpmode));
184
185 for (int i = 0; i < 3; i++)
186 {
187 m_read8[i] = nullptr;
188 m_write8[i] = nullptr;
189 m_read16[i] = nullptr;
190 m_write16[i] = nullptr;
191 m_read32[i] = nullptr;
192 m_read32mask[i] = nullptr;
193 m_write32[i] = nullptr;
194 m_write32mask[i] = nullptr;
195 m_read64[i] = nullptr;
196 m_read64mask[i] = nullptr;
197 m_write64[i] = nullptr;
198 m_write64mask[i] = nullptr;
199 }
200
201 for (int i = 0; i < 18; i++)
202 {
203 m_exception[i] = nullptr;
204 m_exception_norecover[i] = nullptr;
205 }
206 memset(m_fastram, 0, sizeof(m_fastram));
207 memset(m_hotspot, 0, sizeof(m_hotspot));
208
209 // configure the virtual TLB
210 if (m_flavor == MIPS3_TYPE_TX4925)
211 set_vtlb_fixed_entries(2 * m_tlbentries + 3);
212 else
213 set_vtlb_fixed_entries(2 * m_tlbentries + 2);
214 }
215
memory_space_config() const216 device_memory_interface::space_config_vector mips3_device::memory_space_config() const
217 {
218 return space_config_vector {
219 std::make_pair(AS_PROGRAM, &m_program_config)
220 };
221 }
222
223
device_stop()224 void mips3_device::device_stop()
225 {
226 if (m_drcfe != nullptr)
227 {
228 m_drcfe = nullptr;
229 }
230 if (m_drcuml != nullptr)
231 {
232 m_drcuml = nullptr;
233 }
234 }
235
236 /***************************************************************************
237 EXECEPTION HANDLING
238 ***************************************************************************/
239
generate_exception(int exception,int backup)240 void mips3_device::generate_exception(int exception, int backup)
241 {
242 uint32_t offset = 0x180;
243 /*
244 useful for catching exceptions:
245
246 if (exception != 0)
247 {
248 fprintf(stderr, "Exception: PC=%08X, PPC=%08X\n", m_core->pc, m_ppc);
249 machine().debug_break();
250 }
251 */
252
253 /* back up if necessary */
254 if (backup)
255 m_core->pc = m_ppc;
256
257 #if ENABLE_EE_DECI2
258 if (exception == EXCEPTION_SYSCALL && m_flavor == MIPS3_TYPE_R5900)
259 {
260 uint32_t call = 0;
261 bool success = RBYTE(m_core->pc - 4, &call);
262 //logerror("Syscall: %08x\n", call);
263 if (call == 0x7c)
264 {
265 const uint32_t func = m_core->r[4];
266 const uint32_t param = m_core->r[5];
267 logerror("Deci2 syscall, func=%08x, param=%08x\n", func, param);
268 if (func == 0x10 && success)
269 {
270 uint32_t str_addr = 0;
271 success = RWORD(param, &str_addr);
272
273 logerror("Deci2 str_addr: %08x\n", str_addr);
274
275 uint32_t curr_char = 0;
276 success = RBYTE(str_addr & 0x01ffffff, &curr_char);
277
278 char buf[0x10000] = { 0 };
279 uint32_t index = 0;
280 while (success && curr_char != 0 && index < 0xffff)
281 {
282 buf[index] = (char)curr_char;
283 success = RBYTE(str_addr & 0x01ffffff, &curr_char);
284 str_addr++;
285 }
286 buf[index] = 0;
287 logerror("Deci2 log: %s\n", buf);
288 }
289 }
290 }
291 #endif
292
293 /* translate our fake fill exceptions into real exceptions */
294 if (exception == EXCEPTION_TLBLOAD_FILL || exception == EXCEPTION_TLBSTORE_FILL)
295 {
296 /* don't use the tlb exception offset if within another exception */
297 if (!(SR & SR_EXL))
298 offset = 0;
299 exception = (exception - EXCEPTION_TLBLOAD_FILL) + EXCEPTION_TLBLOAD;
300 }
301 else if (exception == EXCEPTION_INTERRUPT && m_flavor == MIPS3_TYPE_R5900)
302 {
303 offset = 0x200;
304 }
305
306 /* put the cause in the low 8 bits and clear the branch delay flag */
307 CAUSE = (CAUSE & ~0x800000ff) | (exception << 2);
308
309 /* set the appropriate bits for coprocessor exceptions */
310 if(exception == EXCEPTION_BADCOP)
311 {
312 CAUSE |= m_badcop_value << 28;
313 }
314
315 /* check if exception within another exception */
316 if (!(SR & SR_EXL))
317 {
318 /* if we were in a branch delay slot and we are backing up, adjust */
319 if (((m_nextpc != ~0) || (m_delayslot)) && backup)
320 {
321 m_delayslot = false;
322 m_nextpc = ~0;
323 m_core->cpr[0][COP0_EPC] = m_core->pc - 4;
324 CAUSE |= 0x80000000;
325 }
326 else
327 m_core->cpr[0][COP0_EPC] = m_core->pc;
328
329 /* set the exception level */
330 SR |= SR_EXL;
331 }
332
333 /* based on the BEV bit, we either go to ROM or RAM */
334 m_core->pc = ((SR & SR_BEV) ? 0xbfc00200 : 0x80000000) + offset;
335
336 /*
337 useful for tracking interrupts
338
339 if ((CAUSE & 0x7f) == 0)
340 logerror("Took interrupt -- Cause = %08X, PC = %08X\n", (uint32_t)CAUSE, m_core->pc);
341 */
342 debugger_exception_hook(exception);
343 }
344
345
generate_tlb_exception(int exception,offs_t address)346 void mips3_device::generate_tlb_exception(int exception, offs_t address)
347 {
348 m_core->cpr[0][COP0_BadVAddr] = address;
349 if(exception == EXCEPTION_TLBLOAD || exception == EXCEPTION_TLBSTORE || exception == EXCEPTION_TLBLOAD_FILL || exception == EXCEPTION_TLBSTORE_FILL)
350 {
351 m_core->cpr[0][COP0_Context] = (m_core->cpr[0][COP0_Context] & 0xff800000) | ((address >> 9) & 0x007ffff0);
352 m_core->cpr[0][COP0_EntryHi] = (address & 0xffffe000) | (m_core->cpr[0][COP0_EntryHi] & 0xff);
353 }
354 generate_exception(exception, 1);
355 }
356
357
invalid_instruction(uint32_t op)358 void mips3_device::invalid_instruction(uint32_t op)
359 {
360 fatalerror("Invalid instruction! %08x\n", op);
361 generate_exception(EXCEPTION_INVALIDOP, 1);
362 }
363
364
365
366 /***************************************************************************
367 IRQ HANDLING
368 ***************************************************************************/
369
check_irqs()370 void mips3_device::check_irqs()
371 {
372 if ((CAUSE & SR & 0xfc00) && (SR & SR_IE) && !(SR & (SR_EXL | SR_ERL)))
373 generate_exception(EXCEPTION_INTERRUPT, 0);
374 }
375
check_irqs()376 void r5900le_device::check_irqs()
377 {
378 if ((CAUSE & SR & 0xfc00) && (SR & SR_IE) && (SR & SR_EIE) && !(SR & (SR_EXL | SR_ERL)))
379 generate_exception(EXCEPTION_INTERRUPT, 0);
380 }
381
382
383 /***************************************************************************
384 CORE CALLBACKS
385 ***************************************************************************/
386
device_start()387 void mips3_device::device_start()
388 {
389 m_isdrc = allow_drc();
390
391 /* allocate the implementation-specific state from the full cache */
392 m_core = (internal_mips3_state *)m_drc_cache.alloc_near(sizeof(internal_mips3_state));
393 m_icache = (uint8_t *)m_drc_cache.alloc_near(c_dcache_size);
394 m_dcache = (uint8_t *)m_drc_cache.alloc_near(c_icache_size);
395
396 /* initialize based on the config */
397 memset(m_core, 0, sizeof(internal_mips3_state));
398
399 m_cpu_clock = clock();
400 m_program = &space(AS_PROGRAM);
401 if(m_program->endianness() == ENDIANNESS_LITTLE)
402 {
403 if (m_data_bits == 32)
404 {
405 m_program->cache(m_cache32le);
406 m_pr32 = [this](offs_t address) -> u32 { return m_cache32le.read_dword(address); };
407 m_prptr = [this](offs_t address) -> const void * { return m_cache32le.read_ptr(address); };
408 }
409 else
410 {
411 m_program->cache(m_cache64le);
412 m_pr32 = [this](offs_t address) -> u32 { return m_cache64le.read_dword(address); };
413 m_prptr = [this](offs_t address) -> const void * { return m_cache64le.read_ptr(address); };
414 }
415 }
416 else
417 {
418 if (m_data_bits == 32)
419 {
420 m_program->cache(m_cache32be);
421 m_pr32 = [this](offs_t address) -> u32 { return m_cache32be.read_dword(address); };
422 m_prptr = [this](offs_t address) -> const void * { return m_cache32be.read_ptr(address); };
423 }
424 else
425 {
426 m_program->cache(m_cache64be);
427 m_pr32 = [this](offs_t address) -> u32 { return m_cache64be.read_dword(address); };
428 m_prptr = [this](offs_t address) -> const void * { return m_cache64be.read_ptr(address); };
429 }
430 }
431
432 /* set up the endianness */
433 m_program->accessors(m_memory);
434
435 /* allocate a timer for the compare interrupt */
436 m_compare_int_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mips3_device::compare_int_callback), this));
437
438 uint32_t flags = 0;
439 /* initialize the UML generator */
440 m_drcuml = std::make_unique<drcuml_state>(*this, m_drc_cache, flags, 8, 32, 2);
441
442 /* add symbols for our stuff */
443 m_drcuml->symbol_add(&m_core->pc, sizeof(m_core->pc), "pc");
444 m_drcuml->symbol_add(&m_core->icount, sizeof(m_core->icount), "icount");
445 for (int regnum = 0; regnum < 32; regnum++)
446 {
447 char buf[10];
448 sprintf(buf, "r%d", regnum);
449 m_drcuml->symbol_add(&m_core->r[regnum], sizeof(m_core->r[regnum]), buf);
450 sprintf(buf, "f%d", regnum);
451 m_drcuml->symbol_add(&m_core->cpr[1][regnum], sizeof(m_core->cpr[1][regnum]), buf);
452 }
453 m_drcuml->symbol_add(&m_core->r[REG_LO], sizeof(m_core->r[REG_LO]), "lo");
454 m_drcuml->symbol_add(&m_core->r[REG_HI], sizeof(m_core->r[REG_LO]), "hi");
455 m_drcuml->symbol_add(&m_core->cpr[0][COP0_Index], sizeof(m_core->cpr[0][COP0_Index]), "Index");
456 m_drcuml->symbol_add(&m_core->cpr[0][COP0_Random], sizeof(m_core->cpr[0][COP0_Random]), "Random");
457 m_drcuml->symbol_add(&m_core->cpr[0][COP0_EntryLo0], sizeof(m_core->cpr[0][COP0_EntryLo0]), "EntryLo0");
458 m_drcuml->symbol_add(&m_core->cpr[0][COP0_EntryLo1], sizeof(m_core->cpr[0][COP0_EntryLo1]), "EntryLo1");
459 m_drcuml->symbol_add(&m_core->cpr[0][COP0_Context], sizeof(m_core->cpr[0][COP0_Context]), "Context");
460 m_drcuml->symbol_add(&m_core->cpr[0][COP0_PageMask], sizeof(m_core->cpr[0][COP0_PageMask]), "PageMask");
461 m_drcuml->symbol_add(&m_core->cpr[0][COP0_Wired], sizeof(m_core->cpr[0][COP0_Wired]), "Wired");
462 m_drcuml->symbol_add(&m_core->cpr[0][COP0_BadVAddr], sizeof(m_core->cpr[0][COP0_BadVAddr]), "BadVAddr");
463 m_drcuml->symbol_add(&m_core->cpr[0][COP0_Count], sizeof(m_core->cpr[0][COP0_Count]), "Count");
464 m_drcuml->symbol_add(&m_core->cpr[0][COP0_EntryHi], sizeof(m_core->cpr[0][COP0_EntryHi]), "EntryHi");
465 m_drcuml->symbol_add(&m_core->cpr[0][COP0_Compare], sizeof(m_core->cpr[0][COP0_Compare]), "Compare");
466 m_drcuml->symbol_add(&m_core->cpr[0][COP0_Status], sizeof(m_core->cpr[0][COP0_Status]), "Status");
467 m_drcuml->symbol_add(&m_core->cpr[0][COP0_Cause], sizeof(m_core->cpr[0][COP0_Cause]), "Cause");
468 m_drcuml->symbol_add(&m_core->cpr[0][COP0_EPC], sizeof(m_core->cpr[0][COP0_EPC]), "EPC");
469 m_drcuml->symbol_add(&m_core->cpr[0][COP0_PRId], sizeof(m_core->cpr[0][COP0_PRId]), "PRId");
470 m_drcuml->symbol_add(&m_core->cpr[0][COP0_Config], sizeof(m_core->cpr[0][COP0_Config]), "Config");
471 m_drcuml->symbol_add(&m_core->cpr[0][COP0_LLAddr], sizeof(m_core->cpr[0][COP0_LLAddr]), "LLAddr");
472 m_drcuml->symbol_add(&m_core->cpr[0][COP0_XContext], sizeof(m_core->cpr[0][COP0_XContext]), "XContext");
473 m_drcuml->symbol_add(&m_core->cpr[0][COP0_ECC], sizeof(m_core->cpr[0][COP0_ECC]), "ECC");
474 m_drcuml->symbol_add(&m_core->cpr[0][COP0_CacheErr], sizeof(m_core->cpr[0][COP0_CacheErr]), "CacheErr");
475 m_drcuml->symbol_add(&m_core->cpr[0][COP0_TagLo], sizeof(m_core->cpr[0][COP0_TagLo]), "TagLo");
476 m_drcuml->symbol_add(&m_core->cpr[0][COP0_TagHi], sizeof(m_core->cpr[0][COP0_TagHi]), "TagHi");
477 m_drcuml->symbol_add(&m_core->cpr[0][COP0_ErrorPC], sizeof(m_core->cpr[0][COP0_ErrorPC]), "ErrorPC");
478 m_drcuml->symbol_add(&m_core->ccr[1][31], sizeof(m_core->cpr[1][31]), "fcr31");
479 m_drcuml->symbol_add(&m_core->mode, sizeof(m_core->mode), "mode");
480 m_drcuml->symbol_add(&m_core->arg0, sizeof(m_core->arg0), "arg0");
481 m_drcuml->symbol_add(&m_core->arg1, sizeof(m_core->arg1), "arg1");
482 m_drcuml->symbol_add(&m_core->numcycles, sizeof(m_core->numcycles), "numcycles");
483 m_drcuml->symbol_add(&m_fpmode, sizeof(m_fpmode), "fpmode");
484
485 /* initialize the front-end helper */
486 m_drcfe = std::make_unique<mips3_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
487
488 /* allocate memory for cache-local state and initialize it */
489 memcpy(m_fpmode, fpmode_source, sizeof(fpmode_source));
490
491 /* compute the register parameters */
492 for (int regnum = 0; regnum < 34; regnum++)
493 {
494 m_regmap[regnum] = (regnum == 0) ? uml::parameter(0) : uml::parameter::make_memory(&m_core->r[regnum]);
495 m_regmaplo[regnum] = (regnum == 0) ? uml::parameter(0) : uml::parameter::make_memory(LOPTR(&m_core->r[regnum]));
496 }
497
498 /* if we have registers to spare, assign r2, r3, r4 to leftovers */
499 if (!DISABLE_FAST_REGISTERS)
500 {
501 drcbe_info beinfo;
502
503 m_drcuml->get_backend_info(beinfo);
504 if (beinfo.direct_iregs > 4)
505 {
506 m_regmap[2] = uml::I4;
507 m_regmaplo[2] = uml::I4;
508 }
509 if (beinfo.direct_iregs > 5)
510 {
511 m_regmap[3] = uml::I5;
512 m_regmaplo[3] = uml::I5;
513 }
514 if (beinfo.direct_iregs > 6)
515 {
516 m_regmap[4] = uml::I6;
517 m_regmaplo[4] = uml::I6;
518 }
519 }
520
521 /* mark the cache dirty so it is updated on next execute */
522 m_drc_cache_dirty = true;
523
524
525 /* register for save states */
526 save_item(NAME(m_core->pc));
527 save_item(NAME(m_core->r));
528 save_item(NAME(m_core->cpr));
529 save_item(NAME(m_core->ccr));
530 save_item(NAME(m_core->llbit));
531 save_item(NAME(m_core->count_zero_time));
532 for (int tlbindex = 0; tlbindex < m_tlbentries; tlbindex++)
533 {
534 save_item(NAME(m_tlb[tlbindex].page_mask), tlbindex);
535 save_item(NAME(m_tlb[tlbindex].entry_hi), tlbindex);
536 save_item(NAME(m_tlb[tlbindex].entry_lo), tlbindex);
537 }
538 save_item(NAME(m_tlb_seed));
539
540 // Register state with debugger
541 state_add( MIPS3_PC, "PC", m_core->pc).formatstr("%08X");
542 state_add( MIPS3_SR, "SR", m_core->cpr[0][COP0_Status]).formatstr("%08X");
543 state_add( MIPS3_EPC, "EPC", m_core->cpr[0][COP0_EPC]).formatstr("%08X");
544 state_add( MIPS3_CAUSE, "Cause", m_core->cpr[0][COP0_Cause]).formatstr("%08X");
545 state_add( MIPS3_BADVADDR, "BadVAddr", m_core->cpr[0][COP0_BadVAddr]).formatstr("%08X");
546
547 #if USE_ABI_REG_NAMES
548 state_add( MIPS3_R0, "zero", m_core->r[0]).callimport().formatstr("%016X"); // Can't change R0
549 state_add( MIPS3_R1, "at", m_core->r[1]).formatstr("%016X").callimport();
550 state_add( MIPS3_R2, "v0", m_core->r[2]).formatstr("%016X").callimport();
551 state_add( MIPS3_R3, "v1", m_core->r[3]).formatstr("%016X").callimport();
552 state_add( MIPS3_R4, "a0", m_core->r[4]).formatstr("%016X").callimport();
553 state_add( MIPS3_R5, "a1", m_core->r[5]).formatstr("%016X").callimport();
554 state_add( MIPS3_R6, "a2", m_core->r[6]).formatstr("%016X").callimport();
555 state_add( MIPS3_R7, "a3", m_core->r[7]).formatstr("%016X").callimport();
556 state_add( MIPS3_R8, "t0", m_core->r[8]).formatstr("%016X").callimport();
557 state_add( MIPS3_R9, "t1", m_core->r[9]).formatstr("%016X").callimport();
558 state_add( MIPS3_R10, "t2", m_core->r[10]).formatstr("%016X").callimport();
559 state_add( MIPS3_R11, "t3", m_core->r[11]).formatstr("%016X").callimport();
560 state_add( MIPS3_R12, "t4", m_core->r[12]).formatstr("%016X").callimport();
561 state_add( MIPS3_R13, "t5", m_core->r[13]).formatstr("%016X").callimport();
562 state_add( MIPS3_R14, "t6", m_core->r[14]).formatstr("%016X").callimport();
563 state_add( MIPS3_R15, "t7", m_core->r[15]).formatstr("%016X").callimport();
564 state_add( MIPS3_R16, "s0", m_core->r[16]).formatstr("%016X").callimport();
565 state_add( MIPS3_R17, "s1", m_core->r[17]).formatstr("%016X").callimport();
566 state_add( MIPS3_R18, "s2", m_core->r[18]).formatstr("%016X").callimport();
567 state_add( MIPS3_R19, "s3", m_core->r[19]).formatstr("%016X").callimport();
568 state_add( MIPS3_R20, "s4", m_core->r[20]).formatstr("%016X").callimport();
569 state_add( MIPS3_R21, "s5", m_core->r[21]).formatstr("%016X").callimport();
570 state_add( MIPS3_R22, "s6", m_core->r[22]).formatstr("%016X").callimport();
571 state_add( MIPS3_R23, "s7", m_core->r[23]).formatstr("%016X").callimport();
572 state_add( MIPS3_R24, "t8", m_core->r[24]).formatstr("%016X").callimport();
573 state_add( MIPS3_R25, "t9", m_core->r[25]).formatstr("%016X").callimport();
574 state_add( MIPS3_R26, "k0", m_core->r[26]).formatstr("%016X").callimport();
575 state_add( MIPS3_R27, "k1", m_core->r[27]).formatstr("%016X").callimport();
576 state_add( MIPS3_R28, "gp", m_core->r[28]).formatstr("%016X").callimport();
577 state_add( MIPS3_R29, "sp", m_core->r[29]).formatstr("%016X").callimport();
578 state_add( MIPS3_R30, "fp", m_core->r[30]).formatstr("%016X").callimport();
579 state_add( MIPS3_R31, "ra", m_core->r[31]).formatstr("%016X").callimport();
580 #else
581 state_add( MIPS3_R0, "R0", m_core->r[0]).callimport().formatstr("%016X"); // Can't change R0
582 state_add( MIPS3_R1, "R1", m_core->r[1]).formatstr("%016X").callimport();
583 state_add( MIPS3_R2, "R2", m_core->r[2]).formatstr("%016X").callimport();
584 state_add( MIPS3_R3, "R3", m_core->r[3]).formatstr("%016X").callimport();
585 state_add( MIPS3_R4, "R4", m_core->r[4]).formatstr("%016X").callimport();
586 state_add( MIPS3_R5, "R5", m_core->r[5]).formatstr("%016X").callimport();
587 state_add( MIPS3_R6, "R6", m_core->r[6]).formatstr("%016X").callimport();
588 state_add( MIPS3_R7, "R7", m_core->r[7]).formatstr("%016X").callimport();
589 state_add( MIPS3_R8, "R8", m_core->r[8]).formatstr("%016X").callimport();
590 state_add( MIPS3_R9, "R9", m_core->r[9]).formatstr("%016X").callimport();
591 state_add( MIPS3_R10, "R10", m_core->r[10]).formatstr("%016X").callimport();
592 state_add( MIPS3_R11, "R11", m_core->r[11]).formatstr("%016X").callimport();
593 state_add( MIPS3_R12, "R12", m_core->r[12]).formatstr("%016X").callimport();
594 state_add( MIPS3_R13, "R13", m_core->r[13]).formatstr("%016X").callimport();
595 state_add( MIPS3_R14, "R14", m_core->r[14]).formatstr("%016X").callimport();
596 state_add( MIPS3_R15, "R15", m_core->r[15]).formatstr("%016X").callimport();
597 state_add( MIPS3_R16, "R16", m_core->r[16]).formatstr("%016X").callimport();
598 state_add( MIPS3_R17, "R17", m_core->r[17]).formatstr("%016X").callimport();
599 state_add( MIPS3_R18, "R18", m_core->r[18]).formatstr("%016X").callimport();
600 state_add( MIPS3_R19, "R19", m_core->r[19]).formatstr("%016X").callimport();
601 state_add( MIPS3_R20, "R20", m_core->r[20]).formatstr("%016X").callimport();
602 state_add( MIPS3_R21, "R21", m_core->r[21]).formatstr("%016X").callimport();
603 state_add( MIPS3_R22, "R22", m_core->r[22]).formatstr("%016X").callimport();
604 state_add( MIPS3_R23, "R23", m_core->r[23]).formatstr("%016X").callimport();
605 state_add( MIPS3_R24, "R24", m_core->r[24]).formatstr("%016X").callimport();
606 state_add( MIPS3_R25, "R25", m_core->r[25]).formatstr("%016X").callimport();
607 state_add( MIPS3_R26, "R26", m_core->r[26]).formatstr("%016X").callimport();
608 state_add( MIPS3_R27, "R27", m_core->r[27]).formatstr("%016X").callimport();
609 state_add( MIPS3_R28, "R28", m_core->r[28]).formatstr("%016X").callimport();
610 state_add( MIPS3_R29, "R29", m_core->r[29]).formatstr("%016X").callimport();
611 state_add( MIPS3_R30, "R30", m_core->r[30]).formatstr("%016X").callimport();
612 state_add( MIPS3_R31, "R31", m_core->r[31]).formatstr("%016X").callimport();
613 #endif
614 state_add( MIPS3_HI, "HI", m_core->r[REG_HI]).formatstr("%016X").callimport();
615 state_add( MIPS3_LO, "LO", m_core->r[REG_LO]).formatstr("%016X").callimport();
616
617 state_add( MIPS3_CCR1_31, "CCR31", m_core->ccr[1][31]).formatstr("%08X");
618
619 state_add( MIPS3_FPR0, "FPR0", m_core->cpr[1][0]).formatstr("%016X");
620 state_add( MIPS3_FPS0, "FPS0", m_core->cpr[1][0]).formatstr("%17s");
621 state_add( MIPS3_FPD0, "FPD0", m_core->cpr[1][0]).formatstr("%17s");
622 state_add( MIPS3_FPR1, "FPR1", m_core->cpr[1][1]).formatstr("%016X");
623 state_add( MIPS3_FPS1, "FPS1", m_core->cpr[1][1]).formatstr("%17s");
624 state_add( MIPS3_FPD1, "FPD1", m_core->cpr[1][1]).formatstr("%17s");
625 state_add( MIPS3_FPR2, "FPR2", m_core->cpr[1][2]).formatstr("%016X");
626 state_add( MIPS3_FPS2, "FPS2", m_core->cpr[1][2]).formatstr("%17s");
627 state_add( MIPS3_FPD2, "FPD2", m_core->cpr[1][2]).formatstr("%17s");
628 state_add( MIPS3_FPR3, "FPR3", m_core->cpr[1][3]).formatstr("%016X");
629 state_add( MIPS3_FPS3, "FPS3", m_core->cpr[1][3]).formatstr("%17s");
630 state_add( MIPS3_FPD3, "FPD3", m_core->cpr[1][3]).formatstr("%17s");
631 state_add( MIPS3_FPR4, "FPR4", m_core->cpr[1][4]).formatstr("%016X");
632 state_add( MIPS3_FPS4, "FPS4", m_core->cpr[1][4]).formatstr("%17s");
633 state_add( MIPS3_FPD4, "FPD4", m_core->cpr[1][4]).formatstr("%17s");
634 state_add( MIPS3_FPR5, "FPR5", m_core->cpr[1][5]).formatstr("%016X");
635 state_add( MIPS3_FPS5, "FPS5", m_core->cpr[1][5]).formatstr("%17s");
636 state_add( MIPS3_FPD5, "FPD5", m_core->cpr[1][5]).formatstr("%17s");
637 state_add( MIPS3_FPR6, "FPR6", m_core->cpr[1][6]).formatstr("%016X");
638 state_add( MIPS3_FPS6, "FPS6", m_core->cpr[1][6]).formatstr("%17s");
639 state_add( MIPS3_FPD6, "FPD6", m_core->cpr[1][6]).formatstr("%17s");
640 state_add( MIPS3_FPR7, "FPR7", m_core->cpr[1][7]).formatstr("%016X");
641 state_add( MIPS3_FPS7, "FPS7", m_core->cpr[1][7]).formatstr("%17s");
642 state_add( MIPS3_FPD7, "FPD7", m_core->cpr[1][7]).formatstr("%17s");
643 state_add( MIPS3_FPR8, "FPR8", m_core->cpr[1][8]).formatstr("%016X");
644 state_add( MIPS3_FPS8, "FPS8", m_core->cpr[1][8]).formatstr("%17s");
645 state_add( MIPS3_FPD8, "FPD8", m_core->cpr[1][8]).formatstr("%17s");
646 state_add( MIPS3_FPR9, "FPR9", m_core->cpr[1][9]).formatstr("%016X");
647 state_add( MIPS3_FPS9, "FPS9", m_core->cpr[1][9]).formatstr("%17s");
648 state_add( MIPS3_FPD9, "FPD9", m_core->cpr[1][9]).formatstr("%17s");
649 state_add( MIPS3_FPR10, "FPR10", m_core->cpr[1][10]).formatstr("%016X");
650 state_add( MIPS3_FPS10, "FPS10", m_core->cpr[1][10]).formatstr("%17s");
651 state_add( MIPS3_FPD10, "FPD10", m_core->cpr[1][10]).formatstr("%17s");
652 state_add( MIPS3_FPR11, "FPR11", m_core->cpr[1][11]).formatstr("%016X");
653 state_add( MIPS3_FPS11, "FPS11", m_core->cpr[1][11]).formatstr("%17s");
654 state_add( MIPS3_FPD11, "FPD11", m_core->cpr[1][11]).formatstr("%17s");
655 state_add( MIPS3_FPR12, "FPR12", m_core->cpr[1][12]).formatstr("%016X");
656 state_add( MIPS3_FPS12, "FPS12", m_core->cpr[1][12]).formatstr("%17s");
657 state_add( MIPS3_FPD12, "FPD12", m_core->cpr[1][12]).formatstr("%17s");
658 state_add( MIPS3_FPR13, "FPR13", m_core->cpr[1][13]).formatstr("%016X");
659 state_add( MIPS3_FPS13, "FPS13", m_core->cpr[1][13]).formatstr("%17s");
660 state_add( MIPS3_FPD13, "FPD13", m_core->cpr[1][13]).formatstr("%17s");
661 state_add( MIPS3_FPR14, "FPR14", m_core->cpr[1][14]).formatstr("%016X");
662 state_add( MIPS3_FPS14, "FPS14", m_core->cpr[1][14]).formatstr("%17s");
663 state_add( MIPS3_FPD14, "FPD14", m_core->cpr[1][14]).formatstr("%17s");
664 state_add( MIPS3_FPR15, "FPR15", m_core->cpr[1][15]).formatstr("%016X");
665 state_add( MIPS3_FPS15, "FPS15", m_core->cpr[1][15]).formatstr("%17s");
666 state_add( MIPS3_FPD15, "FPD15", m_core->cpr[1][15]).formatstr("%17s");
667 state_add( MIPS3_FPR16, "FPR16", m_core->cpr[1][16]).formatstr("%016X");
668 state_add( MIPS3_FPS16, "FPS16", m_core->cpr[1][16]).formatstr("%17s");
669 state_add( MIPS3_FPD16, "FPD16", m_core->cpr[1][16]).formatstr("%17s");
670 state_add( MIPS3_FPR17, "FPR17", m_core->cpr[1][17]).formatstr("%016X");
671 state_add( MIPS3_FPS17, "FPS17", m_core->cpr[1][17]).formatstr("%17s");
672 state_add( MIPS3_FPD17, "FPD17", m_core->cpr[1][17]).formatstr("%17s");
673 state_add( MIPS3_FPR18, "FPR18", m_core->cpr[1][18]).formatstr("%016X");
674 state_add( MIPS3_FPS18, "FPS18", m_core->cpr[1][18]).formatstr("%17s");
675 state_add( MIPS3_FPD18, "FPD18", m_core->cpr[1][18]).formatstr("%17s");
676 state_add( MIPS3_FPR19, "FPR19", m_core->cpr[1][19]).formatstr("%016X");
677 state_add( MIPS3_FPS19, "FPS19", m_core->cpr[1][19]).formatstr("%17s");
678 state_add( MIPS3_FPD19, "FPD19", m_core->cpr[1][19]).formatstr("%17s");
679 state_add( MIPS3_FPR20, "FPR20", m_core->cpr[1][20]).formatstr("%016X");
680 state_add( MIPS3_FPS20, "FPS20", m_core->cpr[1][20]).formatstr("%17s");
681 state_add( MIPS3_FPD20, "FPD20", m_core->cpr[1][20]).formatstr("%17s");
682 state_add( MIPS3_FPR21, "FPR21", m_core->cpr[1][21]).formatstr("%016X");
683 state_add( MIPS3_FPS21, "FPS21", m_core->cpr[1][21]).formatstr("%17s");
684 state_add( MIPS3_FPD21, "FPD21", m_core->cpr[1][21]).formatstr("%17s");
685 state_add( MIPS3_FPR22, "FPR22", m_core->cpr[1][22]).formatstr("%016X");
686 state_add( MIPS3_FPS22, "FPS22", m_core->cpr[1][22]).formatstr("%17s");
687 state_add( MIPS3_FPD22, "FPD22", m_core->cpr[1][22]).formatstr("%17s");
688 state_add( MIPS3_FPR23, "FPR23", m_core->cpr[1][23]).formatstr("%016X");
689 state_add( MIPS3_FPS23, "FPS23", m_core->cpr[1][23]).formatstr("%17s");
690 state_add( MIPS3_FPD23, "FPD23", m_core->cpr[1][23]).formatstr("%17s");
691 state_add( MIPS3_FPR24, "FPR24", m_core->cpr[1][24]).formatstr("%016X");
692 state_add( MIPS3_FPS24, "FPS24", m_core->cpr[1][24]).formatstr("%17s");
693 state_add( MIPS3_FPD24, "FPD24", m_core->cpr[1][24]).formatstr("%17s");
694 state_add( MIPS3_FPR25, "FPR25", m_core->cpr[1][25]).formatstr("%016X");
695 state_add( MIPS3_FPS25, "FPS25", m_core->cpr[1][25]).formatstr("%17s");
696 state_add( MIPS3_FPD25, "FPD25", m_core->cpr[1][25]).formatstr("%17s");
697 state_add( MIPS3_FPR26, "FPR26", m_core->cpr[1][26]).formatstr("%016X");
698 state_add( MIPS3_FPS26, "FPS26", m_core->cpr[1][26]).formatstr("%17s");
699 state_add( MIPS3_FPD26, "FPD26", m_core->cpr[1][26]).formatstr("%17s");
700 state_add( MIPS3_FPR27, "FPR27", m_core->cpr[1][27]).formatstr("%016X");
701 state_add( MIPS3_FPS27, "FPS27", m_core->cpr[1][27]).formatstr("%17s");
702 state_add( MIPS3_FPD27, "FPD27", m_core->cpr[1][27]).formatstr("%17s");
703 state_add( MIPS3_FPR28, "FPR28", m_core->cpr[1][28]).formatstr("%016X");
704 state_add( MIPS3_FPS28, "FPS28", m_core->cpr[1][28]).formatstr("%17s");
705 state_add( MIPS3_FPD28, "FPD28", m_core->cpr[1][28]).formatstr("%17s");
706 state_add( MIPS3_FPR29, "FPR29", m_core->cpr[1][29]).formatstr("%016X");
707 state_add( MIPS3_FPS29, "FPS29", m_core->cpr[1][29]).formatstr("%17s");
708 state_add( MIPS3_FPD29, "FPD29", m_core->cpr[1][29]).formatstr("%17s");
709 state_add( MIPS3_FPR30, "FPR30", m_core->cpr[1][30]).formatstr("%016X");
710 state_add( MIPS3_FPS30, "FPS30", m_core->cpr[1][30]).formatstr("%17s");
711 state_add( MIPS3_FPD30, "FPD30", m_core->cpr[1][30]).formatstr("%17s");
712 state_add( MIPS3_FPR31, "FPR31", m_core->cpr[1][31]).formatstr("%016X");
713 state_add( MIPS3_FPS31, "FPS31", m_core->cpr[1][31]).formatstr("%17s");
714 state_add( MIPS3_FPD31, "FPD31", m_core->cpr[1][31]).formatstr("%17s");
715
716 //state_add( MIPS3_SR, "SR", m_core->cpr[0][COP0_Status]).formatstr("%08X");
717 //state_add( MIPS3_EPC, "EPC", m_core->cpr[0][COP0_EPC]).formatstr("%08X");
718 //state_add( MIPS3_CAUSE, "Cause", m_core->cpr[0][COP0_Cause]).formatstr("%08X");
719 state_add( MIPS3_COUNT, "Count", m_debugger_temp).callexport().formatstr("%08X");
720 state_add( MIPS3_COMPARE, "Compare", m_core->cpr[0][COP0_Compare]).formatstr("%08X");
721 state_add( MIPS3_INDEX, "Index", m_core->cpr[0][COP0_Index]).formatstr("%08X");
722 state_add( MIPS3_RANDOM, "Random", m_core->cpr[0][COP0_Random]).formatstr("%08X");
723 state_add( MIPS3_ENTRYHI, "EntryHi", m_core->cpr[0][COP0_EntryHi]).formatstr("%016X");
724 state_add( MIPS3_ENTRYLO0, "EntryLo0", m_core->cpr[0][COP0_EntryLo0]).formatstr("%016X");
725 state_add( MIPS3_ENTRYLO1, "EntryLo1", m_core->cpr[0][COP0_EntryLo1]).formatstr("%016X");
726 state_add( MIPS3_PAGEMASK, "PageMask", m_core->cpr[0][COP0_PageMask]).formatstr("%016X");
727 state_add( MIPS3_WIRED, "Wired", m_core->cpr[0][COP0_Wired]).formatstr("%08X");
728 //state_add( MIPS3_BADVADDR, "BadVAddr", m_core->cpr[0][COP0_BadVAddr]).formatstr("%08X");
729 state_add( MIPS3_LLADDR, "LLAddr", m_core->cpr[0][COP0_LLAddr]).formatstr("%08X");
730
731 state_add( STATE_GENPCBASE, "CURPC", m_core->pc).noshow();
732 state_add( STATE_GENSP, "CURSP", m_core->r[31]).noshow();
733 state_add( STATE_GENFLAGS, "CURFLAGS", m_debugger_temp).formatstr("%1s").noshow();
734
735 set_icountptr(m_core->icount);
736 }
737
device_start()738 void r5900le_device::device_start()
739 {
740 mips3_device::device_start();
741 #if USE_ABI_REG_NAMES
742 state_add( MIPS3_R0H, "zeroh", m_core->rh[0]).callimport().formatstr("%016X"); // Can't change R0
743 state_add( MIPS3_R1H, "ath", m_core->rh[1]).formatstr("%016X");
744 state_add( MIPS3_R2H, "v0h", m_core->rh[2]).formatstr("%016X");
745 state_add( MIPS3_R3H, "v1h", m_core->rh[3]).formatstr("%016X");
746 state_add( MIPS3_R4H, "a0h", m_core->rh[4]).formatstr("%016X");
747 state_add( MIPS3_R5H, "a1h", m_core->rh[5]).formatstr("%016X");
748 state_add( MIPS3_R6H, "a2h", m_core->rh[6]).formatstr("%016X");
749 state_add( MIPS3_R7H, "a3h", m_core->rh[7]).formatstr("%016X");
750 state_add( MIPS3_R8H, "t0h", m_core->rh[8]).formatstr("%016X");
751 state_add( MIPS3_R9H, "t1h", m_core->rh[9]).formatstr("%016X");
752 state_add( MIPS3_R10H, "t2h", m_core->rh[10]).formatstr("%016X");
753 state_add( MIPS3_R11H, "t3h", m_core->rh[11]).formatstr("%016X");
754 state_add( MIPS3_R12H, "t4h", m_core->rh[12]).formatstr("%016X");
755 state_add( MIPS3_R13H, "t5h", m_core->rh[13]).formatstr("%016X");
756 state_add( MIPS3_R14H, "t6h", m_core->rh[14]).formatstr("%016X");
757 state_add( MIPS3_R15H, "t7h", m_core->rh[15]).formatstr("%016X");
758 state_add( MIPS3_R16H, "s0h", m_core->rh[16]).formatstr("%016X");
759 state_add( MIPS3_R17H, "s1h", m_core->rh[17]).formatstr("%016X");
760 state_add( MIPS3_R18H, "s2h", m_core->rh[18]).formatstr("%016X");
761 state_add( MIPS3_R19H, "s3h", m_core->rh[19]).formatstr("%016X");
762 state_add( MIPS3_R20H, "s4h", m_core->rh[20]).formatstr("%016X");
763 state_add( MIPS3_R21H, "s5h", m_core->rh[21]).formatstr("%016X");
764 state_add( MIPS3_R22H, "s6h", m_core->rh[22]).formatstr("%016X");
765 state_add( MIPS3_R23H, "s7h", m_core->rh[23]).formatstr("%016X");
766 state_add( MIPS3_R24H, "t8h", m_core->rh[24]).formatstr("%016X");
767 state_add( MIPS3_R25H, "t9h", m_core->rh[25]).formatstr("%016X");
768 state_add( MIPS3_R26H, "k0h", m_core->rh[26]).formatstr("%016X");
769 state_add( MIPS3_R27H, "k1h", m_core->rh[27]).formatstr("%016X");
770 state_add( MIPS3_R28H, "gph", m_core->rh[28]).formatstr("%016X");
771 state_add( MIPS3_R29H, "sph", m_core->rh[29]).formatstr("%016X");
772 state_add( MIPS3_R30H, "fph", m_core->rh[30]).formatstr("%016X");
773 state_add( MIPS3_R31H, "rah", m_core->rh[31]).formatstr("%016X");
774 #else
775 state_add( MIPS3_R0H, "R0H", m_core->rh[0]).callimport().formatstr("%016X"); // Can't change R0
776 state_add( MIPS3_R1H, "R1H", m_core->rh[1]).formatstr("%016X");
777 state_add( MIPS3_R2H, "R2H", m_core->rh[2]).formatstr("%016X");
778 state_add( MIPS3_R3H, "R3H", m_core->rh[3]).formatstr("%016X");
779 state_add( MIPS3_R4H, "R4H", m_core->rh[4]).formatstr("%016X");
780 state_add( MIPS3_R5H, "R5H", m_core->rh[5]).formatstr("%016X");
781 state_add( MIPS3_R6H, "R6H", m_core->rh[6]).formatstr("%016X");
782 state_add( MIPS3_R7H, "R7H", m_core->rh[7]).formatstr("%016X");
783 state_add( MIPS3_R8H, "R8H", m_core->rh[8]).formatstr("%016X");
784 state_add( MIPS3_R9H, "R9H", m_core->rh[9]).formatstr("%016X");
785 state_add( MIPS3_R10H, "R10H", m_core->rh[10]).formatstr("%016X");
786 state_add( MIPS3_R11H, "R11H", m_core->rh[11]).formatstr("%016X");
787 state_add( MIPS3_R12H, "R12H", m_core->rh[12]).formatstr("%016X");
788 state_add( MIPS3_R13H, "R13H", m_core->rh[13]).formatstr("%016X");
789 state_add( MIPS3_R14H, "R14H", m_core->rh[14]).formatstr("%016X");
790 state_add( MIPS3_R15H, "R15H", m_core->rh[15]).formatstr("%016X");
791 state_add( MIPS3_R16H, "R16H", m_core->rh[16]).formatstr("%016X");
792 state_add( MIPS3_R17H, "R17H", m_core->rh[17]).formatstr("%016X");
793 state_add( MIPS3_R18H, "R18H", m_core->rh[18]).formatstr("%016X");
794 state_add( MIPS3_R19H, "R19H", m_core->rh[19]).formatstr("%016X");
795 state_add( MIPS3_R20H, "R20H", m_core->rh[20]).formatstr("%016X");
796 state_add( MIPS3_R21H, "R21H", m_core->rh[21]).formatstr("%016X");
797 state_add( MIPS3_R22H, "R22H", m_core->rh[22]).formatstr("%016X");
798 state_add( MIPS3_R23H, "R23H", m_core->rh[23]).formatstr("%016X");
799 state_add( MIPS3_R24H, "R24H", m_core->rh[24]).formatstr("%016X");
800 state_add( MIPS3_R25H, "R25H", m_core->rh[25]).formatstr("%016X");
801 state_add( MIPS3_R26H, "R26H", m_core->rh[26]).formatstr("%016X");
802 state_add( MIPS3_R27H, "R27H", m_core->rh[27]).formatstr("%016X");
803 state_add( MIPS3_R28H, "R28H", m_core->rh[28]).formatstr("%016X");
804 state_add( MIPS3_R29H, "R29H", m_core->rh[29]).formatstr("%016X");
805 state_add( MIPS3_R30H, "R30H", m_core->rh[30]).formatstr("%016X");
806 state_add( MIPS3_R31H, "R31H", m_core->rh[31]).formatstr("%016X");
807 #endif
808 }
809
state_export(const device_state_entry & entry)810 void mips3_device::state_export(const device_state_entry &entry)
811 {
812 switch (entry.index())
813 {
814 case MIPS3_COUNT:
815 m_debugger_temp = (total_cycles() - m_core->count_zero_time) / 2;
816 break;
817 }
818 }
819
state_import(const device_state_entry & entry)820 void mips3_device::state_import(const device_state_entry &entry)
821 {
822 if (m_isdrc && (entry.index() >= MIPS3_R1) && (entry.index() <= MIPS3_LO))
823 {
824 // this refers to HI as R32 and LO as R33 because I'm lazy
825 const unsigned regnum = entry.index() - MIPS3_R0;
826 if (m_regmap[regnum].is_int_register())
827 logerror("debugger R%u = %08X, must update UML I%u\n", regnum, m_core->r[regnum], m_regmap[regnum].ireg() - uml::REG_I0);
828 }
829 }
830
state_string_export(const device_state_entry & entry,std::string & str) const831 void mips3_device::state_string_export(const device_state_entry &entry, std::string &str) const
832 {
833 switch (entry.index())
834 {
835 case MIPS3_FPS0:
836 str = string_format("!%16g", *(float *)&m_core->cpr[1][0]);
837 break;
838
839 case MIPS3_FPD0:
840 str = string_format("!%16g", *(double *)&m_core->cpr[1][0]);
841 break;
842
843 case MIPS3_FPS1:
844 str = string_format("!%16g", *(float *)&m_core->cpr[1][1]);
845 break;
846
847 case MIPS3_FPD1:
848 str = string_format("!%16g", *(double *)&m_core->cpr[1][1]);
849 break;
850
851 case MIPS3_FPS2:
852 str = string_format("!%16g", *(float *)&m_core->cpr[1][2]);
853 break;
854
855 case MIPS3_FPD2:
856 str = string_format("!%16g", *(double *)&m_core->cpr[1][2]);
857 break;
858
859 case MIPS3_FPS3:
860 str = string_format("!%16g", *(float *)&m_core->cpr[1][3]);
861 break;
862
863 case MIPS3_FPD3:
864 str = string_format("!%16g", *(double *)&m_core->cpr[1][3]);
865 break;
866
867 case MIPS3_FPS4:
868 str = string_format("!%16g", *(float *)&m_core->cpr[1][4]);
869 break;
870
871 case MIPS3_FPD4:
872 str = string_format("!%16g", *(double *)&m_core->cpr[1][4]);
873 break;
874
875 case MIPS3_FPS5:
876 str = string_format("!%16g", *(float *)&m_core->cpr[1][5]);
877 break;
878
879 case MIPS3_FPD5:
880 str = string_format("!%16g", *(double *)&m_core->cpr[1][5]);
881 break;
882
883 case MIPS3_FPS6:
884 str = string_format("!%16g", *(float *)&m_core->cpr[1][6]);
885 break;
886
887 case MIPS3_FPD6:
888 str = string_format("!%16g", *(double *)&m_core->cpr[1][6]);
889 break;
890
891 case MIPS3_FPS7:
892 str = string_format("!%16g", *(float *)&m_core->cpr[1][7]);
893 break;
894
895 case MIPS3_FPD7:
896 str = string_format("!%16g", *(double *)&m_core->cpr[1][7]);
897 break;
898
899 case MIPS3_FPS8:
900 str = string_format("!%16g", *(float *)&m_core->cpr[1][8]);
901 break;
902
903 case MIPS3_FPD8:
904 str = string_format("!%16g", *(double *)&m_core->cpr[1][8]);
905 break;
906
907 case MIPS3_FPS9:
908 str = string_format("!%16g", *(float *)&m_core->cpr[1][9]);
909 break;
910
911 case MIPS3_FPD9:
912 str = string_format("!%16g", *(double *)&m_core->cpr[1][9]);
913 break;
914
915 case MIPS3_FPS10:
916 str = string_format("!%16g", *(float *)&m_core->cpr[1][10]);
917 break;
918
919 case MIPS3_FPD10:
920 str = string_format("!%16g", *(double *)&m_core->cpr[1][10]);
921 break;
922
923 case MIPS3_FPS11:
924 str = string_format("!%16g", *(float *)&m_core->cpr[1][11]);
925 break;
926
927 case MIPS3_FPD11:
928 str = string_format("!%16g", *(double *)&m_core->cpr[1][11]);
929 break;
930
931 case MIPS3_FPS12:
932 str = string_format("!%16g", *(float *)&m_core->cpr[1][12]);
933 break;
934
935 case MIPS3_FPD12:
936 str = string_format("!%16g", *(double *)&m_core->cpr[1][12]);
937 break;
938
939 case MIPS3_FPS13:
940 str = string_format("!%16g", *(float *)&m_core->cpr[1][13]);
941 break;
942
943 case MIPS3_FPD13:
944 str = string_format("!%16g", *(double *)&m_core->cpr[1][13]);
945 break;
946
947 case MIPS3_FPS14:
948 str = string_format("!%16g", *(float *)&m_core->cpr[1][14]);
949 break;
950
951 case MIPS3_FPD14:
952 str = string_format("!%16g", *(double *)&m_core->cpr[1][14]);
953 break;
954
955 case MIPS3_FPS15:
956 str = string_format("!%16g", *(float *)&m_core->cpr[1][15]);
957 break;
958
959 case MIPS3_FPD15:
960 str = string_format("!%16g", *(double *)&m_core->cpr[1][15]);
961 break;
962
963 case MIPS3_FPS16:
964 str = string_format("!%16g", *(float *)&m_core->cpr[1][16]);
965 break;
966
967 case MIPS3_FPD16:
968 str = string_format("!%16g", *(double *)&m_core->cpr[1][16]);
969 break;
970
971 case MIPS3_FPS17:
972 str = string_format("!%16g", *(float *)&m_core->cpr[1][17]);
973 break;
974
975 case MIPS3_FPD17:
976 str = string_format("!%16g", *(double *)&m_core->cpr[1][17]);
977 break;
978
979 case MIPS3_FPS18:
980 str = string_format("!%16g", *(float *)&m_core->cpr[1][18]);
981 break;
982
983 case MIPS3_FPD18:
984 str = string_format("!%16g", *(double *)&m_core->cpr[1][18]);
985 break;
986
987 case MIPS3_FPS19:
988 str = string_format("!%16g", *(float *)&m_core->cpr[1][19]);
989 break;
990
991 case MIPS3_FPD19:
992 str = string_format("!%16g", *(double *)&m_core->cpr[1][19]);
993 break;
994
995 case MIPS3_FPS20:
996 str = string_format("!%16g", *(float *)&m_core->cpr[1][20]);
997 break;
998
999 case MIPS3_FPD20:
1000 str = string_format("!%16g", *(double *)&m_core->cpr[1][20]);
1001 break;
1002
1003 case MIPS3_FPS21:
1004 str = string_format("!%16g", *(float *)&m_core->cpr[1][21]);
1005 break;
1006
1007 case MIPS3_FPD21:
1008 str = string_format("!%16g", *(double *)&m_core->cpr[1][21]);
1009 break;
1010
1011 case MIPS3_FPS22:
1012 str = string_format("!%16g", *(float *)&m_core->cpr[1][22]);
1013 break;
1014
1015 case MIPS3_FPD22:
1016 str = string_format("!%16g", *(double *)&m_core->cpr[1][22]);
1017 break;
1018
1019 case MIPS3_FPS23:
1020 str = string_format("!%16g", *(float *)&m_core->cpr[1][23]);
1021 break;
1022
1023 case MIPS3_FPD23:
1024 str = string_format("!%16g", *(double *)&m_core->cpr[1][23]);
1025 break;
1026
1027 case MIPS3_FPS24:
1028 str = string_format("!%16g", *(float *)&m_core->cpr[1][24]);
1029 break;
1030
1031 case MIPS3_FPD24:
1032 str = string_format("!%16g", *(double *)&m_core->cpr[1][24]);
1033 break;
1034
1035 case MIPS3_FPS25:
1036 str = string_format("!%16g", *(float *)&m_core->cpr[1][25]);
1037 break;
1038
1039 case MIPS3_FPD25:
1040 str = string_format("!%16g", *(double *)&m_core->cpr[1][25]);
1041 break;
1042
1043 case MIPS3_FPS26:
1044 str = string_format("!%16g", *(float *)&m_core->cpr[1][26]);
1045 break;
1046
1047 case MIPS3_FPD26:
1048 str = string_format("!%16g", *(double *)&m_core->cpr[1][26]);
1049 break;
1050
1051 case MIPS3_FPS27:
1052 str = string_format("!%16g", *(float *)&m_core->cpr[1][27]);
1053 break;
1054
1055 case MIPS3_FPD27:
1056 str = string_format("!%16g", *(double *)&m_core->cpr[1][27]);
1057 break;
1058
1059 case MIPS3_FPS28:
1060 str = string_format("!%16g", *(float *)&m_core->cpr[1][28]);
1061 break;
1062
1063 case MIPS3_FPD28:
1064 str = string_format("!%16g", *(double *)&m_core->cpr[1][28]);
1065 break;
1066
1067 case MIPS3_FPS29:
1068 str = string_format("!%16g", *(float *)&m_core->cpr[1][29]);
1069 break;
1070
1071 case MIPS3_FPD29:
1072 str = string_format("!%16g", *(double *)&m_core->cpr[1][29]);
1073 break;
1074
1075 case MIPS3_FPS30:
1076 str = string_format("!%16g", *(float *)&m_core->cpr[1][30]);
1077 break;
1078
1079 case MIPS3_FPD30:
1080 str = string_format("!%16g", *(double *)&m_core->cpr[1][30]);
1081 break;
1082
1083 case MIPS3_FPS31:
1084 str = string_format("!%16g", *(float *)&m_core->cpr[1][31]);
1085 break;
1086
1087 case MIPS3_FPD31:
1088 str = string_format("!%16g", *(double *)&m_core->cpr[1][31]);
1089 break;
1090
1091 case STATE_GENFLAGS:
1092 str = " ";
1093 break;
1094 }
1095 }
1096
1097
device_reset()1098 void mips3_device::device_reset()
1099 {
1100 /* common reset */
1101 m_nextpc = ~0;
1102 memset(m_cf, 0, sizeof(m_cf));
1103
1104 /* initialize the state */
1105 m_core->pc = 0xbfc00000;
1106 m_core->cpr[0][COP0_Status] = SR_BEV | SR_ERL;
1107 m_core->cpr[0][COP0_Wired] = 0;
1108 m_core->cpr[0][COP0_Compare] = 0xffffffff;
1109 m_core->cpr[0][COP0_Count] = 0;
1110 m_core->cpr[0][COP0_Config] = compute_config_register();
1111 m_core->cpr[0][COP0_PRId] = compute_prid_register();
1112 m_core->cpr[0][COP0_LLAddr] = 0;
1113 m_core->llbit = 0;
1114 m_core->count_zero_time = total_cycles();
1115
1116 /* initialize the TLB state */
1117 for (int tlbindex = 0; tlbindex < m_tlbentries; tlbindex++)
1118 {
1119 mips3_tlb_entry *entry = &m_tlb[tlbindex];
1120 entry->page_mask = 0;
1121 entry->entry_hi = 0xffffffff;
1122 entry->entry_lo[0] = 0xfffffff8;
1123 entry->entry_lo[1] = 0xfffffff8;
1124 vtlb_load(2 * tlbindex + 0, 0, 0, 0);
1125 vtlb_load(2 * tlbindex + 1, 0, 0, 0);
1126 if (m_flavor == MIPS3_TYPE_TX4925)
1127 vtlb_load(2 * tlbindex + 2, 0, 0, 0);
1128 }
1129
1130 /* load the fixed TLB range */
1131 vtlb_load(2 * m_tlbentries + 0, (0xa0000000 - 0x80000000) >> MIPS3_MIN_PAGE_SHIFT, 0x80000000, 0x00000000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID);
1132 vtlb_load(2 * m_tlbentries + 1, (0xc0000000 - 0xa0000000) >> MIPS3_MIN_PAGE_SHIFT, 0xa0000000, 0x00000000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID);
1133 // TX4925 on-board peripherals pass-through
1134 if (m_flavor == MIPS3_TYPE_TX4925)
1135 vtlb_load(2 * m_tlbentries + 2, (0xff200000 - 0xff1f0000) >> MIPS3_MIN_PAGE_SHIFT, 0xff1f0000, 0xff1f0000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID);
1136 m_tlb_seed = 0;
1137
1138 m_core->mode = (MODE_KERNEL << 1) | 0;
1139 m_drc_cache_dirty = true;
1140 m_interrupt_cycles = 0;
1141
1142 m_core->vfr[0][3] = 1.0f;
1143 m_core->vfmem = &m_core->vumem[0];
1144 m_core->vimem = reinterpret_cast<uint32_t*>(m_core->vfmem);
1145 m_core->vr = &m_core->vcr[20];
1146 m_core->i = reinterpret_cast<float*>(&m_core->vcr[21]);
1147 m_core->q = reinterpret_cast<float*>(&m_core->vcr[22]);
1148 }
1149
1150
memory_translate(int spacenum,int intention,offs_t & address)1151 bool mips3_device::memory_translate(int spacenum, int intention, offs_t &address)
1152 {
1153 /* only applies to the program address space */
1154 if (spacenum == AS_PROGRAM)
1155 {
1156 const vtlb_entry *table = vtlb_table();
1157 vtlb_entry entry = table[address >> MIPS3_MIN_PAGE_SHIFT];
1158 if ((entry & (1 << (intention & (TRANSLATE_TYPE_MASK | TRANSLATE_USER_MASK)))) == 0)
1159 return false;
1160 address = (entry & ~MIPS3_MIN_PAGE_MASK) | (address & MIPS3_MIN_PAGE_MASK);
1161 }
1162 return true;
1163 }
1164
create_disassembler()1165 std::unique_ptr<util::disasm_interface> mips3_device::create_disassembler()
1166 {
1167 return std::make_unique<mips3_disassembler>();
1168 }
1169
create_disassembler()1170 std::unique_ptr<util::disasm_interface> r5900le_device::create_disassembler()
1171 {
1172 return std::make_unique<ee_disassembler>();
1173 }
1174
1175
1176
1177 /***************************************************************************
1178 TLB HANDLING
1179 ***************************************************************************/
1180
RBYTE(offs_t address,uint32_t * result)1181 inline bool mips3_device::RBYTE(offs_t address, uint32_t *result)
1182 {
1183 const uint32_t tlbval = vtlb_table()[address >> 12];
1184 if (tlbval & VTLB_READ_ALLOWED)
1185 {
1186 const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
1187 for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
1188 {
1189 if (tlbaddress < m_fastram[ramnum].start || tlbaddress > m_fastram[ramnum].end)
1190 {
1191 continue;
1192 }
1193 *result = m_fastram[ramnum].offset_base8[tlbaddress ^ m_byte_xor];
1194 return true;
1195 }
1196 *result = (*m_memory.read_byte)(*m_program, tlbaddress);
1197 }
1198 else
1199 {
1200 if(tlbval & VTLB_FLAG_FIXED)
1201 {
1202 generate_tlb_exception(EXCEPTION_TLBLOAD, address);
1203 }
1204 else
1205 {
1206 generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address);
1207 }
1208 *result = 0;
1209 return false;
1210 }
1211 return true;
1212 }
1213
RHALF(offs_t address,uint32_t * result)1214 inline bool mips3_device::RHALF(offs_t address, uint32_t *result)
1215 {
1216 const uint32_t tlbval = vtlb_table()[address >> 12];
1217 if (tlbval & VTLB_READ_ALLOWED)
1218 {
1219 const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
1220 for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
1221 {
1222 if (tlbaddress < m_fastram[ramnum].start || tlbaddress > m_fastram[ramnum].end)
1223 {
1224 continue;
1225 }
1226 *result = m_fastram[ramnum].offset_base16[(tlbaddress ^ m_word_xor) >> 1];
1227 return true;
1228 }
1229 *result = (*m_memory.read_word)(*m_program, tlbaddress);
1230 }
1231 else
1232 {
1233 if(tlbval & VTLB_FLAG_FIXED)
1234 {
1235 generate_tlb_exception(EXCEPTION_TLBLOAD, address);
1236 }
1237 else
1238 {
1239 generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address);
1240 }
1241 *result = 0;
1242 return false;
1243 }
1244 return true;
1245 }
1246
RWORD(offs_t address,uint32_t * result,bool insn)1247 inline bool mips3_device::RWORD(offs_t address, uint32_t *result, bool insn)
1248 {
1249 const uint32_t tlbval = vtlb_table()[address >> 12];
1250 if (tlbval & VTLB_READ_ALLOWED)
1251 {
1252 const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
1253 for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
1254 {
1255 if (tlbaddress < m_fastram[ramnum].start || tlbaddress > m_fastram[ramnum].end)
1256 {
1257 continue;
1258 }
1259 *result = m_fastram[ramnum].offset_base32[(tlbaddress ^ m_dword_xor) >> 2];
1260 return true;
1261 }
1262 *result = (*m_memory.read_dword)(*m_program, tlbaddress);
1263 }
1264 else
1265 {
1266 if(tlbval & VTLB_FLAG_FIXED)
1267 {
1268 generate_tlb_exception(EXCEPTION_TLBLOAD, address);
1269 }
1270 else
1271 {
1272 generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address);
1273 }
1274 *result = 0;
1275 return false;
1276 }
1277 return true;
1278 }
1279
RWORD_MASKED(offs_t address,uint32_t * result,uint32_t mem_mask)1280 inline bool mips3_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_t mem_mask)
1281 {
1282 const uint32_t tlbval = vtlb_table()[address >> 12];
1283 if (tlbval & VTLB_READ_ALLOWED)
1284 {
1285 *result = (*m_memory.read_dword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), mem_mask);
1286 }
1287 else
1288 {
1289 if(tlbval & VTLB_FLAG_FIXED)
1290 {
1291 generate_tlb_exception(EXCEPTION_TLBLOAD, address);
1292 }
1293 else
1294 {
1295 generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address);
1296 }
1297 *result = 0;
1298 return false;
1299 }
1300 return true;
1301 }
1302
RDOUBLE(offs_t address,uint64_t * result)1303 inline bool mips3_device::RDOUBLE(offs_t address, uint64_t *result)
1304 {
1305 const uint32_t tlbval = vtlb_table()[address >> 12];
1306 if (tlbval & VTLB_READ_ALLOWED)
1307 {
1308 *result = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff));
1309 }
1310 else
1311 {
1312 if(tlbval & VTLB_FLAG_FIXED)
1313 {
1314 generate_tlb_exception(EXCEPTION_TLBLOAD, address);
1315 }
1316 else
1317 {
1318 generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address);
1319 }
1320 *result = 0;
1321 return false;
1322 }
1323 return true;
1324 }
1325
RDOUBLE_MASKED(offs_t address,uint64_t * result,uint64_t mem_mask)1326 inline bool mips3_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint64_t mem_mask)
1327 {
1328 const uint32_t tlbval = vtlb_table()[address >> 12];
1329 if (tlbval & VTLB_READ_ALLOWED)
1330 {
1331 *result = (*m_memory.read_qword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), mem_mask);
1332 }
1333 else
1334 {
1335 if(tlbval & VTLB_FLAG_FIXED)
1336 {
1337 generate_tlb_exception(EXCEPTION_TLBLOAD, address);
1338 }
1339 else
1340 {
1341 generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address);
1342 }
1343 *result = 0;
1344 return false;
1345 }
1346 return true;
1347 }
1348
WBYTE(offs_t address,uint8_t data)1349 inline void mips3_device::WBYTE(offs_t address, uint8_t data)
1350 {
1351 const uint32_t tlbval = vtlb_table()[address >> 12];
1352 if (tlbval & VTLB_WRITE_ALLOWED)
1353 {
1354 const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
1355 for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
1356 {
1357 if (m_fastram[ramnum].readonly == true || tlbaddress < m_fastram[ramnum].start || tlbaddress > m_fastram[ramnum].end)
1358 {
1359 continue;
1360 }
1361 m_fastram[ramnum].offset_base8[tlbaddress ^ m_byte_xor] = data;
1362 return;
1363 }
1364 (*m_memory.write_byte)(*m_program, tlbaddress, data);
1365 }
1366 else
1367 {
1368 if(tlbval & VTLB_READ_ALLOWED)
1369 {
1370 generate_tlb_exception(EXCEPTION_TLBMOD, address);
1371 }
1372 else if(tlbval & VTLB_FLAG_FIXED)
1373 {
1374 generate_tlb_exception(EXCEPTION_TLBSTORE, address);
1375 }
1376 else
1377 {
1378 generate_tlb_exception(EXCEPTION_TLBSTORE_FILL, address);
1379 }
1380 }
1381 }
1382
WHALF(offs_t address,uint16_t data)1383 inline void mips3_device::WHALF(offs_t address, uint16_t data)
1384 {
1385 const uint32_t tlbval = vtlb_table()[address >> 12];
1386 if (tlbval & VTLB_WRITE_ALLOWED)
1387 {
1388 const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
1389 for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
1390 {
1391 if (m_fastram[ramnum].readonly == true || tlbaddress < m_fastram[ramnum].start || tlbaddress > m_fastram[ramnum].end)
1392 {
1393 continue;
1394 }
1395 m_fastram[ramnum].offset_base16[(tlbaddress ^ m_word_xor) >> 1] = data;
1396 return;
1397 }
1398 (*m_memory.write_word)(*m_program, tlbaddress, data);
1399 }
1400 else
1401 {
1402 if(tlbval & VTLB_READ_ALLOWED)
1403 {
1404 generate_tlb_exception(EXCEPTION_TLBMOD, address);
1405 }
1406 else if(tlbval & VTLB_FLAG_FIXED)
1407 {
1408 generate_tlb_exception(EXCEPTION_TLBSTORE, address);
1409 }
1410 else
1411 {
1412 generate_tlb_exception(EXCEPTION_TLBSTORE_FILL, address);
1413 }
1414 }
1415 }
1416
WWORD(offs_t address,uint32_t data)1417 inline void mips3_device::WWORD(offs_t address, uint32_t data)
1418 {
1419 const uint32_t tlbval = vtlb_table()[address >> 12];
1420 if (tlbval & VTLB_WRITE_ALLOWED)
1421 {
1422 const uint32_t tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
1423 for (int ramnum = 0; ramnum < m_fastram_select; ramnum++)
1424 {
1425 if (m_fastram[ramnum].readonly == true || tlbaddress < m_fastram[ramnum].start || tlbaddress > m_fastram[ramnum].end)
1426 {
1427 continue;
1428 }
1429 m_fastram[ramnum].offset_base32[(tlbaddress ^ m_dword_xor) >> 2] = data;
1430 return;
1431 }
1432 (*m_memory.write_dword)(*m_program, tlbaddress, data);
1433 }
1434 else
1435 {
1436 if(tlbval & VTLB_READ_ALLOWED)
1437 {
1438 generate_tlb_exception(EXCEPTION_TLBMOD, address);
1439 }
1440 else if(tlbval & VTLB_FLAG_FIXED)
1441 {
1442 generate_tlb_exception(EXCEPTION_TLBSTORE, address);
1443 }
1444 else
1445 {
1446 generate_tlb_exception(EXCEPTION_TLBSTORE_FILL, address);
1447 }
1448 }
1449 }
1450
WWORD_MASKED(offs_t address,uint32_t data,uint32_t mem_mask)1451 inline void mips3_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t mem_mask)
1452 {
1453 const uint32_t tlbval = vtlb_table()[address >> 12];
1454 if (tlbval & VTLB_WRITE_ALLOWED)
1455 {
1456 (*m_memory.write_dword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data, mem_mask);
1457 }
1458 else
1459 {
1460 if(tlbval & VTLB_READ_ALLOWED)
1461 {
1462 generate_tlb_exception(EXCEPTION_TLBMOD, address);
1463 }
1464 else if(tlbval & VTLB_FLAG_FIXED)
1465 {
1466 generate_tlb_exception(EXCEPTION_TLBSTORE, address);
1467 }
1468 else
1469 {
1470 generate_tlb_exception(EXCEPTION_TLBSTORE_FILL, address);
1471 }
1472 }
1473 }
1474
WDOUBLE(offs_t address,uint64_t data)1475 inline void mips3_device::WDOUBLE(offs_t address, uint64_t data)
1476 {
1477 const uint32_t tlbval = vtlb_table()[address >> 12];
1478 if (tlbval & VTLB_WRITE_ALLOWED)
1479 {
1480 (*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data);
1481 }
1482 else
1483 {
1484 if(tlbval & VTLB_READ_ALLOWED)
1485 {
1486 generate_tlb_exception(EXCEPTION_TLBMOD, address);
1487 }
1488 else if(tlbval & VTLB_FLAG_FIXED)
1489 {
1490 generate_tlb_exception(EXCEPTION_TLBSTORE, address);
1491 }
1492 else
1493 {
1494 generate_tlb_exception(EXCEPTION_TLBSTORE_FILL, address);
1495 }
1496 }
1497 }
1498
WDOUBLE_MASKED(offs_t address,uint64_t data,uint64_t mem_mask)1499 inline void mips3_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask)
1500 {
1501 const uint32_t tlbval = vtlb_table()[address >> 12];
1502 if (tlbval & VTLB_WRITE_ALLOWED)
1503 {
1504 (*m_memory.write_qword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data, mem_mask);
1505 }
1506 else
1507 {
1508 if(tlbval & VTLB_READ_ALLOWED)
1509 {
1510 generate_tlb_exception(EXCEPTION_TLBMOD, address);
1511 }
1512 else if(tlbval & VTLB_FLAG_FIXED)
1513 {
1514 generate_tlb_exception(EXCEPTION_TLBSTORE, address);
1515 }
1516 else
1517 {
1518 generate_tlb_exception(EXCEPTION_TLBSTORE_FILL, address);
1519 }
1520 }
1521 }
1522
WBYTE(offs_t address,uint8_t data)1523 inline void r5900le_device::WBYTE(offs_t address, uint8_t data)
1524 {
1525 if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_byte)(*m_program, address, data);
1526 else mips3_device::WBYTE(address, data);
1527 }
1528
WHALF(offs_t address,uint16_t data)1529 inline void r5900le_device::WHALF(offs_t address, uint16_t data)
1530 {
1531 if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_word)(*m_program, address, data);
1532 else mips3_device::WHALF(address, data);
1533 }
1534
WWORD(offs_t address,uint32_t data)1535 inline void r5900le_device::WWORD(offs_t address, uint32_t data)
1536 {
1537 if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_dword)(*m_program, address, data);
1538 else mips3_device::WWORD(address, data);
1539 }
1540
WWORD_MASKED(offs_t address,uint32_t data,uint32_t mem_mask)1541 inline void r5900le_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t mem_mask)
1542 {
1543 if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_dword_masked)(*m_program, address, data, mem_mask);
1544 else mips3_device::WWORD_MASKED(address, data, mem_mask);
1545 }
1546
WDOUBLE(offs_t address,uint64_t data)1547 inline void r5900le_device::WDOUBLE(offs_t address, uint64_t data) {
1548 if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_qword)(*m_program, address, data);
1549 else mips3_device::WDOUBLE(address, data);
1550 }
1551
WDOUBLE_MASKED(offs_t address,uint64_t data,uint64_t mem_mask)1552 inline void r5900le_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask)
1553 {
1554 if (address >= 0x70000000 && address < 0x70004000) (*m_memory.write_qword_masked)(*m_program, address, data, mem_mask);
1555 else mips3_device::WDOUBLE_MASKED(address, data, mem_mask);
1556 }
1557
WQUAD(offs_t address,uint64_t data_hi,uint64_t data_lo)1558 inline void r5900le_device::WQUAD(offs_t address, uint64_t data_hi, uint64_t data_lo)
1559 {
1560 if (address >= 0x70000000 && address < 0x70004000)
1561 {
1562 (*m_memory.write_qword)(*m_program, address, data_lo);
1563 (*m_memory.write_qword)(*m_program, address + 8, data_hi);
1564 return;
1565 }
1566
1567 const uint32_t tlbval = vtlb_table()[address >> 12];
1568 if (tlbval & VTLB_WRITE_ALLOWED)
1569 {
1570 (*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data_lo);
1571 (*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | ((address + 8) & 0xfff), data_hi);
1572 }
1573 else
1574 {
1575 if(tlbval & VTLB_READ_ALLOWED)
1576 {
1577 generate_tlb_exception(EXCEPTION_TLBMOD, address);
1578 }
1579 else if(tlbval & VTLB_FLAG_FIXED)
1580 {
1581 generate_tlb_exception(EXCEPTION_TLBSTORE, address);
1582 }
1583 else
1584 {
1585 generate_tlb_exception(EXCEPTION_TLBSTORE_FILL, address);
1586 }
1587 }
1588 }
1589
RBYTE(offs_t address,uint32_t * result)1590 inline bool r5900le_device::RBYTE(offs_t address, uint32_t *result) {
1591 if (address >= 0x70000000 && address < 0x70004000) {
1592 *result = (*m_memory.read_byte)(*m_program, address);
1593 return true;
1594 }
1595 return mips3_device::RBYTE(address, result);
1596 }
1597
RHALF(offs_t address,uint32_t * result)1598 inline bool r5900le_device::RHALF(offs_t address, uint32_t *result)
1599 {
1600 if (address >= 0x70000000 && address < 0x70004000)
1601 {
1602 *result = (*m_memory.read_word)(*m_program, address);
1603 return true;
1604 }
1605 return mips3_device::RHALF(address, result);
1606 }
1607
RWORD(offs_t address,uint32_t * result,bool insn)1608 inline bool r5900le_device::RWORD(offs_t address, uint32_t *result, bool insn)
1609 {
1610 if (address >= 0x70000000 && address < 0x70004000)
1611 {
1612 *result = (*m_memory.read_dword)(*m_program, address);
1613 return true;
1614 }
1615 return mips3_device::RWORD(address, result, insn);
1616 }
1617
RWORD_MASKED(offs_t address,uint32_t * result,uint32_t mem_mask)1618 inline bool r5900le_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_t mem_mask)
1619 {
1620 if (address >= 0x70000000 && address < 0x70004000)
1621 {
1622 *result = (*m_memory.read_dword_masked)(*m_program, address, mem_mask);
1623 return true;
1624 }
1625 return mips3_device::RWORD_MASKED(address, result, mem_mask);
1626 }
1627
RDOUBLE(offs_t address,uint64_t * result)1628 inline bool r5900le_device::RDOUBLE(offs_t address, uint64_t *result)
1629 {
1630 if (address >= 0x70000000 && address < 0x70004000)
1631 {
1632 *result = (*m_memory.read_qword)(*m_program, address);
1633 return true;
1634 }
1635 return mips3_device::RDOUBLE(address, result);
1636 }
1637
RDOUBLE_MASKED(offs_t address,uint64_t * result,uint64_t mem_mask)1638 inline bool r5900le_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint64_t mem_mask)
1639 {
1640 if (address >= 0x70000000 && address < 0x70004000)
1641 {
1642 *result = (*m_memory.read_qword_masked)(*m_program, address, mem_mask);
1643 return true;
1644 }
1645 return mips3_device::RDOUBLE_MASKED(address, result, mem_mask);
1646 }
1647
RQUAD(offs_t address,uint64_t * result_hi,uint64_t * result_lo)1648 inline bool r5900le_device::RQUAD(offs_t address, uint64_t *result_hi, uint64_t *result_lo)
1649 {
1650 if (address >= 0x70000000 && address < 0x70004000)
1651 {
1652 *result_lo = (*m_memory.read_qword)(*m_program, address);
1653 *result_hi = (*m_memory.read_qword)(*m_program, address + 8);
1654 return true;
1655 }
1656
1657 const uint32_t tlbval = vtlb_table()[address >> 12];
1658 if (tlbval & VTLB_READ_ALLOWED)
1659 {
1660 *result_lo = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff));
1661 *result_hi = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | ((address + 8) & 0xfff));
1662 }
1663 else
1664 {
1665 if(tlbval & VTLB_FLAG_FIXED)
1666 {
1667 generate_tlb_exception(EXCEPTION_TLBLOAD, address);
1668 }
1669 else
1670 {
1671 generate_tlb_exception(EXCEPTION_TLBLOAD_FILL, address);
1672 }
1673 *result_hi = 0;
1674 *result_lo = 0;
1675 return false;
1676 }
1677 return true;
1678 }
1679
1680
1681
1682 /***************************************************************************
1683 COP0 (SYSTEM) EXECUTION HANDLING
1684 ***************************************************************************/
1685
get_cop0_reg(int idx)1686 uint64_t mips3_device::get_cop0_reg(int idx)
1687 {
1688 if (idx == COP0_Count)
1689 {
1690 /* it doesn't really take 250 cycles to read this register, but it helps speed */
1691 /* up loops that hammer on it */
1692 if (m_core->icount >= MIPS3_COUNT_READ_CYCLES)
1693 m_core->icount -= MIPS3_COUNT_READ_CYCLES;
1694 else
1695 m_core->icount = 0;
1696 return (uint32_t)((total_cycles() - m_core->count_zero_time) / 2);
1697 }
1698 else if (idx == COP0_Cause)
1699 {
1700 /* it doesn't really take 250 cycles to read this register, but it helps speed */
1701 /* up loops that hammer on it */
1702 if (m_core->icount >= MIPS3_CAUSE_READ_CYCLES)
1703 m_core->icount -= MIPS3_CAUSE_READ_CYCLES;
1704 else
1705 m_core->icount = 0;
1706 }
1707 else if (idx == COP0_Random)
1708 {
1709 int wired = m_core->cpr[0][COP0_Wired] & 0x3f;
1710 int range = 48 - wired;
1711 if (range > 0)
1712 return ((total_cycles() - m_core->count_zero_time) % range + wired) & 0x3f;
1713 else
1714 return 47;
1715 }
1716 return m_core->cpr[0][idx];
1717 }
1718
set_cop0_reg(int idx,uint64_t val)1719 void mips3_device::set_cop0_reg(int idx, uint64_t val)
1720 {
1721 switch (idx)
1722 {
1723 case COP0_Cause:
1724 CAUSE = (CAUSE & 0xfc00) | (val & ~0xfc00);
1725 if (CAUSE & 0x300)
1726 {
1727 /* if we're in a delay slot, propogate the target PC before generating the exception */
1728 if (m_nextpc != ~0)
1729 {
1730 m_core->pc = m_nextpc;
1731 m_nextpc = ~0;
1732 }
1733 generate_exception(EXCEPTION_INTERRUPT, 0);
1734 }
1735 break;
1736
1737 case COP0_Status:
1738 {
1739 /* update interrupts and cycle counting */
1740 uint32_t diff = m_core->cpr[0][idx] ^ val;
1741 // if (val & 0xe0)
1742 // fatalerror("System set 64-bit addressing mode, SR=%08X\n", val);
1743 m_core->cpr[0][idx] = val;
1744 if (diff & 0x8000)
1745 mips3com_update_cycle_counting();
1746 check_irqs();
1747 break;
1748 }
1749
1750 case COP0_Count:
1751 m_core->cpr[0][idx] = val;
1752 m_core->count_zero_time = total_cycles() - ((uint64_t)(uint32_t)val * 2);
1753 mips3com_update_cycle_counting();
1754 break;
1755
1756 case COP0_Compare:
1757 m_core->compare_armed = 1;
1758 CAUSE &= ~0x8000;
1759 m_core->cpr[0][idx] = val & 0xffffffff;
1760 mips3com_update_cycle_counting();
1761 break;
1762
1763 case COP0_PRId:
1764 break;
1765
1766 case COP0_Config:
1767 m_core->cpr[0][idx] = (m_core->cpr[0][idx] & ~7) | (val & 7);
1768 break;
1769
1770 case COP0_EntryHi:
1771 /* if the ASID changes, remap */
1772 if ((m_core->cpr[0][idx] ^ val) & 0xff)
1773 {
1774 m_core->cpr[0][idx] = val;
1775 mips3com_asid_changed();
1776 }
1777 m_core->cpr[0][idx] = val;
1778 break;
1779
1780 default:
1781 m_core->cpr[0][idx] = val;
1782 break;
1783 }
1784 }
1785
get_cop0_creg(int idx)1786 inline uint64_t mips3_device::get_cop0_creg(int idx)
1787 {
1788 return m_core->ccr[0][idx];
1789 }
1790
set_cop0_creg(int idx,uint64_t val)1791 inline void mips3_device::set_cop0_creg(int idx, uint64_t val)
1792 {
1793 m_core->ccr[0][idx] = val;
1794 }
1795
handle_cop0(uint32_t op)1796 void mips3_device::handle_cop0(uint32_t op)
1797 {
1798 if ((SR & SR_KSU_MASK) != SR_KSU_KERNEL && !(SR & SR_COP0) && !(SR & (SR_EXL | SR_ERL)))
1799 {
1800 m_badcop_value = 0;
1801 generate_exception(EXCEPTION_BADCOP, 1);
1802 return;
1803 }
1804
1805 switch (RSREG)
1806 {
1807 case 0x00: /* MFCz */ if (RTREG) RTVAL64 = (int32_t)get_cop0_reg(RDREG); break;
1808 case 0x01: /* DMFCz */ if (RTREG) RTVAL64 = get_cop0_reg(RDREG); break;
1809 case 0x02: /* CFCz */ if (RTREG) RTVAL64 = (int32_t)get_cop0_creg(RDREG); break;
1810 case 0x04: /* MTCz */ set_cop0_reg(RDREG, RTVAL32); break;
1811 case 0x05: /* DMTCz */ set_cop0_reg(RDREG, RTVAL64); break;
1812 case 0x06: /* CTCz */ set_cop0_creg(RDREG, RTVAL32); break;
1813 case 0x08: /* BC */
1814 switch (RTREG)
1815 {
1816 case 0x00: /* BCzF */ if (!m_cf[0]) ADDPC(SIMMVAL); break;
1817 case 0x01: /* BCzF */ if (m_cf[0]) ADDPC(SIMMVAL); break;
1818 case 0x02: /* BCzFL */ invalid_instruction(op); break;
1819 case 0x03: /* BCzTL */ invalid_instruction(op); break;
1820 default: invalid_instruction(op); break;
1821 }
1822 break;
1823 case 0x10:
1824 case 0x11:
1825 case 0x12:
1826 case 0x13:
1827 case 0x14:
1828 case 0x15:
1829 case 0x16:
1830 case 0x17:
1831 case 0x18:
1832 case 0x19:
1833 case 0x1a:
1834 case 0x1b:
1835 case 0x1c:
1836 case 0x1d:
1837 case 0x1e:
1838 case 0x1f: /* COP */
1839 switch (op & 0x01ffffff)
1840 {
1841 case 0x01: /* TLBR */
1842 mips3com_tlbr();
1843 break;
1844
1845 case 0x02: /* TLBWI */
1846 mips3com_tlbwi();
1847 break;
1848
1849 case 0x06: /* TLBWR */
1850 mips3com_tlbwr();
1851 break;
1852
1853 case 0x08: /* TLBP */
1854 mips3com_tlbp();
1855 break;
1856
1857 case 0x10: /* RFE */ invalid_instruction(op); break;
1858 case 0x18: /* ERET */
1859 m_core->pc = m_core->cpr[0][COP0_EPC];
1860 SR &= ~SR_EXL;
1861 check_irqs();
1862 m_core->llbit = 0;
1863 break;
1864 case 0x20: /* WAIT */ break;
1865 default: handle_extra_cop0(op); break;
1866 }
1867 break;
1868 default: invalid_instruction(op); break;
1869 }
1870 }
1871
handle_extra_cop0(uint32_t op)1872 void mips3_device::handle_extra_cop0(uint32_t op)
1873 {
1874 invalid_instruction(op);
1875 }
1876
1877
1878 /***************************************************************************
1879 COP1 (FPU) EXECUTION HANDLING
1880 ***************************************************************************/
1881
get_cop1_reg32(int idx)1882 inline uint32_t mips3_device::get_cop1_reg32(int idx)
1883 {
1884 if (IS_FR0)
1885 return ((uint32_t *)&m_core->cpr[1][idx & 0x1E])[idx & 1];
1886 else
1887 return m_core->cpr[1][idx];
1888 }
1889
get_cop1_reg64(int idx)1890 inline uint64_t mips3_device::get_cop1_reg64(int idx)
1891 {
1892 if (IS_FR0)
1893 idx &= 0x1E;
1894 return m_core->cpr[1][idx];
1895 }
1896
set_cop1_reg32(int idx,uint32_t val)1897 inline void mips3_device::set_cop1_reg32(int idx, uint32_t val)
1898 {
1899 if (IS_FR0)
1900 ((uint32_t *)&m_core->cpr[1][idx & 0x1E])[idx & 1] = val;
1901 else
1902 m_core->cpr[1][idx] = val;
1903 }
1904
set_cop1_reg64(int idx,uint64_t val)1905 inline void mips3_device::set_cop1_reg64(int idx, uint64_t val)
1906 {
1907 if (IS_FR0)
1908 idx &= 0x1E;
1909 m_core->cpr[1][idx] = val;
1910 }
1911
get_cop1_creg(int idx)1912 inline uint64_t mips3_device::get_cop1_creg(int idx)
1913 {
1914 if (idx == 31)
1915 {
1916 uint32_t result = m_core->ccr[1][31] & ~0xfe800000;
1917 int i;
1918
1919 for (i = 0; i < 8; i++)
1920 if (m_cf[1][i])
1921 result |= 1 << fcc_shift[i];
1922 return result;
1923 }
1924 return m_core->ccr[1][idx];
1925 }
1926
set_cop1_creg(int idx,uint64_t val)1927 inline void mips3_device::set_cop1_creg(int idx, uint64_t val)
1928 {
1929 m_core->ccr[1][idx] = val;
1930 if (idx == 31)
1931 {
1932 int i;
1933
1934 for (i = 0; i < 8; i++)
1935 m_cf[1][i] = (val >> fcc_shift[i]) & 1;
1936 }
1937 }
1938
handle_cop1_fr0(uint32_t op)1939 void mips3_device::handle_cop1_fr0(uint32_t op)
1940 {
1941 double dtemp;
1942
1943 /* note: additional condition codes available on R5000 only */
1944
1945 if (!(SR & SR_COP1))
1946 {
1947 m_badcop_value = 1;
1948 generate_exception(EXCEPTION_BADCOP, 1);
1949 return;
1950 }
1951
1952 switch (RSREG)
1953 {
1954 case 0x00: /* MFCz */ if (RTREG) RTVAL64 = (int32_t)get_cop1_reg32(RDREG); break;
1955 case 0x01: /* DMFCz */ if (RTREG) RTVAL64 = get_cop1_reg64(RDREG); break;
1956 case 0x02: /* CFCz */ if (RTREG) RTVAL64 = (int32_t)get_cop1_creg(RDREG); break;
1957 case 0x04: /* MTCz */ set_cop1_reg32(RDREG, RTVAL32); break;
1958 case 0x05: /* DMTCz */ set_cop1_reg64(RDREG, RTVAL64); break;
1959 case 0x06: /* CTCz */ set_cop1_creg(RDREG, RTVAL32); break;
1960 case 0x08: /* BC */
1961 switch ((op >> 16) & 3)
1962 {
1963 case 0x00: /* BCzF */ if (!GET_FCC((op >> 18) & 7)) ADDPC(SIMMVAL); break;
1964 case 0x01: /* BCzT */ if (GET_FCC((op >> 18) & 7)) ADDPC(SIMMVAL); break;
1965 case 0x02: /* BCzFL */ if (!GET_FCC((op >> 18) & 7)) ADDPC(SIMMVAL); else m_core->pc += 4; break;
1966 case 0x03: /* BCzTL */ if (GET_FCC((op >> 18) & 7)) ADDPC(SIMMVAL); else m_core->pc += 4; break;
1967 }
1968 break;
1969 default:
1970 switch (op & 0x3f)
1971 {
1972 case 0x00:
1973 if (IS_SINGLE(op)) /* ADD.S */
1974 FDVALS_FR0 = FSVALS_FR0 + FTVALS_FR0;
1975 else /* ADD.D */
1976 FDVALD_FR0 = FSVALD_FR0 + FTVALD_FR0;
1977 break;
1978
1979 case 0x01:
1980 if (IS_SINGLE(op)) /* SUB.S */
1981 FDVALS_FR0 = FSVALS_FR0 - FTVALS_FR0;
1982 else /* SUB.D */
1983 FDVALD_FR0 = FSVALD_FR0 - FTVALD_FR0;
1984 break;
1985
1986 case 0x02:
1987 if (IS_SINGLE(op)) /* MUL.S */
1988 FDVALS_FR0 = FSVALS_FR0 * FTVALS_FR0;
1989 else /* MUL.D */
1990 FDVALD_FR0 = FSVALD_FR0 * FTVALD_FR0;
1991 break;
1992
1993 case 0x03:
1994 if (IS_SINGLE(op)) { /* DIV.S */
1995 if (FTVALW_FR0 == 0 && (COP1_FCR31 & (1 << (FCR31_ENABLE + FPE_DIV0)))) {
1996 COP1_FCR31 |= (1 << (FCR31_FLAGS + FPE_DIV0)); // Set flag
1997 COP1_FCR31 |= (1 << (FCR31_CAUSE + FPE_DIV0)); // Set cause
1998 generate_exception(EXCEPTION_FPE, 1);
1999 //machine().debug_break();
2000 }
2001 else {
2002 FDVALS_FR0 = FSVALS_FR0 / FTVALS_FR0;
2003 }
2004 }
2005 else { /* DIV.D */
2006 if (FTVALL_FR0 == 0ull && (COP1_FCR31 & (1 << (FCR31_ENABLE + FPE_DIV0)))) {
2007 COP1_FCR31 |= (1 << (FCR31_FLAGS + FPE_DIV0)); // Set flag
2008 COP1_FCR31 |= (1 << (FCR31_CAUSE + FPE_DIV0)); // Set cause
2009 generate_exception(EXCEPTION_FPE, 1);
2010 //machine().debug_break();
2011 }
2012 else {
2013 FDVALD_FR0 = FSVALD_FR0 / FTVALD_FR0;
2014 }
2015 }
2016 break;
2017
2018 case 0x04:
2019 if (IS_SINGLE(op)) /* SQRT.S */
2020 FDVALS_FR0 = sqrt(FSVALS_FR0);
2021 else /* SQRT.D */
2022 FDVALD_FR0 = sqrt(FSVALD_FR0);
2023 break;
2024
2025 case 0x05:
2026 if (IS_SINGLE(op)) /* ABS.S */
2027 FDVALS_FR0 = fabs(FSVALS_FR0);
2028 else /* ABS.D */
2029 FDVALD_FR0 = fabs(FSVALD_FR0);
2030 break;
2031
2032 case 0x06:
2033 if (IS_SINGLE(op)) /* MOV.S */
2034 FDVALS_FR0 = FSVALS_FR0;
2035 else /* MOV.D */
2036 FDVALD_FR0 = FSVALD_FR0;
2037 break;
2038
2039 case 0x07:
2040 if (IS_SINGLE(op)) /* NEG.S */
2041 FDVALS_FR0 = -FSVALS_FR0;
2042 else /* NEG.D */
2043 FDVALD_FR0 = -FSVALD_FR0;
2044 break;
2045
2046 case 0x08:
2047 if (IS_SINGLE(op)) /* ROUND.L.S */
2048 {
2049 double temp = FSVALS_FR0;
2050 if (temp < 0)
2051 temp = ceil(temp - 0.5);
2052 else
2053 temp = floor(temp + 0.5);
2054 FDVALL_FR0 = (int64_t)temp;
2055 }
2056 else /* ROUND.L.D */
2057 {
2058 double temp = FSVALD_FR0;
2059 if (temp < 0)
2060 temp = ceil(temp - 0.5);
2061 else
2062 temp = floor(temp + 0.5);
2063 FDVALL_FR0 = (int64_t)temp;
2064 }
2065 break;
2066
2067 case 0x09:
2068 if (IS_SINGLE(op)) /* TRUNC.L.S */
2069 {
2070 double temp = FSVALS_FR0;
2071 if (temp < 0)
2072 temp = ceil(temp);
2073 else
2074 temp = floor(temp);
2075 FDVALL_FR0 = (int64_t)temp;
2076 }
2077 else /* TRUNC.L.D */
2078 {
2079 double temp = FSVALD_FR0;
2080 if (temp < 0)
2081 temp = ceil(temp);
2082 else
2083 temp = floor(temp);
2084 FDVALL_FR0 = (int64_t)temp;
2085 }
2086 break;
2087
2088 case 0x0a:
2089 if (IS_SINGLE(op)) /* CEIL.L.S */
2090 dtemp = ceil(FSVALS_FR0);
2091 else /* CEIL.L.D */
2092 dtemp = ceil(FSVALD_FR0);
2093 FDVALL_FR0 = (int64_t)dtemp;
2094 break;
2095
2096 case 0x0b:
2097 if (IS_SINGLE(op)) /* FLOOR.L.S */
2098 dtemp = floor(FSVALS_FR0);
2099 else /* FLOOR.L.D */
2100 dtemp = floor(FSVALD_FR0);
2101 FDVALL_FR0 = (int64_t)dtemp;
2102 break;
2103
2104 case 0x0c:
2105 if (IS_SINGLE(op)) /* ROUND.W.S */
2106 {
2107 dtemp = FSVALS_FR0;
2108 if (dtemp < 0)
2109 dtemp = ceil(dtemp - 0.5);
2110 else
2111 dtemp = floor(dtemp + 0.5);
2112 FDVALW_FR0 = (int32_t)dtemp;
2113 }
2114 else /* ROUND.W.D */
2115 {
2116 dtemp = FSVALD_FR0;
2117 if (dtemp < 0)
2118 dtemp = ceil(dtemp - 0.5);
2119 else
2120 dtemp = floor(dtemp + 0.5);
2121 FDVALW_FR0 = (int32_t)dtemp;
2122 }
2123 break;
2124
2125 case 0x0d:
2126 if (IS_SINGLE(op)) /* TRUNC.W.S */
2127 {
2128 dtemp = FSVALS_FR0;
2129 if (dtemp < 0)
2130 dtemp = ceil(dtemp);
2131 else
2132 dtemp = floor(dtemp);
2133 FDVALW_FR0 = (int32_t)dtemp;
2134 }
2135 else /* TRUNC.W.D */
2136 {
2137 dtemp = FSVALD_FR0;
2138 if (dtemp < 0)
2139 dtemp = ceil(dtemp);
2140 else
2141 dtemp = floor(dtemp);
2142 FDVALW_FR0 = (int32_t)dtemp;
2143 }
2144 break;
2145
2146 case 0x0e:
2147 if (IS_SINGLE(op)) /* CEIL.W.S */
2148 dtemp = ceil(FSVALS_FR0);
2149 else /* CEIL.W.D */
2150 dtemp = ceil(FSVALD_FR0);
2151 FDVALW_FR0 = (int32_t)dtemp;
2152 break;
2153
2154 case 0x0f:
2155 if (IS_SINGLE(op)) /* FLOOR.W.S */
2156 dtemp = floor(FSVALS_FR0);
2157 else /* FLOOR.W.D */
2158 dtemp = floor(FSVALD_FR0);
2159 FDVALW_FR0 = (int32_t)dtemp;
2160 break;
2161
2162 case 0x11: /* R5000 */
2163 if (GET_FCC((op >> 18) & 7) == ((op >> 16) & 1))
2164 {
2165 if (IS_SINGLE(op)) /* MOVT/F.S */
2166 FDVALS_FR0 = FSVALS_FR0;
2167 else /* MOVT/F.D */
2168 FDVALD_FR0 = FSVALD_FR0;
2169 }
2170 break;
2171
2172 case 0x12: /* R5000 */
2173 if (RTVAL64 == 0)
2174 {
2175 if (IS_SINGLE(op)) /* MOVZ.S */
2176 FDVALS_FR0 = FSVALS_FR0;
2177 else /* MOVZ.D */
2178 FDVALD_FR0 = FSVALD_FR0;
2179 }
2180 break;
2181
2182 case 0x13: /* R5000 */
2183 if (RTVAL64 != 0)
2184 {
2185 if (IS_SINGLE(op)) /* MOVN.S */
2186 FDVALS_FR0 = FSVALS_FR0;
2187 else /* MOVN.D */
2188 FDVALD_FR0 = FSVALD_FR0;
2189 }
2190 break;
2191
2192 case 0x15: /* R5000 */
2193 if (IS_SINGLE(op)) /* RECIP.S */
2194 FDVALS_FR0 = 1.0f / FSVALS_FR0;
2195 else /* RECIP.D */
2196 FDVALD_FR0 = 1.0 / FSVALD_FR0;
2197 break;
2198
2199 case 0x16: /* R5000 */
2200 if (IS_SINGLE(op)) /* RSQRT.S */
2201 FDVALS_FR0 = 1.0f / sqrt(FSVALS_FR0);
2202 else /* RSQRT.D */
2203 FDVALD_FR0 = 1.0 / sqrt(FSVALD_FR0);
2204 break;
2205
2206 case 0x20:
2207 if (IS_INTEGRAL(op))
2208 {
2209 if (IS_SINGLE(op)) /* CVT.S.W */
2210 FDVALS_FR0 = (int32_t)FSVALW_FR0;
2211 else /* CVT.S.L */
2212 FDVALS_FR0 = (int64_t)FSVALL_FR0;
2213 }
2214 else /* CVT.S.D */
2215 FDVALS_FR0 = FSVALD_FR0;
2216 break;
2217
2218 case 0x21:
2219 if (IS_INTEGRAL(op))
2220 {
2221 if (IS_SINGLE(op)) /* CVT.D.W */
2222 FDVALD_FR0 = (int32_t)FSVALW_FR0;
2223 else /* CVT.D.L */
2224 FDVALD_FR0 = (int64_t)FSVALL_FR0;
2225 }
2226 else /* CVT.D.S */
2227 FDVALD_FR0 = FSVALS_FR0;
2228 break;
2229
2230 case 0x24:
2231 if (IS_SINGLE(op)) /* CVT.W.S */
2232 FDVALW_FR0 = (int32_t)FSVALS_FR0;
2233 else
2234 FDVALW_FR0 = (int32_t)FSVALD_FR0;
2235 break;
2236
2237 case 0x25:
2238 if (IS_SINGLE(op)) /* CVT.L.S */
2239 FDVALL_FR0 = (int64_t)FSVALS_FR0;
2240 else /* CVT.L.D */
2241 FDVALL_FR0 = (int64_t)FSVALD_FR0;
2242 break;
2243
2244 case 0x30:
2245 case 0x38:
2246 if (IS_SINGLE(op)) /* C.F.S */
2247 SET_FCC((op >> 8) & 7, 0);
2248 else /* C.F.D */
2249 SET_FCC((op >> 8) & 7, 0);
2250 break;
2251
2252 case 0x31:
2253 case 0x39:
2254 if (IS_SINGLE(op)) /* C.UN.S */
2255 SET_FCC((op >> 8) & 7, 0);
2256 else /* C.UN.D */
2257 SET_FCC((op >> 8) & 7, 0);
2258 break;
2259
2260 case 0x32:
2261 case 0x3a:
2262 if (IS_SINGLE(op)) /* C.EQ.S */
2263 SET_FCC((op >> 8) & 7, (FSVALS_FR0 == FTVALS_FR0));
2264 else /* C.EQ.D */
2265 SET_FCC((op >> 8) & 7, (FSVALD_FR0 == FTVALD_FR0));
2266 break;
2267
2268 case 0x33:
2269 case 0x3b:
2270 if (IS_SINGLE(op)) /* C.UEQ.S */
2271 SET_FCC((op >> 8) & 7, (FSVALS_FR0 == FTVALS_FR0));
2272 else /* C.UEQ.D */
2273 SET_FCC((op >> 8) & 7, (FSVALD_FR0 == FTVALD_FR0));
2274 break;
2275
2276 case 0x34:
2277 case 0x3c:
2278 if (IS_SINGLE(op)) /* C.OLT.S */
2279 SET_FCC((op >> 8) & 7, (FSVALS_FR0 < FTVALS_FR0));
2280 else /* C.OLT.D */
2281 SET_FCC((op >> 8) & 7, (FSVALD_FR0 < FTVALD_FR0));
2282 break;
2283
2284 case 0x35:
2285 case 0x3d:
2286 if (IS_SINGLE(op)) /* C.ULT.S */
2287 SET_FCC((op >> 8) & 7, (FSVALS_FR0 < FTVALS_FR0));
2288 else /* C.ULT.D */
2289 SET_FCC((op >> 8) & 7, (FSVALD_FR0 < FTVALD_FR0));
2290 break;
2291
2292 case 0x36:
2293 case 0x3e:
2294 if (IS_SINGLE(op)) /* C.OLE.S */
2295 SET_FCC((op >> 8) & 7, (FSVALS_FR0 <= FTVALS_FR0));
2296 else /* C.OLE.D */
2297 SET_FCC((op >> 8) & 7, (FSVALD_FR0 <= FTVALD_FR0));
2298 break;
2299
2300 case 0x37:
2301 case 0x3f:
2302 if (IS_SINGLE(op)) /* C.ULE.S */
2303 SET_FCC((op >> 8) & 7, (FSVALS_FR0 <= FTVALS_FR0));
2304 else /* C.ULE.D */
2305 SET_FCC((op >> 8) & 7, (FSVALD_FR0 <= FTVALD_FR0));
2306 break;
2307
2308 default:
2309 handle_extra_cop1(op);
2310 break;
2311 }
2312 break;
2313 }
2314 }
2315
handle_extra_cop1(uint32_t op)2316 void mips3_device::handle_extra_cop1(uint32_t op)
2317 {
2318 invalid_instruction(op);
2319 }
2320
handle_cop1_fr1(uint32_t op)2321 void mips3_device::handle_cop1_fr1(uint32_t op)
2322 {
2323 double dtemp;
2324
2325 /* note: additional condition codes available on R5000 only */
2326
2327 if (!(SR & SR_COP1))
2328 {
2329 m_badcop_value = 1;
2330 generate_exception(EXCEPTION_BADCOP, 1);
2331 return;
2332 }
2333
2334 switch (RSREG)
2335 {
2336 case 0x00: /* MFCz */ if (RTREG) RTVAL64 = (int32_t)get_cop1_reg32(RDREG); break;
2337 case 0x01: /* DMFCz */ if (RTREG) RTVAL64 = get_cop1_reg64(RDREG); break;
2338 case 0x02: /* CFCz */ if (RTREG) RTVAL64 = (int32_t)get_cop1_creg(RDREG); break;
2339 case 0x04: /* MTCz */ set_cop1_reg32(RDREG, RTVAL32); break;
2340 case 0x05: /* DMTCz */ set_cop1_reg64(RDREG, RTVAL64); break;
2341 case 0x06: /* CTCz */ set_cop1_creg(RDREG, RTVAL32); break;
2342 case 0x08: /* BC */
2343 switch ((op >> 16) & 3)
2344 {
2345 case 0x00: /* BCzF */ if (!GET_FCC((op >> 18) & 7)) ADDPC(SIMMVAL); break;
2346 case 0x01: /* BCzT */ if (GET_FCC((op >> 18) & 7)) ADDPC(SIMMVAL); break;
2347 case 0x02: /* BCzFL */ if (!GET_FCC((op >> 18) & 7)) ADDPC(SIMMVAL); else m_core->pc += 4; break;
2348 case 0x03: /* BCzTL */ if (GET_FCC((op >> 18) & 7)) ADDPC(SIMMVAL); else m_core->pc += 4; break;
2349 }
2350 break;
2351 default:
2352 switch (op & 0x3f)
2353 {
2354 case 0x00:
2355 if (IS_SINGLE(op)) /* ADD.S */
2356 FDVALS_FR1 = FSVALS_FR1 + FTVALS_FR1;
2357 else /* ADD.D */
2358 FDVALD_FR1 = FSVALD_FR1 + FTVALD_FR1;
2359 break;
2360
2361 case 0x01:
2362 if (IS_SINGLE(op)) /* SUB.S */
2363 FDVALS_FR1 = FSVALS_FR1 - FTVALS_FR1;
2364 else /* SUB.D */
2365 FDVALD_FR1 = FSVALD_FR1 - FTVALD_FR1;
2366 break;
2367
2368 case 0x02:
2369 if (IS_SINGLE(op)) /* MUL.S */
2370 FDVALS_FR1 = FSVALS_FR1 * FTVALS_FR1;
2371 else /* MUL.D */
2372 FDVALD_FR1 = FSVALD_FR1 * FTVALD_FR1;
2373 break;
2374
2375 case 0x03:
2376 if (IS_SINGLE(op)) /* DIV.S */
2377 FDVALS_FR1 = FSVALS_FR1 / FTVALS_FR1;
2378 else /* DIV.D */
2379 FDVALD_FR1 = FSVALD_FR1 / FTVALD_FR1;
2380 break;
2381
2382 case 0x04:
2383 if (IS_SINGLE(op)) /* SQRT.S */
2384 FDVALS_FR1 = sqrt(FSVALS_FR1);
2385 else /* SQRT.D */
2386 FDVALD_FR1 = sqrt(FSVALD_FR1);
2387 break;
2388
2389 case 0x05:
2390 if (IS_SINGLE(op)) /* ABS.S */
2391 FDVALS_FR1 = fabs(FSVALS_FR1);
2392 else /* ABS.D */
2393 FDVALD_FR1 = fabs(FSVALD_FR1);
2394 break;
2395
2396 case 0x06:
2397 if (IS_SINGLE(op)) /* MOV.S */
2398 FDVALS_FR1 = FSVALS_FR1;
2399 else /* MOV.D */
2400 FDVALD_FR1 = FSVALD_FR1;
2401 break;
2402
2403 case 0x07:
2404 if (IS_SINGLE(op)) /* NEG.S */
2405 FDVALS_FR1 = -FSVALS_FR1;
2406 else /* NEG.D */
2407 FDVALD_FR1 = -FSVALD_FR1;
2408 break;
2409
2410 case 0x08:
2411 if (IS_SINGLE(op)) /* ROUND.L.S */
2412 {
2413 double temp = FSVALS_FR1;
2414 if (temp < 0)
2415 temp = ceil(temp - 0.5);
2416 else
2417 temp = floor(temp + 0.5);
2418 FDVALL_FR1 = (int64_t)temp;
2419 }
2420 else /* ROUND.L.D */
2421 {
2422 double temp = FSVALD_FR1;
2423 if (temp < 0)
2424 temp = ceil(temp - 0.5);
2425 else
2426 temp = floor(temp + 0.5);
2427 FDVALL_FR1 = (int64_t)temp;
2428 }
2429 break;
2430
2431 case 0x09:
2432 if (IS_SINGLE(op)) /* TRUNC.L.S */
2433 {
2434 double temp = FSVALS_FR1;
2435 if (temp < 0)
2436 temp = ceil(temp);
2437 else
2438 temp = floor(temp);
2439 FDVALL_FR1 = (int64_t)temp;
2440 }
2441 else /* TRUNC.L.D */
2442 {
2443 double temp = FSVALD_FR1;
2444 if (temp < 0)
2445 temp = ceil(temp);
2446 else
2447 temp = floor(temp);
2448 FDVALL_FR1 = (int64_t)temp;
2449 }
2450 break;
2451
2452 case 0x0a:
2453 if (IS_SINGLE(op)) /* CEIL.L.S */
2454 dtemp = ceil(FSVALS_FR1);
2455 else /* CEIL.L.D */
2456 dtemp = ceil(FSVALD_FR1);
2457 FDVALL_FR1 = (int64_t)dtemp;
2458 break;
2459
2460 case 0x0b:
2461 if (IS_SINGLE(op)) /* FLOOR.L.S */
2462 dtemp = floor(FSVALS_FR1);
2463 else /* FLOOR.L.D */
2464 dtemp = floor(FSVALD_FR1);
2465 FDVALL_FR1 = (int64_t)dtemp;
2466 break;
2467
2468 case 0x0c:
2469 if (IS_SINGLE(op)) /* ROUND.W.S */
2470 {
2471 dtemp = FSVALS_FR1;
2472 if (dtemp < 0)
2473 dtemp = ceil(dtemp - 0.5);
2474 else
2475 dtemp = floor(dtemp + 0.5);
2476 FDVALW_FR1 = (int32_t)dtemp;
2477 }
2478 else /* ROUND.W.D */
2479 {
2480 dtemp = FSVALD_FR1;
2481 if (dtemp < 0)
2482 dtemp = ceil(dtemp - 0.5);
2483 else
2484 dtemp = floor(dtemp + 0.5);
2485 FDVALW_FR1 = (int32_t)dtemp;
2486 }
2487 break;
2488
2489 case 0x0d:
2490 if (IS_SINGLE(op)) /* TRUNC.W.S */
2491 {
2492 dtemp = FSVALS_FR1;
2493 if (dtemp < 0)
2494 dtemp = ceil(dtemp);
2495 else
2496 dtemp = floor(dtemp);
2497 FDVALW_FR1 = (int32_t)dtemp;
2498 }
2499 else /* TRUNC.W.D */
2500 {
2501 dtemp = FSVALD_FR1;
2502 if (dtemp < 0)
2503 dtemp = ceil(dtemp);
2504 else
2505 dtemp = floor(dtemp);
2506 FDVALW_FR1 = (int32_t)dtemp;
2507 }
2508 break;
2509
2510 case 0x0e:
2511 if (IS_SINGLE(op)) /* CEIL.W.S */
2512 dtemp = ceil(FSVALS_FR1);
2513 else /* CEIL.W.D */
2514 dtemp = ceil(FSVALD_FR1);
2515 FDVALW_FR1 = (int32_t)dtemp;
2516 break;
2517
2518 case 0x0f:
2519 if (IS_SINGLE(op)) /* FLOOR.W.S */
2520 dtemp = floor(FSVALS_FR1);
2521 else /* FLOOR.W.D */
2522 dtemp = floor(FSVALD_FR1);
2523 FDVALW_FR1 = (int32_t)dtemp;
2524 break;
2525
2526 case 0x11: /* R5000 */
2527 if (GET_FCC((op >> 18) & 7) == ((op >> 16) & 1))
2528 {
2529 if (IS_SINGLE(op)) /* MOVT/F.S */
2530 FDVALS_FR1 = FSVALS_FR1;
2531 else /* MOVT/F.D */
2532 FDVALD_FR1 = FSVALD_FR1;
2533 }
2534 break;
2535
2536 case 0x12: /* R5000 */
2537 if (RTVAL64 == 0)
2538 {
2539 if (IS_SINGLE(op)) /* MOVZ.S */
2540 FDVALS_FR1 = FSVALS_FR1;
2541 else /* MOVZ.D */
2542 FDVALD_FR1 = FSVALD_FR1;
2543 }
2544 break;
2545
2546 case 0x13: /* R5000 */
2547 if (RTVAL64 != 0)
2548 {
2549 if (IS_SINGLE(op)) /* MOVN.S */
2550 FDVALS_FR1 = FSVALS_FR1;
2551 else /* MOVN.D */
2552 FDVALD_FR1 = FSVALD_FR1;
2553 }
2554 break;
2555
2556 case 0x15: /* R5000 */
2557 if (IS_SINGLE(op)) /* RECIP.S */
2558 FDVALS_FR1 = 1.0f / FSVALS_FR1;
2559 else /* RECIP.D */
2560 FDVALD_FR1 = 1.0 / FSVALD_FR1;
2561 break;
2562
2563 case 0x16: /* R5000 */
2564 if (IS_SINGLE(op)) /* RSQRT.S */
2565 FDVALS_FR1 = 1.0f / sqrt(FSVALS_FR1);
2566 else /* RSQRT.D */
2567 FDVALD_FR1 = 1.0 / sqrt(FSVALD_FR1);
2568 break;
2569
2570 case 0x20:
2571 if (IS_INTEGRAL(op))
2572 {
2573 if (IS_SINGLE(op)) /* CVT.S.W */
2574 FDVALS_FR1 = (int32_t)FSVALW_FR1;
2575 else /* CVT.S.L */
2576 FDVALS_FR1 = (int64_t)FSVALL_FR1;
2577 }
2578 else /* CVT.S.D */
2579 FDVALS_FR1 = FSVALD_FR1;
2580 break;
2581
2582 case 0x21:
2583 if (IS_INTEGRAL(op))
2584 {
2585 if (IS_SINGLE(op)) /* CVT.D.W */
2586 FDVALD_FR1 = (int32_t)FSVALW_FR1;
2587 else /* CVT.D.L */
2588 FDVALD_FR1 = (int64_t)FSVALL_FR1;
2589 }
2590 else /* CVT.D.S */
2591 FDVALD_FR1 = FSVALS_FR1;
2592 break;
2593
2594 case 0x24:
2595 if (IS_SINGLE(op)) /* CVT.W.S */
2596 FDVALW_FR1 = (int32_t)FSVALS_FR1;
2597 else
2598 FDVALW_FR1 = (int32_t)FSVALD_FR1;
2599 break;
2600
2601 case 0x25:
2602 if (IS_SINGLE(op)) /* CVT.L.S */
2603 FDVALL_FR1 = (int64_t)FSVALS_FR1;
2604 else /* CVT.L.D */
2605 FDVALL_FR1 = (int64_t)FSVALD_FR1;
2606 break;
2607
2608 case 0x30:
2609 case 0x38:
2610 if (IS_SINGLE(op)) /* C.F.S */
2611 SET_FCC((op >> 8) & 7, 0);
2612 else /* C.F.D */
2613 SET_FCC((op >> 8) & 7, 0);
2614 break;
2615
2616 case 0x31:
2617 case 0x39:
2618 if (IS_SINGLE(op)) /* C.UN.S */
2619 SET_FCC((op >> 8) & 7, 0);
2620 else /* C.UN.D */
2621 SET_FCC((op >> 8) & 7, 0);
2622 break;
2623
2624 case 0x32:
2625 case 0x3a:
2626 if (IS_SINGLE(op)) /* C.EQ.S */
2627 SET_FCC((op >> 8) & 7, (FSVALS_FR1 == FTVALS_FR1));
2628 else /* C.EQ.D */
2629 SET_FCC((op >> 8) & 7, (FSVALD_FR1 == FTVALD_FR1));
2630 break;
2631
2632 case 0x33:
2633 case 0x3b:
2634 if (IS_SINGLE(op)) /* C.UEQ.S */
2635 SET_FCC((op >> 8) & 7, (FSVALS_FR1 == FTVALS_FR1));
2636 else /* C.UEQ.D */
2637 SET_FCC((op >> 8) & 7, (FSVALD_FR1 == FTVALD_FR1));
2638 break;
2639
2640 case 0x34:
2641 case 0x3c:
2642 if (IS_SINGLE(op)) /* C.OLT.S */
2643 SET_FCC((op >> 8) & 7, (FSVALS_FR1 < FTVALS_FR1));
2644 else /* C.OLT.D */
2645 SET_FCC((op >> 8) & 7, (FSVALD_FR1 < FTVALD_FR1));
2646 break;
2647
2648 case 0x35:
2649 case 0x3d:
2650 if (IS_SINGLE(op)) /* C.ULT.S */
2651 SET_FCC((op >> 8) & 7, (FSVALS_FR1 < FTVALS_FR1));
2652 else /* C.ULT.D */
2653 SET_FCC((op >> 8) & 7, (FSVALD_FR1 < FTVALD_FR1));
2654 break;
2655
2656 case 0x36:
2657 case 0x3e:
2658 if (IS_SINGLE(op)) /* C.OLE.S */
2659 SET_FCC((op >> 8) & 7, (FSVALS_FR1 <= FTVALS_FR1));
2660 else /* C.OLE.D */
2661 SET_FCC((op >> 8) & 7, (FSVALD_FR1 <= FTVALD_FR1));
2662 break;
2663
2664 case 0x37:
2665 case 0x3f:
2666 if (IS_SINGLE(op)) /* C.ULE.S */
2667 SET_FCC((op >> 8) & 7, (FSVALS_FR1 <= FTVALS_FR1));
2668 else /* C.ULE.D */
2669 SET_FCC((op >> 8) & 7, (FSVALD_FR1 <= FTVALD_FR1));
2670 break;
2671
2672 default:
2673 fprintf(stderr, "cop1 %X\n", op);
2674 break;
2675 }
2676 break;
2677 }
2678 }
2679
2680
2681
2682 /***************************************************************************
2683 COP1X (FPU EXTRA) EXECUTION HANDLING
2684 ***************************************************************************/
2685
handle_cop1x_fr0(uint32_t op)2686 void mips3_device::handle_cop1x_fr0(uint32_t op)
2687 {
2688 uint64_t temp64;
2689 uint32_t temp;
2690
2691 if (!(SR & SR_COP1))
2692 {
2693 m_badcop_value = 1;
2694 generate_exception(EXCEPTION_BADCOP, 1);
2695 return;
2696 }
2697
2698 switch (op & 0x3f)
2699 {
2700 case 0x00: /* LWXC1 */
2701 if (RWORD(RSVAL32 + RTVAL32, &temp)) FDVALW_FR0 = temp;
2702 break;
2703
2704 case 0x01: /* LDXC1 */
2705 if (RDOUBLE(RSVAL32 + RTVAL32, &temp64)) FDVALL_FR0 = temp64;
2706 break;
2707
2708 case 0x08: /* SWXC1 */
2709 WWORD(RSVAL32 + RTVAL32, get_cop1_reg32(FDREG));
2710 break;
2711
2712 case 0x09: /* SDXC1 */
2713 WDOUBLE(RSVAL32 + RTVAL32, get_cop1_reg64(FDREG));
2714 break;
2715
2716 case 0x0f: /* PREFX */
2717 break;
2718
2719 case 0x20: /* MADD.S */
2720 FDVALS_FR0 = FSVALS_FR0 * FTVALS_FR0 + FRVALS_FR0;
2721 break;
2722
2723 case 0x21: /* MADD.D */
2724 FDVALD_FR0 = FSVALD_FR0 * FTVALD_FR0 + FRVALD_FR0;
2725 break;
2726
2727 case 0x28: /* MSUB.S */
2728 FDVALS_FR0 = FSVALS_FR0 * FTVALS_FR0 - FRVALS_FR0;
2729 break;
2730
2731 case 0x29: /* MSUB.D */
2732 FDVALD_FR0 = FSVALD_FR0 * FTVALD_FR0 - FRVALD_FR0;
2733 break;
2734
2735 case 0x30: /* NMADD.S */
2736 FDVALS_FR0 = -(FSVALS_FR0 * FTVALS_FR0 + FRVALS_FR0);
2737 break;
2738
2739 case 0x31: /* NMADD.D */
2740 FDVALD_FR0 = -(FSVALD_FR0 * FTVALD_FR0 + FRVALD_FR0);
2741 break;
2742
2743 case 0x38: /* NMSUB.S */
2744 FDVALS_FR0 = -(FSVALS_FR0 * FTVALS_FR0 - FRVALS_FR0);
2745 break;
2746
2747 case 0x39: /* NMSUB.D */
2748 FDVALD_FR0 = -(FSVALD_FR0 * FTVALD_FR0 - FRVALD_FR0);
2749 break;
2750
2751 case 0x24: /* MADD.W */
2752 case 0x25: /* MADD.L */
2753 case 0x2c: /* MSUB.W */
2754 case 0x2d: /* MSUB.L */
2755 case 0x34: /* NMADD.W */
2756 case 0x35: /* NMADD.L */
2757 case 0x3c: /* NMSUB.W */
2758 case 0x3d: /* NMSUB.L */
2759 default:
2760 fprintf(stderr, "cop1x %X\n", op);
2761 break;
2762 }
2763 }
2764
handle_cop1x_fr1(uint32_t op)2765 void mips3_device::handle_cop1x_fr1(uint32_t op)
2766 {
2767 uint64_t temp64;
2768 uint32_t temp;
2769
2770 if (!(SR & SR_COP1))
2771 {
2772 m_badcop_value = 1;
2773 generate_exception(EXCEPTION_BADCOP, 1);
2774 return;
2775 }
2776
2777 switch (op & 0x3f)
2778 {
2779 case 0x00: /* LWXC1 */
2780 if (RWORD(RSVAL32 + RTVAL32, &temp)) FDVALW_FR1 = temp;
2781 break;
2782
2783 case 0x01: /* LDXC1 */
2784 if (RDOUBLE(RSVAL32 + RTVAL32, &temp64)) FDVALL_FR1 = temp64;
2785 break;
2786
2787 case 0x08: /* SWXC1 */
2788 WWORD(RSVAL32 + RTVAL32, get_cop1_reg32(FDREG));
2789 break;
2790
2791 case 0x09: /* SDXC1 */
2792 WDOUBLE(RSVAL32 + RTVAL32, get_cop1_reg64(FDREG));
2793 break;
2794
2795 case 0x0f: /* PREFX */
2796 break;
2797
2798 case 0x20: /* MADD.S */
2799 FDVALS_FR1 = FSVALS_FR1 * FTVALS_FR1 + FRVALS_FR1;
2800 break;
2801
2802 case 0x21: /* MADD.D */
2803 FDVALD_FR1 = FSVALD_FR1 * FTVALD_FR1 + FRVALD_FR1;
2804 break;
2805
2806 case 0x28: /* MSUB.S */
2807 FDVALS_FR1 = FSVALS_FR1 * FTVALS_FR1 - FRVALS_FR1;
2808 break;
2809
2810 case 0x29: /* MSUB.D */
2811 FDVALD_FR1 = FSVALD_FR1 * FTVALD_FR1 - FRVALD_FR1;
2812 break;
2813
2814 case 0x30: /* NMADD.S */
2815 FDVALS_FR1 = -(FSVALS_FR1 * FTVALS_FR1 + FRVALS_FR1);
2816 break;
2817
2818 case 0x31: /* NMADD.D */
2819 FDVALD_FR1 = -(FSVALD_FR1 * FTVALD_FR1 + FRVALD_FR1);
2820 break;
2821
2822 case 0x38: /* NMSUB.S */
2823 FDVALS_FR1 = -(FSVALS_FR1 * FTVALS_FR1 - FRVALS_FR1);
2824 break;
2825
2826 case 0x39: /* NMSUB.D */
2827 FDVALD_FR1 = -(FSVALD_FR1 * FTVALD_FR1 - FRVALD_FR1);
2828 break;
2829
2830 case 0x24: /* MADD.W */
2831 case 0x25: /* MADD.L */
2832 case 0x2c: /* MSUB.W */
2833 case 0x2d: /* MSUB.L */
2834 case 0x34: /* NMADD.W */
2835 case 0x35: /* NMADD.L */
2836 case 0x3c: /* NMSUB.W */
2837 case 0x3d: /* NMSUB.L */
2838 default:
2839 fprintf(stderr, "cop1x %X\n", op);
2840 break;
2841 }
2842 }
2843
2844
2845
2846 /***************************************************************************
2847 COP2 (CUSTOM) EXECUTION HANDLING
2848 ***************************************************************************/
2849
handle_dmfc2(uint32_t op)2850 inline void mips3_device::handle_dmfc2(uint32_t op)
2851 {
2852 if (RTREG) RTVAL64 = get_cop2_reg(RDREG);
2853 }
2854
handle_dmtc2(uint32_t op)2855 inline void mips3_device::handle_dmtc2(uint32_t op)
2856 {
2857 set_cop2_reg(RDREG, RTVAL64);
2858 }
2859
get_cop2_reg(int idx)2860 inline uint64_t mips3_device::get_cop2_reg(int idx)
2861 {
2862 return m_core->cpr[2][idx];
2863 }
2864
set_cop2_reg(int idx,uint64_t val)2865 inline void mips3_device::set_cop2_reg(int idx, uint64_t val)
2866 {
2867 m_core->cpr[2][idx] = val;
2868 }
2869
get_cop2_creg(int idx)2870 inline uint64_t mips3_device::get_cop2_creg(int idx)
2871 {
2872 return m_core->ccr[2][idx];
2873 }
2874
set_cop2_creg(int idx,uint64_t val)2875 inline void mips3_device::set_cop2_creg(int idx, uint64_t val)
2876 {
2877 m_core->vfr[idx][0] = val;
2878 }
2879
handle_dmfc2(uint32_t op)2880 inline void r5900le_device::handle_dmfc2(uint32_t op)
2881 {
2882 // QMFC2
2883 if (!RTREG)
2884 {
2885 return;
2886 }
2887 const int rt = RTREG;
2888 uint32_t rtval[4] = { 0 };
2889 uint32_t *reg = reinterpret_cast<uint32_t*>(m_core->vfr[RDREG]);
2890 for (int i = 0; i < 4; i++)
2891 {
2892 rtval[i] = reg[i];
2893 }
2894 m_core->r[rt] = ((uint64_t)rtval[1] << 32) | rtval[0];
2895 m_core->rh[rt] = ((uint64_t)rtval[3] << 32) | rtval[2];
2896 }
2897
handle_dmtc2(uint32_t op)2898 inline void r5900le_device::handle_dmtc2(uint32_t op)
2899 {
2900 // QMTC2
2901 uint32_t rt = RTREG;
2902 uint32_t rtval[4] = { (uint32_t)m_core->r[rt], (uint32_t)(m_core->r[rt] >> 32), (uint32_t)m_core->rh[rt], (uint32_t)(m_core->rh[rt] >> 32) };
2903 uint32_t *reg = reinterpret_cast<uint32_t*>(m_core->vfr[RDREG]);
2904 for (int i = 0; i < 4; i++)
2905 {
2906 reg[i] = rtval[i];
2907 }
2908 }
2909
get_cop2_reg(int idx)2910 inline uint64_t r5900le_device::get_cop2_reg(int idx)
2911 {
2912 return reinterpret_cast<uint32_t*>(m_core->vfr[idx])[0];
2913 }
2914
set_cop2_reg(int idx,uint64_t val)2915 inline void r5900le_device::set_cop2_reg(int idx, uint64_t val)
2916 {
2917 reinterpret_cast<uint32_t*>(m_core->vfr[idx])[0] = (uint32_t)val;
2918 }
2919
get_cop2_creg(int idx)2920 inline uint64_t r5900le_device::get_cop2_creg(int idx)
2921 {
2922 logerror("%s: CFC2: Getting ccr[%d] (%08x)\n", machine().describe_context(), idx, m_core->vcr[idx]);
2923 return m_core->vcr[idx];
2924 }
2925
set_cop2_creg(int idx,uint64_t val)2926 inline void r5900le_device::set_cop2_creg(int idx, uint64_t val)
2927 {
2928 if (idx < 16)
2929 {
2930 m_core->vcr[idx] = val & 0xffff;
2931 }
2932 else
2933 {
2934 logerror("%s: CTC2: Setting ccr[%d] (%08x)\n", machine().describe_context(), idx, (uint32_t)val);
2935 switch (idx)
2936 {
2937 case 16: // Status flag
2938 m_core->vcr[idx] = val & 0xf30;
2939 break;
2940
2941 case 17: // MAC flag
2942 m_core->vcr[idx] = val & 0xffff;
2943 break;
2944
2945 case 26: // TPC register
2946 m_core->vcr[idx] = val & 0xffff;
2947 logerror("%s: CTC2: Setting TPC to %08x\n", machine().describe_context(), m_core->vcr[idx]);
2948 break;
2949
2950 case 27: // CMSAR0 register
2951 m_core->vcr[idx] = val & 0xffff;
2952 logerror("%s: CTC2: Setting CMSAR0 to %08x\n", machine().describe_context(), m_core->vcr[idx]);
2953 break;
2954
2955 case 18: // clipping flag
2956 m_core->vcr[idx] = val & 0xffffff;
2957 break;
2958
2959 case 20: // R register
2960 m_core->vcr[idx] = val & 0x7fffff;
2961 break;
2962
2963 case 21: // I register
2964 case 22: // Q register
2965 m_core->vcr[idx] = val;
2966 break;
2967
2968 case 28: // FBRST register
2969 m_core->vcr[idx] = val & 0xc0c;
2970 logerror("%s: CTC2: Setting FBRST to %08x\n", machine().describe_context(), val);
2971 break;
2972
2973 case 29: // VPU-STAT register
2974 // Register is read-only
2975 break;
2976
2977 case 31: // CMSAR1 register
2978 m_core->vcr[idx] = val & 0xffff;
2979 logerror("%s: CTC2: Setting CMSAR1 to %08x\n", machine().describe_context(), m_core->vcr[idx]);
2980 // TODO: Begin execution
2981 break;
2982
2983 case 19:
2984 case 23:
2985 case 24:
2986 case 25:
2987 case 30: // reserved
2988 break;
2989
2990 default:
2991 m_core->vcr[idx] = val;
2992 break;
2993 }
2994 }
2995 }
2996
handle_cop2(uint32_t op)2997 void mips3_device::handle_cop2(uint32_t op)
2998 {
2999 if (!(SR & SR_COP2))
3000 {
3001 m_badcop_value = 2;
3002 generate_exception(EXCEPTION_BADCOP, 1);
3003 return;
3004 }
3005
3006 switch (RSREG)
3007 {
3008 case 0x00: /* MFCz */ if (RTREG) RTVAL64 = (int32_t)get_cop2_reg(RDREG); break;
3009 case 0x01: /* DMFCz */ handle_dmfc2(op); break;
3010 case 0x02: /* CFCz */ if (RTREG) RTVAL64 = (int32_t)get_cop2_creg(RDREG); break;
3011 case 0x04: /* MTCz */ set_cop2_reg(RDREG, RTVAL32); break;
3012 case 0x05: /* DMTCz */ handle_dmtc2(op); break;
3013 case 0x06: /* CTCz */ set_cop2_creg(RDREG, RTVAL32); break;
3014 case 0x08: /* BC */
3015 switch (RTREG)
3016 {
3017 case 0x00: /* BCzF */ if (!m_cf[2]) ADDPC(SIMMVAL); break;
3018 case 0x01: /* BCzT */ if (m_cf[2]) ADDPC(SIMMVAL); break;
3019 case 0x02: /* BCzFL */ invalid_instruction(op); break;
3020 case 0x03: /* BCzTL */ invalid_instruction(op); break;
3021 default: invalid_instruction(op); break;
3022 }
3023 break;
3024 default: handle_extra_cop2(op); break;
3025 }
3026 }
3027
handle_extra_cop2(uint32_t op)3028 void mips3_device::handle_extra_cop2(uint32_t op)
3029 {
3030 invalid_instruction(op);
3031 }
3032
3033
3034 /***************************************************************************
3035 VU0/1 (COP2) EXECUTION HANDLING (R5900)
3036 ***************************************************************************/
3037
handle_extra_cop2(uint32_t op)3038 void r5900le_device::handle_extra_cop2(uint32_t op)
3039 {
3040 // TODO: Flags, rounding...
3041 const int rd = (op >> 6) & 31;
3042 const int rs = (op >> 11) & 31;
3043 const int rt = (op >> 16) & 31;
3044 const int ext = ((op >> 4) & 0x7c) | (op & 3);
3045
3046 switch (op & 0x3f)
3047 {
3048 case 0x00: case 0x01: case 0x02: case 0x03: /* VADDbc */
3049 if (rd)
3050 {
3051 const uint32_t bc = op & 3;
3052 float *fs = m_core->vfr[rs];
3053 float *ft = m_core->vfr[rt];
3054 float *fd = m_core->vfr[rd];
3055 for (int field = 0; field < 4; field++)
3056 {
3057 if (BIT(op, 24-field))
3058 {
3059 fd[field] = fs[field] + ft[bc];
3060 }
3061 }
3062 }
3063 break;
3064 case 0x04: case 0x05: case 0x06: case 0x07: /* VSUBbc */
3065 if (rd)
3066 {
3067 const uint32_t bc = op & 3;
3068 float *fs = m_core->vfr[rs];
3069 float *ft = m_core->vfr[rt];
3070 float *fd = m_core->vfr[rd];
3071 for (int field = 0; field < 4; field++)
3072 {
3073 if (BIT(op, 24-field))
3074 {
3075 fd[field] = fs[field] - ft[bc];
3076 }
3077 }
3078 }
3079 break;
3080 case 0x08: case 0x09: case 0x0a: case 0x0b: /* VMADDbc */
3081 if (rd)
3082 {
3083 const uint32_t bc = op & 3;
3084 float *fs = m_core->vfr[rs];
3085 float *ft = m_core->vfr[rt];
3086 float *fd = m_core->vfr[rd];
3087 for (int field = 0; field < 4; field++)
3088 {
3089 if (BIT(op, 24-field))
3090 {
3091 fd[field] = m_core->vacc[field] + fs[field] * ft[bc];
3092 }
3093 }
3094 }
3095 break;
3096 case 0x0c: case 0x0d: case 0x0e: case 0x0f:
3097 printf("Unsupported instruction: VMSUBbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3098 case 0x10: case 0x11: case 0x12: case 0x13: /* VMAXbc */
3099 if (rd)
3100 {
3101 const uint32_t bc = op & 3;
3102 float *fs = m_core->vfr[rs];
3103 float *ft = m_core->vfr[rt];
3104 float *fd = m_core->vfr[rd];
3105 for (int field = 0; field < 4; field++)
3106 {
3107 if (BIT(op, 24-field))
3108 {
3109 fd[field] = std::fmax(fs[field], ft[bc]);
3110 }
3111 }
3112 }
3113 break;
3114 case 0x14: case 0x15: case 0x16: case 0x17: /* VMINIbc */
3115 if (rd)
3116 {
3117 const uint32_t bc = op & 3;
3118 float *fs = m_core->vfr[rs];
3119 float *ft = m_core->vfr[rt];
3120 float *fd = m_core->vfr[rd];
3121 for (int field = 0; field < 4; field++)
3122 {
3123 if (BIT(op, 24-field))
3124 {
3125 fd[field] = std::fmin(fs[field], ft[bc]);
3126 }
3127 }
3128 }
3129 break;
3130 case 0x18: case 0x19: case 0x1a: case 0x1b: /* VMULbc */
3131 if (rd)
3132 {
3133 const uint32_t bc = op & 3;
3134 float *fs = m_core->vfr[rs];
3135 float *ft = m_core->vfr[rt];
3136 float *fd = m_core->vfr[rd];
3137 for (int field = 0; field < 4; field++)
3138 {
3139 if (BIT(op, 24-field))
3140 {
3141 fd[field] = fs[field] * ft[bc];
3142 }
3143 }
3144 }
3145 break;
3146 case 0x1c: /* VMULq */
3147 if (rd)
3148 {
3149 float *fs = m_core->vfr[rs];
3150 float *ft = m_core->vfr[rt];
3151 float *fd = m_core->vfr[rd];
3152 for (int field = 0; field < 4; field++)
3153 {
3154 if (BIT(op, 24-field))
3155 {
3156 fd[field] = fs[field] * ft[field];
3157 }
3158 }
3159 }
3160 break;
3161 case 0x1d: printf("Unsupported instruction: VMAXi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3162 case 0x1e: printf("Unsupported instruction: VMULi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3163 case 0x1f: printf("Unsupported instruction: VMINIi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3164 case 0x20: /* VADDq */
3165 if (rd)
3166 {
3167 float *fs = m_core->vfr[rs];
3168 float *fd = m_core->vfr[rd];
3169 for (int field = 0; field < 4; field++)
3170 {
3171 if (BIT(op, 24-field))
3172 {
3173 fd[field] = fs[field] + *(m_core->q);
3174 }
3175 }
3176 }
3177 break;
3178 case 0x21: printf("Unsupported instruction: VMADDq @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3179 case 0x22: printf("Unsupported instruction: VADDi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3180 case 0x23: printf("Unsupported instruction: VMADDi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3181 case 0x24: printf("Unsupported instruction: VSUBq @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3182 case 0x25: printf("Unsupported instruction: VMSUBq @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3183 case 0x26: printf("Unsupported instruction: VSUBi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3184 case 0x27: printf("Unsupported instruction: VMSUBi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3185 case 0x28: /* VADD */
3186 if (rd)
3187 {
3188 float *fs = m_core->vfr[rs];
3189 float *ft = m_core->vfr[rt];
3190 float *fd = m_core->vfr[rd];
3191 for (int field = 0; field < 4; field++)
3192 {
3193 if (BIT(op, 24-field))
3194 {
3195 fd[field] = fs[field] + ft[field];
3196 }
3197 }
3198 }
3199 break;
3200 case 0x29: printf("Unsupported instruction: VMADD @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3201 case 0x2a: /* VMUL */
3202 if (rd)
3203 {
3204 float *fs = m_core->vfr[rs];
3205 float *ft = m_core->vfr[rt];
3206 float *fd = m_core->vfr[rd];
3207 for (int field = 0; field < 4; field++)
3208 {
3209 if (BIT(op, 24-field))
3210 {
3211 fd[field] = fs[field] * ft[field];
3212 }
3213 }
3214 }
3215 break;
3216 case 0x2b: printf("Unsupported instruction: VMAX @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3217 case 0x2c: /* VSUB */
3218 {
3219 if (rd)
3220 {
3221 float *fs = m_core->vfr[rs];
3222 float *ft = m_core->vfr[rt];
3223 float *fd = m_core->vfr[rd];
3224 for (int field = 0; field < 4; field++)
3225 {
3226 if (BIT(op, 24-field))
3227 {
3228 fd[field] = fs[field] - ft[field];
3229 }
3230 }
3231 }
3232 break;
3233 }
3234 case 0x2d: printf("Unsupported instruction: VMSUB @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3235 case 0x2e: /* VOPMSUB */
3236 if (rd)
3237 {
3238 float *fs = m_core->vfr[rs];
3239 float *ft = m_core->vfr[rt];
3240 float *fd = m_core->vfr[rd];
3241 fd[0] = m_core->vacc[0] - fs[1] * ft[2];
3242 fd[1] = m_core->vacc[1] - fs[2] * ft[0];
3243 fd[2] = m_core->vacc[2] - fs[0] * ft[1];
3244 }
3245 break;
3246 case 0x2f: printf("Unsupported instruction: VMINI @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3247 case 0x30:
3248 if (rd)
3249 {
3250 m_core->vcr[rd] = (m_core->vcr[rs] + m_core->vcr[rt]) & 0xffff;
3251 }
3252 break;
3253 case 0x31: printf("Unsupported instruction: VISUB @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3254 case 0x32: printf("Unsupported instruction: VIADDI @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3255 case 0x34: printf("Unsupported instruction: VIAND @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3256 case 0x35: printf("Unsupported instruction: VIOR @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3257 case 0x38: printf("Unsupported instruction: VCALLMS @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3258 case 0x39: printf("Unsupported instruction: VCALLMSR @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3259 case 0x3c: case 0x3d: case 0x3e: case 0x3f:
3260 switch (ext)
3261 {
3262 case 0x00: case 0x01: case 0x02: case 0x03:
3263 printf("Unsupported instruction: VADDAbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3264 case 0x04: case 0x05: case 0x06: case 0x07:
3265 printf("Unsupported instruction: VSUBAbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3266 case 0x08: case 0x09: case 0x0a: case 0x0b: /* VMADDAbc */
3267 if (rd)
3268 {
3269 const uint32_t bc = op & 3;
3270 float *fs = m_core->vfr[rs];
3271 float *ft = m_core->vfr[rt];
3272 for (int field = 0; field < 4; field++)
3273 {
3274 if (BIT(op, 24-field))
3275 {
3276 m_core->vacc[field] += fs[field] * ft[bc];
3277 }
3278 }
3279 }
3280 break;
3281 case 0x0c: case 0x0d: case 0x0e: case 0x0f:
3282 printf("Unsupported instruction: VMSUBAbc @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3283 case 0x10: printf("Unsupported instruction: VITOF0 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3284 case 0x11: printf("Unsupported instruction: VITOF4 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3285 case 0x12: printf("Unsupported instruction: VITOF12 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3286 case 0x13: printf("Unsupported instruction: VITOF15 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3287 case 0x14: /* VFTOI0 */
3288 if (rt)
3289 {
3290 float *fs = m_core->vfr[rs];
3291 int32_t *ft = reinterpret_cast<int32_t*>(m_core->vfr[rt]);
3292 for (int field = 0; field < 4; field++)
3293 {
3294 if (BIT(op, 24-field))
3295 {
3296 ft[field] = (int32_t)(fs[field]);
3297 }
3298 }
3299 }
3300 break;
3301 case 0x15: /* VFTOI4 */
3302 if (rt)
3303 {
3304 float *fs = m_core->vfr[rs];
3305 int32_t *ft = reinterpret_cast<int32_t*>(m_core->vfr[rt]);
3306 for (int field = 0; field < 4; field++)
3307 {
3308 if (BIT(op, 24-field))
3309 {
3310 ft[field] = (int32_t)(fs[field] * 16.0f);
3311 }
3312 }
3313 }
3314 break;
3315 case 0x16: printf("Unsupported instruction: VFTOI12 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3316 case 0x17: printf("Unsupported instruction: VFTOI15 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3317 case 0x18: case 0x19: case 0x1a: case 0x1b: /* VMULAbc */
3318 {
3319 const uint32_t bc = op & 3;
3320 float *fs = m_core->vfr[rs];
3321 float *ft = m_core->vfr[rt];
3322 for (int field = 0; field < 4; field++)
3323 {
3324 if (BIT(op, 24-field))
3325 {
3326 m_core->vacc[field] = fs[field] * ft[bc];
3327 }
3328 }
3329 }
3330 break;
3331 case 0x1c: printf("Unsupported instruction: VMULAq @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3332 case 0x1d: printf("Unsupported instruction: VABS @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3333 case 0x1e: printf("Unsupported instruction: VMULAi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3334 case 0x1f: printf("Unsupported instruction: VCLIP @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3335 case 0x20: printf("Unsupported instruction: VADDAq @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3336 case 0x21: printf("Unsupported instruction: VMADDAq @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3337 case 0x22: printf("Unsupported instruction: VADDAi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3338 case 0x23: printf("Unsupported instruction: VMADDAi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3339 case 0x24: printf("Unsupported instruction: VSUBAq @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3340 case 0x25: printf("Unsupported instruction: VMSUBAq @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3341 case 0x26: printf("Unsupported instruction: VSUBAi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3342 case 0x27: printf("Unsupported instruction: VMSUBAi @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3343 case 0x28: printf("Unsupported instruction: VADDA @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3344 case 0x29: printf("Unsupported instruction: VMADDA @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3345 case 0x2a: printf("Unsupported instruction: VMULA @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3346 // 2b?
3347 case 0x2c: printf("Unsupported instruction: VSUBA @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3348 case 0x2d: printf("Unsupported instruction: VMSUBA @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3349 case 0x2e: /* VOPMULA */
3350 {
3351 float *fs = m_core->vfr[rs];
3352 float *ft = m_core->vfr[rt];
3353 m_core->vacc[0] = fs[1] * ft[2];
3354 m_core->vacc[1] = fs[2] * ft[0];
3355 m_core->vacc[2] = fs[0] * ft[1];
3356 }
3357 break;
3358 case 0x2f: /* VNOP */
3359 break;
3360 case 0x30: /* VMOVE */
3361 if (rt)
3362 {
3363 float *fs = m_core->vfr[rs];
3364 float *ft = m_core->vfr[rt];
3365 for (int field = 0; field < 4; field++)
3366 {
3367 if (BIT(op, 24-field))
3368 {
3369 ft[field] = fs[field];
3370 }
3371 }
3372 }
3373 break;
3374 case 0x31: /* VMR32 */
3375 if (rt)
3376 {
3377 float *fs = m_core->vfr[rs];
3378 float *ft = m_core->vfr[rt];
3379 for (int field = 0; field < 4; field++)
3380 {
3381 if (BIT(op, 24-field))
3382 {
3383 ft[field] = fs[(field + 3) & 3];
3384 }
3385 }
3386 }
3387 break;
3388 // 32?
3389 // 33?
3390 case 0x34: printf("Unsupported instruction: VLQI @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3391 case 0x35: /* VSQI */
3392 {
3393 uint32_t *base = &m_core->vimem[(m_core->vcr[rt] << 2) & 0xfff];
3394 uint32_t *fs = reinterpret_cast<uint32_t*>(m_core->vfr[rs]);
3395 for (int field = 0; field < 4; field++)
3396 {
3397 if (BIT(op, 24-field))
3398 {
3399 base[field] = fs[field];
3400 }
3401 }
3402 if (rt)
3403 {
3404 m_core->vcr[rt]++;
3405 m_core->vcr[rt] &= 0xffff;
3406 }
3407 break;
3408 }
3409 case 0x36: printf("Unsupported instruction: VLQD @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3410 case 0x37: printf("Unsupported instruction: VSQD @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3411 case 0x38: /* VDIV */
3412 {
3413 const uint32_t fsf = (op >> 21) & 3;
3414 const uint32_t ftf = (op >> 23) & 3;
3415 const float *fs = m_core->vfr[rs];
3416 const float *ft = m_core->vfr[rt];
3417 const float ftval = ft[ftf];
3418 if (ftval)
3419 *(m_core->q) = fs[fsf] / ft[ftf];
3420 }
3421 break;
3422 case 0x39: /* VSQRT */
3423 {
3424 const uint32_t ftf = (op >> 23) & 3;
3425 *(m_core->q) = (float)sqrt(m_core->vfr[rt][ftf]);
3426 }
3427 break;
3428 case 0x3a: printf("Unsupported instruction: VRSQRT @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3429 case 0x3b: /* VWAITQ */
3430 // TODO: We assume Q is instantly available. Fix this!
3431 break;
3432 case 0x3c: printf("Unsupported instruction: VMTIR @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3433 case 0x3d: printf("Unsupported instruction: VMFIR @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3434 case 0x3e: printf("Unsupported instruction: VILWR @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3435 case 0x3f: /* VISWR */
3436 {
3437 const uint32_t val = m_core->vcr[rt];
3438 const uint32_t base = m_core->vcr[rs] << 2;
3439 for (int field = 0; field < 4; field++)
3440 {
3441 if (BIT(op, 24-field))
3442 {
3443 m_core->vimem[(base + field) & 0xfff] = val;
3444 }
3445 }
3446 break;
3447 }
3448 case 0x40: printf("Unsupported instruction: VRNEXT @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3449 case 0x41: printf("Unsupported instruction: VRGET @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3450 case 0x42: printf("Unsupported instruction: VRINIT @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3451 case 0x43: printf("Unsupported instruction: VRXOR @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported VU instruction\n"); break;
3452 default: invalid_instruction(op); break;
3453 }
3454 break;
3455 default:
3456 invalid_instruction(op);
3457 break;
3458 }
3459 }
3460
3461 /***************************************************************************
3462 CORE EXECUTION LOOP
3463 ***************************************************************************/
3464
handle_extra_base(uint32_t op)3465 void mips3_device::handle_extra_base(uint32_t op)
3466 {
3467 /* ??? */
3468 invalid_instruction(op);
3469 }
3470
handle_regimm(uint32_t op)3471 void mips3_device::handle_regimm(uint32_t op)
3472 {
3473 switch (RTREG)
3474 {
3475 case 0x00: /* BLTZ */ if ((int64_t)RSVAL64 < 0) ADDPC(SIMMVAL); break;
3476 case 0x01: /* BGEZ */ if ((int64_t)RSVAL64 >= 0) ADDPC(SIMMVAL); break;
3477 case 0x02: /* BLTZL */ if ((int64_t)RSVAL64 < 0) ADDPC(SIMMVAL); else m_core->pc += 4; break;
3478 case 0x03: /* BGEZL */ if ((int64_t)RSVAL64 >= 0) ADDPC(SIMMVAL); else m_core->pc += 4; break;
3479 case 0x08: /* TGEI */ if ((int64_t)RSVAL64 >= SIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
3480 case 0x09: /* TGEIU */ if (RSVAL64 >= UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
3481 case 0x0a: /* TLTI */ if ((int64_t)RSVAL64 < SIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
3482 case 0x0b: /* TLTIU */ if (RSVAL64 >= UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
3483 case 0x0c: /* TEQI */ if (RSVAL64 == UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
3484 case 0x0e: /* TNEI */ if (RSVAL64 != UIMMVAL) generate_exception(EXCEPTION_TRAP, 1); break;
3485 case 0x10: /* BLTZAL */ m_core->r[31] = (int32_t)(m_core->pc + 4); if ((int64_t)RSVAL64 < 0) ADDPC(SIMMVAL); break;
3486 case 0x11: /* BGEZAL */ m_core->r[31] = (int32_t)(m_core->pc + 4); if ((int64_t)RSVAL64 >= 0) ADDPC(SIMMVAL); break;
3487 case 0x12: /* BLTZALL */ m_core->r[31] = (int32_t)(m_core->pc + 4); if ((int64_t)RSVAL64 < 0) ADDPC(SIMMVAL); else m_core->pc += 4; break;
3488 case 0x13: /* BGEZALL */ m_core->r[31] = (int32_t)(m_core->pc + 4); if ((int64_t)RSVAL64 >= 0) ADDPC(SIMMVAL); else m_core->pc += 4; break;
3489 default: /* ??? */ handle_extra_regimm(op); break;
3490 }
3491 }
3492
handle_mult(uint32_t op)3493 void mips3_device::handle_mult(uint32_t op)
3494 {
3495 uint64_t temp64 = (int64_t)(int32_t)RSVAL32 * (int64_t)(int32_t)RTVAL32;
3496 LOVAL64 = (int32_t)temp64;
3497 HIVAL64 = (int32_t)(temp64 >> 32);
3498 m_core->icount -= 3;
3499 }
3500
handle_mult(uint32_t op)3501 void r5900le_device::handle_mult(uint32_t op)
3502 {
3503 mips3_device::handle_mult(op);
3504 if (RDREG) RDVAL64 = LOVAL64;
3505 }
3506
handle_multu(uint32_t op)3507 void mips3_device::handle_multu(uint32_t op)
3508 {
3509 uint64_t temp64 = (uint64_t)RSVAL32 * (uint64_t)RTVAL32;
3510 LOVAL64 = (int32_t)temp64;
3511 HIVAL64 = (int32_t)(temp64 >> 32);
3512 m_core->icount -= 3;
3513 }
3514
handle_multu(uint32_t op)3515 void r5900le_device::handle_multu(uint32_t op)
3516 {
3517 mips3_device::handle_multu(op);
3518 if (RDREG) RDVAL64 = LOVAL64;
3519 }
3520
handle_special(uint32_t op)3521 void mips3_device::handle_special(uint32_t op)
3522 {
3523 switch (op & 63)
3524 {
3525 case 0x00: /* SLL */ if (RDREG) RDVAL64 = (int32_t)(RTVAL32 << SHIFT); break;
3526 case 0x01: /* MOVF - R5000*/if (RDREG && GET_FCC((op >> 18) & 7) == ((op >> 16) & 1)) RDVAL64 = RSVAL64; break;
3527 case 0x02: /* SRL */ if (RDREG) RDVAL64 = (int32_t)(RTVAL32 >> SHIFT); break;
3528 case 0x03: /* SRA */ if (RDREG) RDVAL64 = (int32_t)RTVAL32 >> SHIFT; break;
3529 case 0x04: /* SLLV */ if (RDREG) RDVAL64 = (int32_t)(RTVAL32 << (RSVAL32 & 31)); break;
3530 case 0x06: /* SRLV */ if (RDREG) RDVAL64 = (int32_t)(RTVAL32 >> (RSVAL32 & 31)); break;
3531 case 0x07: /* SRAV */ if (RDREG) RDVAL64 = (int32_t)RTVAL32 >> (RSVAL32 & 31); break;
3532 case 0x08: /* JR */ SETPC(RSVAL32); break;
3533 case 0x09: /* JALR */ SETPCL(RSVAL32,RDREG); break;
3534 case 0x0a: /* MOVZ - R5000 */if (RTVAL64 == 0) { if (RDREG) RDVAL64 = RSVAL64; } break;
3535 case 0x0b: /* MOVN - R5000 */if (RTVAL64 != 0) { if (RDREG) RDVAL64 = RSVAL64; } break;
3536 case 0x0c: /* SYSCALL */ generate_exception(EXCEPTION_SYSCALL, 1); break;
3537 case 0x0d: /* BREAK */ generate_exception(EXCEPTION_BREAK, 1); break;
3538 case 0x0f: /* SYNC */ /* effective no-op */ break;
3539 case 0x10: /* MFHI */ if (RDREG) RDVAL64 = HIVAL64; break;
3540 case 0x11: /* MTHI */ HIVAL64 = RSVAL64; break;
3541 case 0x12: /* MFLO */ if (RDREG) RDVAL64 = LOVAL64; break;
3542 case 0x13: /* MTLO */ LOVAL64 = RSVAL64; break;
3543 case 0x14: /* DSLLV */ if (RDREG) RDVAL64 = RTVAL64 << (RSVAL32 & 63); break;
3544 case 0x16: /* DSRLV */ if (RDREG) RDVAL64 = RTVAL64 >> (RSVAL32 & 63); break;
3545 case 0x17: /* DSRAV */ if (RDREG) RDVAL64 = (int64_t)RTVAL64 >> (RSVAL32 & 63); break;
3546 case 0x18: /* MULT */ handle_mult(op); break;
3547 case 0x19: /* MULTU */ handle_multu(op); break;
3548 case 0x1a: /* DIV */
3549 if (RTVAL32)
3550 {
3551 LOVAL64 = (int32_t)((int32_t)RSVAL32 / (int32_t)RTVAL32);
3552 HIVAL64 = (int32_t)((int32_t)RSVAL32 % (int32_t)RTVAL32);
3553 }
3554 m_core->icount -= 35;
3555 break;
3556 case 0x1b: /* DIVU */
3557 if (RTVAL32)
3558 {
3559 LOVAL64 = (int32_t)(RSVAL32 / RTVAL32);
3560 HIVAL64 = (int32_t)(RSVAL32 % RTVAL32);
3561 }
3562 m_core->icount -= 35;
3563 break;
3564 case 0x1c: /* DMULT */
3565 LOVAL64 = mul_64x64(RSVAL64, RTVAL64, reinterpret_cast<s64 *>(&HIVAL64));
3566 m_core->icount -= 7;
3567 break;
3568 case 0x1d: /* DMULTU */
3569 LOVAL64 = mulu_64x64(RSVAL64, RTVAL64, &HIVAL64);
3570 m_core->icount -= 7;
3571 break;
3572 case 0x1e: /* DDIV */
3573 if (RTVAL64)
3574 {
3575 LOVAL64 = (int64_t)RSVAL64 / (int64_t)RTVAL64;
3576 HIVAL64 = (int64_t)RSVAL64 % (int64_t)RTVAL64;
3577 }
3578 m_core->icount -= 67;
3579 break;
3580 case 0x1f: /* DDIVU */
3581 if (RTVAL64)
3582 {
3583 LOVAL64 = RSVAL64 / RTVAL64;
3584 HIVAL64 = RSVAL64 % RTVAL64;
3585 }
3586 m_core->icount -= 67;
3587 break;
3588 case 0x20: /* ADD */
3589 if (ENABLE_OVERFLOWS && RSVAL32 > ~RTVAL32) generate_exception(EXCEPTION_OVERFLOW, 1);
3590 else if (RDREG) RDVAL64 = (int32_t)(RSVAL32 + RTVAL32);
3591 break;
3592 case 0x21: /* ADDU */ if (RDREG) RDVAL64 = (int32_t)(RSVAL32 + RTVAL32); break;
3593 case 0x22: /* SUB */
3594 if (ENABLE_OVERFLOWS && RSVAL32 < RTVAL32) generate_exception(EXCEPTION_OVERFLOW, 1);
3595 else if (RDREG) RDVAL64 = (int32_t)(RSVAL32 - RTVAL32);
3596 break;
3597 case 0x23: /* SUBU */ if (RDREG) RDVAL64 = (int32_t)(RSVAL32 - RTVAL32); break;
3598 case 0x24: /* AND */ if (RDREG) RDVAL64 = RSVAL64 & RTVAL64; break;
3599 case 0x25: /* OR */ if (RDREG) RDVAL64 = RSVAL64 | RTVAL64; break;
3600 case 0x26: /* XOR */ if (RDREG) RDVAL64 = RSVAL64 ^ RTVAL64; break;
3601 case 0x27: /* NOR */ if (RDREG) RDVAL64 = ~(RSVAL64 | RTVAL64); break;
3602 case 0x28: handle_extra_special(op); break;
3603 case 0x2a: /* SLT */ if (RDREG) RDVAL64 = (int64_t)RSVAL64 < (int64_t)RTVAL64; break;
3604 case 0x2b: /* SLTU */ if (RDREG) RDVAL64 = (uint64_t)RSVAL64 < (uint64_t)RTVAL64; break;
3605 case 0x2c: /* DADD */
3606 if (ENABLE_OVERFLOWS && RSVAL64 > ~RTVAL64) generate_exception(EXCEPTION_OVERFLOW, 1);
3607 else if (RDREG) RDVAL64 = RSVAL64 + RTVAL64;
3608 break;
3609 case 0x2d: /* DADDU */ if (RDREG) RDVAL64 = RSVAL64 + RTVAL64; break;
3610 case 0x2e: /* DSUB */
3611 if (ENABLE_OVERFLOWS && RSVAL64 < RTVAL64) generate_exception(EXCEPTION_OVERFLOW, 1);
3612 else if (RDREG) RDVAL64 = RSVAL64 - RTVAL64;
3613 break;
3614 case 0x2f: /* DSUBU */ if (RDREG) RDVAL64 = RSVAL64 - RTVAL64; break;
3615 case 0x30: /* TGE */ if ((int64_t)RSVAL64 >= (int64_t)RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break;
3616 case 0x31: /* TGEU */ if (RSVAL64 >= RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break;
3617 case 0x32: /* TLT */ if ((int64_t)RSVAL64 < (int64_t)RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break;
3618 case 0x33: /* TLTU */ if (RSVAL64 < RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break;
3619 case 0x34: /* TEQ */ if (RSVAL64 == RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break;
3620 case 0x36: /* TNE */ if (RSVAL64 != RTVAL64) generate_exception(EXCEPTION_TRAP, 1); break;
3621 case 0x38: /* DSLL */ if (RDREG) RDVAL64 = RTVAL64 << SHIFT; break;
3622 case 0x3a: /* DSRL */ if (RDREG) RDVAL64 = RTVAL64 >> SHIFT; break;
3623 case 0x3b: /* DSRA */ if (RDREG) RDVAL64 = (int64_t)RTVAL64 >> SHIFT; break;
3624 case 0x3c: /* DSLL32 */ if (RDREG) RDVAL64 = RTVAL64 << (SHIFT + 32); break;
3625 case 0x3e: /* DSRL32 */ if (RDREG) RDVAL64 = RTVAL64 >> (SHIFT + 32); break;
3626 case 0x3f: /* DSRA32 */ if (RDREG) RDVAL64 = (int64_t)RTVAL64 >> (SHIFT + 32); break;
3627 default: /* ??? */ handle_extra_special(op); break;
3628 }
3629 }
3630
handle_extra_special(uint32_t op)3631 void mips3_device::handle_extra_special(uint32_t op)
3632 {
3633 invalid_instruction(op);
3634 }
3635
handle_extra_regimm(uint32_t op)3636 void mips3_device::handle_extra_regimm(uint32_t op)
3637 {
3638 invalid_instruction(op);
3639 }
3640
handle_idt(uint32_t op)3641 void mips3_device::handle_idt(uint32_t op)
3642 {
3643 switch (op & 0x1f)
3644 {
3645 case 2: /* MUL */
3646 RDVAL64 = (int32_t)((int32_t)RSVAL32 * (int32_t)RTVAL32);
3647 m_core->icount -= 3;
3648 break;
3649 default:
3650 invalid_instruction(op);
3651 break;
3652 }
3653 }
3654
handle_extra_base(uint32_t op)3655 void r5900le_device::handle_extra_base(uint32_t op)
3656 {
3657 const int rs = (op >> 21) & 31;
3658 const int rt = (op >> 16) & 31;
3659
3660 switch (op >> 26)
3661 {
3662 case 0x1e: /* LQ */
3663 {
3664 uint64_t temp64[2];
3665 bool success = RQUAD(SIMMVAL + m_core->r[rs], &temp64[1], &temp64[0]);
3666 if (success && rt)
3667 {
3668 m_core->r[rt] = temp64[0];
3669 m_core->rh[rt] = temp64[1];
3670 }
3671 m_core->icount--;
3672 break;
3673 }
3674 case 0x1f: /* SQ */
3675 WQUAD(SIMMVAL + m_core->r[rs], m_core->rh[rt], m_core->r[rt]);
3676 m_core->icount--;
3677 break;
3678 default:
3679 invalid_instruction(op);
3680 break;
3681 }
3682 }
3683
handle_extra_special(uint32_t op)3684 void r5900le_device::handle_extra_special(uint32_t op)
3685 {
3686 const int rs = (op >> 21) & 31;
3687 const int rd = (op >> 11) & 31;
3688
3689 switch (op & 63)
3690 {
3691 case 0x28: /* MFSA */
3692 m_core->r[rd] = m_core->sa;
3693 break;
3694 case 0x29: /* MTSA */
3695 m_core->sa = (uint32_t)m_core->r[rs];
3696 break;
3697 default:
3698 invalid_instruction(op);
3699 break;
3700 }
3701 }
3702
handle_extra_regimm(uint32_t op)3703 void r5900le_device::handle_extra_regimm(uint32_t op)
3704 {
3705 switch (op & 63)
3706 {
3707 case 0x18: /* MTSAB */
3708 printf("Unsupported instruction: MTSAB @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
3709 break;
3710 case 0x19: /* MTSAH */
3711 printf("Unsupported instruction: MTSAH @%08x\n", m_core->pc - 4); fatalerror("Unsupported parallel instruction\n");
3712 break;
3713 default:
3714 invalid_instruction(op);
3715 break;
3716 }
3717 }
3718
handle_extra_cop0(uint32_t op)3719 void r5900le_device::handle_extra_cop0(uint32_t op)
3720 {
3721 switch (op & 0x01ffffff)
3722 {
3723 case 0x38: /* EI */
3724 if ((SR & (SR_EXL | SR_ERL | SR_EDI)) || ((SR & SR_KSU_MASK) == SR_KSU_KERNEL))
3725 SR |= SR_EIE;
3726 break;
3727 case 0x39: /* DI */
3728 if ((SR & (SR_EXL | SR_ERL | SR_EDI)) || ((SR & SR_KSU_MASK) == SR_KSU_KERNEL))
3729 SR &= ~SR_EIE;
3730 break;
3731 default:
3732 invalid_instruction(op);
3733 break;
3734 }
3735 }
3736
handle_extra_cop1(uint32_t op)3737 void r5900le_device::handle_extra_cop1(uint32_t op)
3738 {
3739 switch (op & 0x3f)
3740 {
3741 case 0x18: /* ADDA.S */
3742 m_core->acc = FSVALS_FR0 + FTVALS_FR0;
3743 break;
3744
3745 case 0x1c: /* MADD.S */
3746 m_core->acc += FSVALS_FR1 * FTVALS_FR1;
3747 FDVALS_FR1 = m_core->acc;
3748 break;
3749 }
3750 }
3751
handle_idt(uint32_t op)3752 void r5900le_device::handle_idt(uint32_t op)
3753 {
3754 const int rs = (op >> 21) & 31;
3755 const int rt = (op >> 16) & 31;
3756 const int rd = (op >> 11) & 31;
3757 const int sa = (op >> 6) & 31;
3758
3759 switch (op & 0x3f)
3760 {
3761 case 0x00: /* MADD */
3762 {
3763 uint64_t temp64 = (int64_t)(int32_t)RSVAL32 * (int64_t)(int32_t)RTVAL32;
3764 m_core->r[REG_LO] += (int32_t)temp64;
3765 m_core->r[REG_HI] += (int32_t)(temp64 >> 32);
3766 if (rd)
3767 m_core->r[rd] = m_core->r[REG_LO];
3768 m_core->icount -= 3; // ?
3769 break;
3770 }
3771 case 0x01: /* MADDU */
3772 printf("Unsupported instruction: MADDU @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
3773 break;
3774 case 0x04: /* PLZCW */
3775 if (rd)
3776 {
3777 const uint64_t rsval = m_core->r[rs];
3778 uint32_t count[2] = { 0 };
3779 for (uint32_t word = 0; word < 2; word++)
3780 {
3781 uint32_t value = (uint32_t)(rsval >> (word * 32));
3782 const uint32_t compare = value & (1U << 31);
3783 for (int bit = 30; bit >= 0; bit--)
3784 {
3785 value <<= 1;
3786 if ((value & (1U << 31)) == compare)
3787 count[word]++;
3788 else
3789 break;
3790 }
3791 }
3792 m_core->r[rd] = ((uint64_t)count[1] << 32) | count[0];
3793 }
3794 break;
3795 case 0x08: /* MMI0 */
3796 handle_mmi0(op);
3797 break;
3798 case 0x09: /* MMI2 */
3799 handle_mmi2(op);
3800 break;
3801 case 0x10: /* MFHI1 */
3802 if (rd)
3803 m_core->r[rd] = m_core->rh[REG_HI];
3804 break;
3805 case 0x11: /* MTHI1 */
3806 m_core->rh[REG_HI] = m_core->r[rs];
3807 break;
3808 case 0x12: /* MFLO1 */
3809 if (rd)
3810 m_core->r[rd] = m_core->rh[REG_LO];
3811 break;
3812 case 0x13: /* MTLO1 */
3813 m_core->rh[REG_LO] = m_core->r[rs];
3814 break;
3815 case 0x18: /* MULT1 */
3816 {
3817 uint64_t temp64 = (int64_t)(int32_t)RSVAL32 * (int64_t)(int32_t)RTVAL32;
3818 m_core->rh[REG_LO] = (int32_t)temp64;
3819 m_core->rh[REG_HI] = (int32_t)(temp64 >> 32);
3820 if (rd)
3821 m_core->r[rd] = m_core->rh[REG_LO];
3822 m_core->icount -= 3; // ?
3823 break;
3824 }
3825 case 0x19: /* MULTU1 */
3826 printf("Unsupported instruction: MULTU1 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
3827 break;
3828 case 0x1a: /* DIV1 */
3829 if (RTVAL32)
3830 {
3831 m_core->rh[REG_LO] = (int32_t)((int32_t)RSVAL32 / (int32_t)RTVAL32);
3832 m_core->rh[REG_HI] = (int32_t)((int32_t)RSVAL32 % (int32_t)RTVAL32);
3833 }
3834 m_core->icount -= 35; // ?
3835 break;
3836 case 0x1b: /* DIVU1 */
3837 if (RTVAL32)
3838 {
3839 m_core->rh[REG_LO] = (int32_t)(RSVAL32 / RTVAL32);
3840 m_core->rh[REG_HI] = (int32_t)(RSVAL32 % RTVAL32);
3841 }
3842 m_core->icount -= 35; // ?
3843 break;
3844 case 0x20: /* MADD1 */
3845 printf("Unsupported instruction: MADD1 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
3846 break;
3847 case 0x21: /* MADDU1 */
3848 printf("Unsupported instruction: MADDU1 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
3849 break;
3850 case 0x28: /* MMI1 */
3851 handle_mmi1(op);
3852 break;
3853 case 0x29: /* MMI3 */
3854 handle_mmi3(op);
3855 break;
3856 case 0x30: /* PMFHL */
3857 printf("Unsupported instruction: PMFHL @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
3858 break;
3859 case 0x31: /* PMTHL */
3860 printf("Unsupported instruction: PMTHL @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
3861 break;
3862 case 0x34: /* PSLLH */
3863 if (rd)
3864 {
3865 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
3866 uint64_t rdval[2] = { 0, 0 };
3867 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
3868 {
3869 for (int shift = 0; shift < 64; shift += 16)
3870 {
3871 const uint16_t rthalf = (uint16_t)(rtval[dword_idx] >> shift);
3872 const uint16_t result = rthalf << (sa & 0xf);
3873 rdval[dword_idx] |= (uint64_t)result << shift;
3874 }
3875 }
3876 m_core->rh[rd] = rdval[0];
3877 m_core->r[rd] = rdval[1];
3878 }
3879 break;
3880 case 0x36: /* PSRLH */
3881 if (rd)
3882 {
3883 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
3884 uint64_t rdval[2] = { 0, 0 };
3885 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
3886 {
3887 for (int shift = 0; shift < 64; shift += 16)
3888 {
3889 const uint16_t rthalf = (uint16_t)(rtval[dword_idx] >> shift);
3890 const uint16_t result = rthalf >> (sa & 0xf);
3891 rdval[dword_idx] |= (uint64_t)result << shift;
3892 }
3893 }
3894 m_core->rh[rd] = rdval[0];
3895 m_core->r[rd] = rdval[1];
3896 }
3897 break;
3898 case 0x37: /* PSRAH */
3899 if (rd)
3900 {
3901 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
3902 uint64_t rdval[2] = { 0, 0 };
3903 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
3904 {
3905 for (int shift = 0; shift < 64; shift += 16)
3906 {
3907 const int16_t rthalf = (int16_t)(rtval[dword_idx] >> shift);
3908 const int16_t result = rthalf >> (sa & 0xf);
3909 rdval[dword_idx] |= (uint64_t)(uint16_t)result << shift;
3910 }
3911 }
3912 m_core->rh[rd] = rdval[0];
3913 m_core->r[rd] = rdval[1];
3914 }
3915 break;
3916 case 0x3c: /* PSLLW */
3917 if (rd)
3918 {
3919 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
3920 uint64_t rdval[2] = { 0, 0 };
3921 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
3922 {
3923 for (int shift = 0; shift < 64; shift += 32)
3924 {
3925 const uint32_t rtword = (uint32_t)(rtval[dword_idx] >> shift);
3926 const uint32_t result = rtword << (sa & 0x1f);
3927 rdval[dword_idx] |= (uint64_t)(uint32_t)result << shift;
3928 }
3929 }
3930 m_core->rh[rd] = rdval[0];
3931 m_core->r[rd] = rdval[1];
3932 }
3933 break;
3934 case 0x3e: /* PSRLW */
3935 if (rd)
3936 {
3937 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
3938 uint64_t rdval[2] = { 0, 0 };
3939 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
3940 {
3941 for (int shift = 0; shift < 64; shift += 32)
3942 {
3943 const uint32_t rtword = (uint32_t)(rtval[dword_idx] >> shift);
3944 const uint32_t result = rtword >> (sa & 0x1f);
3945 rdval[dword_idx] |= (uint64_t)(uint32_t)result << shift;
3946 }
3947 }
3948 m_core->rh[rd] = rdval[0];
3949 m_core->r[rd] = rdval[1];
3950 }
3951 break;
3952 case 0x3f: /* PSRAW */
3953 if (rd)
3954 {
3955 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
3956 uint64_t rdval[2] = { 0, 0 };
3957 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
3958 {
3959 for (int shift = 0; shift < 64; shift += 32)
3960 {
3961 const int32_t rtword = (int32_t)(rtval[dword_idx] >> shift);
3962 const int32_t result = rtword >> (sa & 0x1f);
3963 rdval[dword_idx] |= (uint64_t)(uint32_t)result << shift;
3964 }
3965 }
3966 m_core->rh[rd] = rdval[0];
3967 m_core->r[rd] = rdval[1];
3968 }
3969 break;
3970 default:
3971 invalid_instruction(op);
3972 break;
3973 }
3974 }
3975
handle_mmi0(uint32_t op)3976 void r5900le_device::handle_mmi0(uint32_t op)
3977 {
3978 const int rs = (op >> 21) & 31;
3979 const int rt = (op >> 16) & 31;
3980 const int rd = (op >> 11) & 31;
3981
3982 switch ((op >> 6) & 0x1f)
3983 {
3984 case 0x00: /* PADDW */
3985 if (rd)
3986 {
3987 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
3988 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
3989 uint64_t rdval[2] = { 0, 0 };
3990 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
3991 {
3992 for (int shift = 0; shift < 64; shift += 32)
3993 {
3994 const uint32_t rsword = (uint32_t)(rsval[dword_idx] >> shift);
3995 const uint32_t rtword = (uint32_t)(rtval[dword_idx] >> shift);
3996 const uint32_t result = rsword + rtword;
3997 rdval[dword_idx] |= (uint64_t)result << shift;
3998 }
3999 }
4000 m_core->rh[rd] = rdval[0];
4001 m_core->r[rd] = rdval[1];
4002 }
4003 break;
4004 case 0x01: /* PSUBW */
4005 if (rd)
4006 {
4007 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4008 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4009 uint64_t rdval[2] = { 0, 0 };
4010 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4011 {
4012 for (int shift = 0; shift < 64; shift += 32)
4013 {
4014 const uint32_t rsword = (uint32_t)(rsval[dword_idx] >> shift);
4015 const uint32_t rtword = (uint32_t)(rtval[dword_idx] >> shift);
4016 const uint32_t result = rsword - rtword;
4017 rdval[dword_idx] |= (uint64_t)result << shift;
4018 }
4019 }
4020 m_core->rh[rd] = rdval[0];
4021 m_core->r[rd] = rdval[1];
4022 }
4023 break;
4024 case 0x02: /* PCGTW */
4025 if (rd)
4026 {
4027 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4028 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4029 uint64_t rdval[2] = { 0, 0 };
4030 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4031 {
4032 for (int word_idx = 0; word_idx < 64; word_idx += 32)
4033 {
4034 const int32_t rsword = (int32_t)(rsval[dword_idx] >> word_idx);
4035 const int32_t rtword = (int32_t)(rtval[dword_idx] >> word_idx);
4036 if (rsword > rtword)
4037 {
4038 rdval[dword_idx] |= (uint64_t)0xffffffff << word_idx;
4039 }
4040 }
4041 }
4042 m_core->rh[rd] = rdval[0];
4043 m_core->r[rd] = rdval[1];
4044 }
4045 break;
4046 case 0x03: /* PMAXW */
4047 if (rd)
4048 {
4049 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4050 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4051 uint64_t rdval[2] = { 0, 0 };
4052 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4053 {
4054 for (int shift = 0; shift < 64; shift += 32)
4055 {
4056 const int32_t rsword = (int32_t)(rsval[dword_idx] >> shift);
4057 const int32_t rtword = (int32_t)(rtval[dword_idx] >> shift);
4058 const int32_t result = (rsword > rtword) ? rsword : rtword;
4059 rdval[dword_idx] |= (uint64_t)(uint32_t)result << shift;
4060 }
4061 }
4062 m_core->rh[rd] = rdval[0];
4063 m_core->r[rd] = rdval[1];
4064 }
4065 break;
4066 case 0x04: /* PADDH */
4067 if (rd)
4068 {
4069 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4070 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4071 uint64_t rdval[2] = { 0, 0 };
4072 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4073 {
4074 for (int shift = 0; shift < 64; shift += 16)
4075 {
4076 const uint16_t rshalf = (uint16_t)(rsval[dword_idx] >> shift);
4077 const uint16_t rthalf = (uint16_t)(rtval[dword_idx] >> shift);
4078 const uint16_t result = rshalf + rthalf;
4079 rdval[dword_idx] |= (uint64_t)result << shift;
4080 }
4081 }
4082 m_core->rh[rd] = rdval[0];
4083 m_core->r[rd] = rdval[1];
4084 }
4085 break;
4086 case 0x05: /* PSUBH */
4087 if (rd)
4088 {
4089 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4090 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4091 uint64_t rdval[2] = { 0, 0 };
4092 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4093 {
4094 for (int shift = 0; shift < 64; shift += 16)
4095 {
4096 const uint16_t rshalf = (uint16_t)(rsval[dword_idx] >> shift);
4097 const uint16_t rthalf = (uint16_t)(rtval[dword_idx] >> shift);
4098 const uint16_t result = rshalf - rthalf;
4099 rdval[dword_idx] |= (uint64_t)result << shift;
4100 }
4101 }
4102 m_core->rh[rd] = rdval[0];
4103 m_core->r[rd] = rdval[1];
4104 }
4105 break;
4106 case 0x06: /* PCGTH */
4107 if (rd)
4108 {
4109 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4110 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4111 uint64_t rdval[2] = { 0, 0 };
4112 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4113 {
4114 for (int half_idx = 0; half_idx < 64; half_idx += 16)
4115 {
4116 const int16_t rshalf = (int16_t)(rsval[dword_idx] >> half_idx);
4117 const int16_t rthalf = (int16_t)(rtval[dword_idx] >> half_idx);
4118 if (rshalf > rthalf)
4119 {
4120 rdval[dword_idx] |= (uint64_t)0xffff << half_idx;
4121 }
4122 }
4123 }
4124 m_core->rh[rd] = rdval[0];
4125 m_core->r[rd] = rdval[1];
4126 }
4127 break;
4128 case 0x07: /* PMAXH */
4129 if (rd)
4130 {
4131 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4132 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4133 uint64_t rdval[2] = { 0, 0 };
4134 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4135 {
4136 for (int shift = 0; shift < 64; shift += 16)
4137 {
4138 const int16_t rshalf = (int16_t)(rsval[dword_idx] >> shift);
4139 const int16_t rthalf = (int16_t)(rtval[dword_idx] >> shift);
4140 const int16_t result = (rshalf > rthalf) ? rshalf : rthalf;
4141 rdval[dword_idx] |= (uint64_t)(uint16_t)result << shift;
4142 }
4143 }
4144 m_core->rh[rd] = rdval[0];
4145 m_core->r[rd] = rdval[1];
4146 }
4147 break;
4148 case 0x08: /* PADDB */
4149 if (rd)
4150 {
4151 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4152 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4153 uint64_t rdval[2] = { 0, 0 };
4154 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4155 {
4156 for (int byte_idx = 0; byte_idx < 64; byte_idx += 8)
4157 {
4158 const uint8_t rsbyte = (uint8_t)(rsval[dword_idx] >> byte_idx);
4159 const uint8_t rtbyte = (uint8_t)(rtval[dword_idx] >> byte_idx);
4160 const uint8_t result = rsbyte + rtbyte;
4161 rdval[dword_idx] |= (uint64_t)result << byte_idx;
4162 }
4163 }
4164 m_core->rh[rd] = rdval[0];
4165 m_core->r[rd] = rdval[1];
4166 }
4167 break;
4168 case 0x09: /* PSUBB */
4169 if (rd)
4170 {
4171 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4172 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4173 uint64_t rdval[2] = { 0, 0 };
4174 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4175 {
4176 for (int byte_idx = 0; byte_idx < 64; byte_idx += 8)
4177 {
4178 const uint8_t rsbyte = (uint8_t)(rsval[dword_idx] >> byte_idx);
4179 const uint8_t rtbyte = (uint8_t)(rtval[dword_idx] >> byte_idx);
4180 const uint8_t result = rsbyte - rtbyte;
4181 rdval[dword_idx] |= (uint64_t)result << byte_idx;
4182 }
4183 }
4184 m_core->rh[rd] = rdval[0];
4185 m_core->r[rd] = rdval[1];
4186 }
4187 break;
4188 case 0x0a: /* PCGTB */
4189 if (rd)
4190 {
4191 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4192 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4193 uint64_t rdval[2] = { 0, 0 };
4194 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4195 {
4196 for (int byte_idx = 0; byte_idx < 64; byte_idx += 8)
4197 {
4198 const int8_t rsbyte = (int8_t)(rsval[dword_idx] >> byte_idx);
4199 const int8_t rtbyte = (int8_t)(rtval[dword_idx] >> byte_idx);
4200 if (rsbyte > rtbyte)
4201 {
4202 rdval[dword_idx] |= (uint64_t)0xff << byte_idx;
4203 }
4204 }
4205 }
4206 m_core->rh[rd] = rdval[0];
4207 m_core->r[rd] = rdval[1];
4208 }
4209 break;
4210 case 0x10: /* PADDSW */
4211 if (rd)
4212 {
4213 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4214 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4215 uint64_t rdval[2] = { 0, 0 };
4216 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4217 {
4218 for (int shift = 0; shift < 64; shift += 32)
4219 {
4220 const int64_t rsword = (int64_t)(int32_t)(rsval[dword_idx] >> shift);
4221 const int64_t rtword = (int64_t)(int32_t)(rtval[dword_idx] >> shift);
4222 const int64_t result = rsword + rtword;
4223 if (result < (int32_t)0x80000000)
4224 {
4225 rdval[dword_idx] |= (uint64_t)0x80000000 << shift;
4226 }
4227 else if (result > 0x7fffffff)
4228 {
4229 rdval[dword_idx] |= (uint64_t)0x7fffffff << shift;
4230 }
4231 else
4232 {
4233 rdval[dword_idx] |= (uint64_t)(uint32_t)result << shift;
4234 }
4235 }
4236 }
4237 m_core->rh[rd] = rdval[0];
4238 m_core->r[rd] = rdval[1];
4239 }
4240 break;
4241 case 0x11: /* PSUBSW */
4242 if (rd)
4243 {
4244 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4245 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4246 uint64_t rdval[2] = { 0, 0 };
4247 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4248 {
4249 for (int shift = 0; shift < 64; shift += 32)
4250 {
4251 const int64_t rsword = (int64_t)(int32_t)(rsval[dword_idx] >> shift);
4252 const int64_t rtword = (int64_t)(int32_t)(rtval[dword_idx] >> shift);
4253 const int64_t result = rsword - rtword;
4254 if (result < (int32_t)0x80000000)
4255 {
4256 rdval[dword_idx] |= (uint64_t)0x80000000 << shift;
4257 }
4258 else if (result > 0x7fffffff)
4259 {
4260 rdval[dword_idx] |= (uint64_t)0x7fffffff << shift;
4261 }
4262 else
4263 {
4264 rdval[dword_idx] |= (uint64_t)(uint32_t)result << shift;
4265 }
4266 }
4267 }
4268 m_core->rh[rd] = rdval[0];
4269 m_core->r[rd] = rdval[1];
4270 }
4271 break;
4272 case 0x12: /* PEXTLW */
4273 {
4274 if (rd)
4275 {
4276 uint64_t rsval = m_core->r[rs];
4277 uint64_t rtval = m_core->r[rt];
4278 uint32_t rdval[4] = { (uint32_t)rtval, (uint32_t)rsval, (uint32_t)(rtval >> 32), (uint32_t)(rsval >> 32) };
4279 m_core->r[rd] = (uint64_t)rdval[1] << 32 | rdval[0];
4280 m_core->rh[rd] = (uint64_t)rdval[3] << 32 | rdval[2];
4281 }
4282 break;
4283 }
4284 case 0x13: /* PPACW */
4285 printf("Unsupported instruction: PPACW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4286 break;
4287 case 0x14: /* PADDSH */
4288 if (rd)
4289 {
4290 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4291 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4292 uint64_t rdval[2] = { 0, 0 };
4293 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4294 {
4295 for (int shift = 0; shift < 64; shift += 16)
4296 {
4297 const int32_t rshalf = (int32_t)(int16_t)(rsval[dword_idx] >> shift);
4298 const int32_t rthalf = (int32_t)(int16_t)(rtval[dword_idx] >> shift);
4299 const int32_t result = rshalf + rthalf;
4300 if (result < -32768)
4301 {
4302 rdval[dword_idx] |= (uint64_t)0x8000 << shift;
4303 }
4304 else if (result > 32767)
4305 {
4306 rdval[dword_idx] |= (uint64_t)0x7fff << shift;
4307 }
4308 else
4309 {
4310 rdval[dword_idx] |= (uint64_t)(uint16_t)result << shift;
4311 }
4312 }
4313 }
4314 m_core->rh[rd] = rdval[0];
4315 m_core->r[rd] = rdval[1];
4316 }
4317 break;
4318 case 0x15: /* PSUBSH */
4319 if (rd)
4320 {
4321 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4322 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4323 uint64_t rdval[2] = { 0, 0 };
4324 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4325 {
4326 for (int shift = 0; shift < 64; shift += 16)
4327 {
4328 const int32_t rshalf = (int32_t)(int16_t)(rsval[dword_idx] >> shift);
4329 const int32_t rthalf = (int32_t)(int16_t)(rtval[dword_idx] >> shift);
4330 const int32_t result = rshalf - rthalf;
4331 if (result < -32768)
4332 {
4333 rdval[dword_idx] |= (uint64_t)0x8000 << shift;
4334 }
4335 else if (result > 32767)
4336 {
4337 rdval[dword_idx] |= (uint64_t)0x7fff << shift;
4338 }
4339 else
4340 {
4341 rdval[dword_idx] |= (uint64_t)(uint16_t)result << shift;
4342 }
4343 }
4344 }
4345 m_core->rh[rd] = rdval[0];
4346 m_core->r[rd] = rdval[1];
4347 }
4348 break;
4349 case 0x16: /* PEXTLH */
4350 printf("Unsupported instruction: PEXTLH @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4351 break;
4352 case 0x17: /* PPACH */
4353 printf("Unsupported instruction: PPACH @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4354 break;
4355 case 0x18: /* PADDSB */
4356 if (rd)
4357 {
4358 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4359 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4360 uint64_t rdval[2] = { 0, 0 };
4361 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4362 {
4363 for (int shift = 0; shift < 64; shift += 8)
4364 {
4365 const int32_t rsbyte = (int32_t)(int8_t)(rsval[dword_idx] >> shift);
4366 const int32_t rtbyte = (int32_t)(int8_t)(rtval[dword_idx] >> shift);
4367 const int32_t result = rsbyte + rtbyte;
4368 if (result < -128)
4369 {
4370 rdval[dword_idx] |= (uint64_t)0x80 << shift;
4371 }
4372 else if (result > 127)
4373 {
4374 rdval[dword_idx] |= (uint64_t)0x7f << shift;
4375 }
4376 else
4377 {
4378 rdval[dword_idx] |= (uint64_t)(uint8_t)result << shift;
4379 }
4380 }
4381 }
4382 m_core->rh[rd] = rdval[0];
4383 m_core->r[rd] = rdval[1];
4384 }
4385 break;
4386 case 0x19: /* PSUBSB */
4387 if (rd)
4388 {
4389 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4390 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4391 uint64_t rdval[2] = { 0, 0 };
4392 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4393 {
4394 for (int shift = 0; shift < 64; shift += 8)
4395 {
4396 const int32_t rsbyte = (int32_t)(int8_t)(rsval[dword_idx] >> shift);
4397 const int32_t rtbyte = (int32_t)(int8_t)(rtval[dword_idx] >> shift);
4398 const int32_t result = rsbyte - rtbyte;
4399 if (result < -128)
4400 {
4401 rdval[dword_idx] |= (uint64_t)0x80 << shift;
4402 }
4403 else if (result >= 127)
4404 {
4405 rdval[dword_idx] |= (uint64_t)0x7f << shift;
4406 }
4407 else
4408 {
4409 rdval[dword_idx] |= (uint64_t)(uint8_t)result << shift;
4410 }
4411 }
4412 }
4413 m_core->rh[rd] = rdval[0];
4414 m_core->r[rd] = rdval[1];
4415 }
4416 break;
4417 case 0x1a: /* PEXTLB */
4418 printf("Unsupported instruction: PEXTLB @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4419 break;
4420 case 0x1b: /* PPACB */
4421 printf("Unsupported instruction: PPACB @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4422 break;
4423 case 0x1e: /* PEXT5 */
4424 printf("Unsupported instruction: PEXT5 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4425 break;
4426 case 0x1f: /* PPAC5 */
4427 printf("Unsupported instruction: PPAC5 @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4428 break;
4429 default:
4430 invalid_instruction(op);
4431 break;
4432 }
4433 }
4434
handle_mmi1(uint32_t op)4435 void r5900le_device::handle_mmi1(uint32_t op)
4436 {
4437 const int rs = (op >> 21) & 31;
4438 const int rt = (op >> 16) & 31;
4439 const int rd = (op >> 11) & 31;
4440
4441 switch ((op >> 6) & 0x1f)
4442 {
4443 case 0x01: /* PABSW */
4444 if (rd)
4445 {
4446 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4447 uint64_t rdval[2] = { 0, 0 };
4448 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4449 {
4450 for (int shift = 0; shift < 64; shift += 32)
4451 {
4452 const int32_t rtword = (int32_t)(rtval[dword_idx] >> shift);
4453 if (rtword == 0x80000000)
4454 {
4455 rdval[dword_idx] |= (uint64_t)0x7fffffff << shift;
4456 }
4457 else if (rtword < 0)
4458 {
4459 rdval[dword_idx] |= (uint64_t)(0 - rtword) << shift;
4460 }
4461 else
4462 {
4463 rdval[dword_idx] |= (uint64_t)rtword << shift;
4464 }
4465 }
4466 }
4467 m_core->rh[rd] = rdval[0];
4468 m_core->r[rd] = rdval[1];
4469 }
4470 break;
4471 case 0x02: /* PCEQW */
4472 if (rd)
4473 {
4474 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4475 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4476 uint64_t rdval[2] = { 0, 0 };
4477 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4478 {
4479 for (int word_idx = 0; word_idx < 64; word_idx += 32)
4480 {
4481 const uint32_t rsword = (uint32_t)(rsval[dword_idx] >> word_idx);
4482 const uint32_t rtword = (uint32_t)(rtval[dword_idx] >> word_idx);
4483 if (rsword == rtword)
4484 {
4485 rdval[dword_idx] |= (uint64_t)0xffffffff << word_idx;
4486 }
4487 }
4488 }
4489 m_core->rh[rd] = rdval[0];
4490 m_core->r[rd] = rdval[1];
4491 }
4492 break;
4493 case 0x03: /* PMINW */
4494 if (rd)
4495 {
4496 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4497 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4498 uint64_t rdval[2] = { 0, 0 };
4499 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4500 {
4501 for (int shift = 0; shift < 64; shift += 32)
4502 {
4503 const int32_t rsword = (int32_t)(rsval[dword_idx] >> shift);
4504 const int32_t rtword = (int32_t)(rtval[dword_idx] >> shift);
4505 const int32_t result = (rsword > rtword) ? rtword : rsword;
4506 rdval[dword_idx] |= (uint64_t)(uint32_t)result << shift;
4507 }
4508 }
4509 m_core->rh[rd] = rdval[0];
4510 m_core->r[rd] = rdval[1];
4511 }
4512 break;
4513 case 0x04: /* PADSBH */
4514 if (rd)
4515 {
4516 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4517 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4518 uint64_t rdval[2] = { 0, 0 };
4519 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4520 {
4521 for (int shift = 0; shift < 64; shift += 16)
4522 {
4523 const uint16_t rshalf = (uint16_t)(rsval[dword_idx] >> shift);
4524 const uint16_t rthalf = (uint16_t)(rtval[dword_idx] >> shift);
4525 const uint16_t result = dword_idx ? (rshalf - rthalf) : (rshalf + rthalf);
4526 rdval[dword_idx] |= (uint64_t)result << shift;
4527 }
4528 }
4529 m_core->rh[rd] = rdval[0];
4530 m_core->r[rd] = rdval[1];
4531 }
4532 break;
4533 case 0x05: /* PABSH */
4534 if (rd)
4535 {
4536 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4537 uint64_t rdval[2] = { 0, 0 };
4538 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4539 {
4540 for (int shift = 0; shift < 64; shift += 16)
4541 {
4542 const int16_t rthalf = (int16_t)(rtval[dword_idx] >> shift);
4543 if (rthalf == -32768)
4544 {
4545 rdval[dword_idx] |= (uint64_t)0x7fff << shift;
4546 }
4547 else if (rthalf < 0)
4548 {
4549 rdval[dword_idx] |= (uint64_t)(0 - rthalf) << shift;
4550 }
4551 else
4552 {
4553 rdval[dword_idx] |= (uint64_t)rthalf << shift;
4554 }
4555 }
4556 }
4557 m_core->rh[rd] = rdval[0];
4558 m_core->r[rd] = rdval[1];
4559 }
4560 break;
4561 case 0x06: /* PCEQH */
4562 if (rd)
4563 {
4564 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4565 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4566 uint64_t rdval[2] = { 0, 0 };
4567 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4568 {
4569 for (int half_idx = 0; half_idx < 64; half_idx += 16)
4570 {
4571 const uint16_t rshalf = (uint16_t)(rsval[dword_idx] >> half_idx);
4572 const uint16_t rthalf = (uint16_t)(rtval[dword_idx] >> half_idx);
4573 if (rshalf == rthalf)
4574 {
4575 rdval[dword_idx] |= (uint64_t)0xffff << half_idx;
4576 }
4577 }
4578 }
4579 m_core->rh[rd] = rdval[0];
4580 m_core->r[rd] = rdval[1];
4581 }
4582 break;
4583 case 0x07: /* PMINH */
4584 if (rd)
4585 {
4586 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4587 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4588 uint64_t rdval[2] = { 0, 0 };
4589 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4590 {
4591 for (int shift = 0; shift < 64; shift += 16)
4592 {
4593 const int16_t rshalf = (int16_t)(rsval[dword_idx] >> shift);
4594 const int16_t rthalf = (int16_t)(rtval[dword_idx] >> shift);
4595 const int16_t result = (rshalf > rthalf) ? rthalf : rshalf;
4596 rdval[dword_idx] |= (uint64_t)(uint16_t)result << shift;
4597 }
4598 }
4599 m_core->rh[rd] = rdval[0];
4600 m_core->r[rd] = rdval[1];
4601 }
4602 break;
4603 case 0x0a: /* PCEQB */
4604 if (rd)
4605 {
4606 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4607 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4608 uint64_t rdval[2] = { 0, 0 };
4609 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4610 {
4611 for (int byte_idx = 0; byte_idx < 64; byte_idx += 8)
4612 {
4613 const uint8_t rsbyte = (uint8_t)(rsval[dword_idx] >> byte_idx);
4614 const uint8_t rtbyte = (uint8_t)(rtval[dword_idx] >> byte_idx);
4615 if (rsbyte == rtbyte)
4616 {
4617 rdval[dword_idx] |= (uint64_t)0xff << byte_idx;
4618 }
4619 }
4620 }
4621 m_core->rh[rd] = rdval[0];
4622 m_core->r[rd] = rdval[1];
4623 }
4624 break;
4625 case 0x10: /* PADDUW */
4626 if (rd)
4627 {
4628 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4629 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4630 uint64_t rdval[2] = { 0, 0 };
4631 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4632 {
4633 for (int shift = 0; shift < 64; shift += 32)
4634 {
4635 const uint64_t rshalf = (uint32_t)(rsval[dword_idx] >> shift);
4636 const uint64_t rthalf = (uint32_t)(rtval[dword_idx] >> shift);
4637 const uint64_t result = rshalf + rthalf;
4638 if (result > 0xffffffff)
4639 {
4640 rdval[dword_idx] |= (uint64_t)0xffffffff << shift;
4641 }
4642 else
4643 {
4644 rdval[dword_idx] |= (uint64_t)result << shift;
4645 }
4646 }
4647 }
4648 m_core->rh[rd] = rdval[0];
4649 m_core->r[rd] = rdval[1];
4650 }
4651 break;
4652 case 0x11: /* PSUBUW */
4653 if (rd)
4654 {
4655 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4656 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4657 uint64_t rdval[2] = { 0, 0 };
4658 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4659 {
4660 for (int shift = 0; shift < 64; shift += 32)
4661 {
4662 const uint64_t rsword = (uint32_t)(rsval[dword_idx] >> shift);
4663 const uint64_t rtword = (uint32_t)(rtval[dword_idx] >> shift);
4664 const uint64_t result = rsword - rtword;
4665 if (result < 0x100000000ULL)
4666 {
4667 rdval[dword_idx] |= (uint64_t)(uint32_t)result << shift;
4668 }
4669 }
4670 }
4671 m_core->rh[rd] = rdval[0];
4672 m_core->r[rd] = rdval[1];
4673 }
4674 break;
4675 case 0x12: /* PEXTUW */
4676 if (rd)
4677 {
4678 uint64_t rsval = m_core->rh[rs];
4679 uint64_t rtval = m_core->rh[rt];
4680 m_core->rh[rd] = (rsval & 0xffffffff00000000ULL) | (rtval >> 32);
4681 m_core->r[rd] = (rtval & 0x00000000ffffffffULL) | (rsval << 32);
4682 }
4683 break;
4684 case 0x14: /* PADDUH */
4685 if (rd)
4686 {
4687 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4688 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4689 uint64_t rdval[2] = { 0, 0 };
4690 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4691 {
4692 for (int shift = 0; shift < 64; shift += 16)
4693 {
4694 const uint32_t rshalf = (uint16_t)(rsval[dword_idx] >> shift);
4695 const uint32_t rthalf = (uint16_t)(rtval[dword_idx] >> shift);
4696 const uint32_t result = rshalf + rthalf;
4697 if (result > 0xffff)
4698 {
4699 rdval[dword_idx] |= (uint64_t)0xffff << shift;
4700 }
4701 else
4702 {
4703 rdval[dword_idx] |= (uint64_t)result << shift;
4704 }
4705 }
4706 }
4707 m_core->rh[rd] = rdval[0];
4708 m_core->r[rd] = rdval[1];
4709 }
4710 break;
4711 case 0x15: /* PSUBUH */
4712 if (rd)
4713 {
4714 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4715 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4716 uint64_t rdval[2] = { 0, 0 };
4717 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4718 {
4719 for (int shift = 0; shift < 64; shift += 16)
4720 {
4721 const uint32_t rshalf = (uint16_t)(rsval[dword_idx] >> shift);
4722 const uint32_t rthalf = (uint16_t)(rtval[dword_idx] >> shift);
4723 const uint32_t result = rshalf - rthalf;
4724 if (result < 0x10000)
4725 {
4726 rdval[dword_idx] |= (uint64_t)(uint16_t)result << shift;
4727 }
4728 }
4729 }
4730 m_core->rh[rd] = rdval[0];
4731 m_core->r[rd] = rdval[1];
4732 }
4733 break;
4734 case 0x16: /* PEXTUH */
4735 printf("Unsupported instruction: PEXTUH @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4736 break;
4737 case 0x18: /* PADDUB */
4738 if (rd)
4739 {
4740 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4741 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4742 uint64_t rdval[2] = { 0, 0 };
4743 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4744 {
4745 for (int shift = 0; shift < 64; shift += 8)
4746 {
4747 const uint32_t rsbyte = (uint8_t)(rsval[dword_idx] >> shift);
4748 const uint32_t rtbyte = (uint8_t)(rtval[dword_idx] >> shift);
4749 const uint32_t result = rsbyte + rtbyte;
4750 if (result > 0xff)
4751 {
4752 rdval[dword_idx] |= (uint64_t)0xff << shift;
4753 }
4754 else
4755 {
4756 rdval[dword_idx] |= (uint64_t)result << shift;
4757 }
4758 }
4759 }
4760 m_core->rh[rd] = rdval[0];
4761 m_core->r[rd] = rdval[1];
4762 }
4763 break;
4764 case 0x19: /* PSUBUB */
4765 if (rd)
4766 {
4767 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4768 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4769 uint64_t rdval[2] = { 0, 0 };
4770 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4771 {
4772 for (int shift = 0; shift < 64; shift += 8)
4773 {
4774 const uint32_t rsbyte = (uint8_t)(rsval[dword_idx] >> shift);
4775 const uint32_t rtbyte = (uint8_t)(rtval[dword_idx] >> shift);
4776 const uint32_t result = rsbyte - rtbyte;
4777 if (result < 0x100)
4778 {
4779 rdval[dword_idx] |= (uint64_t)(uint8_t)result << shift;
4780 }
4781 }
4782 }
4783 m_core->rh[rd] = rdval[0];
4784 m_core->r[rd] = rdval[1];
4785 }
4786 break;
4787 case 0x1a: /* PEXTUB */
4788 printf("Unsupported instruction: PEXTUB @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4789 break;
4790 case 0x1b: /* QFSRV */
4791 printf("Unsupported instruction: QFSRV @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4792 break;
4793 default:
4794 invalid_instruction(op);
4795 break;
4796 }
4797 }
4798
handle_mmi2(uint32_t op)4799 void r5900le_device::handle_mmi2(uint32_t op)
4800 {
4801 const int rs = (op >> 21) & 31;
4802 const int rt = (op >> 16) & 31;
4803 const int rd = (op >> 11) & 31;
4804
4805 switch ((op >> 6) & 0x1f)
4806 {
4807 case 0x00: /* PMADDW */
4808 printf("Unsupported instruction: PMADDW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4809 break;
4810 case 0x02: /* PSLLVW */
4811 if (rd)
4812 {
4813 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4814 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4815 uint64_t rdval[2] = { 0, 0 };
4816 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4817 {
4818 const uint64_t rsword = (uint32_t)rsval[dword_idx];
4819 const uint64_t rtword = (uint32_t)rtval[dword_idx];
4820 const uint32_t result = rtword << (rsword & 0x1f);
4821 rdval[dword_idx] = (uint64_t)(int64_t)(int32_t)result;
4822 }
4823 m_core->rh[rd] = rdval[0];
4824 m_core->r[rd] = rdval[1];
4825 }
4826 break;
4827 case 0x03: /* PSRLVW */
4828 if (rd)
4829 {
4830 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4831 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4832 uint64_t rdval[2] = { 0, 0 };
4833 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4834 {
4835 const uint64_t rsword = (uint32_t)rsval[dword_idx];
4836 const uint64_t rtword = (uint32_t)rtval[dword_idx];
4837 rdval[dword_idx] = (uint64_t)(int64_t)(int32_t)(rtword >> (rsword & 0x1f));
4838 }
4839 m_core->rh[rd] = rdval[0];
4840 m_core->r[rd] = rdval[1];
4841 }
4842 break;
4843 case 0x04: /* PMSUBW */
4844 printf("Unsupported instruction: PMSUBW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4845 break;
4846 case 0x08: /* PMFHI */
4847 if (rd)
4848 {
4849 m_core->r[rd] = m_core->r[REG_HI];
4850 m_core->rh[rd] = m_core->rh[REG_HI];
4851 }
4852 break;
4853 case 0x09: /* PMFLO */
4854 if (rd)
4855 {
4856 m_core->r[rd] = m_core->r[REG_LO];
4857 m_core->rh[rd] = m_core->rh[REG_LO];
4858 }
4859 break;
4860 case 0x0a: /* PINTH */
4861 printf("Unsupported instruction: PINTH @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4862 break;
4863 case 0x0c: /* PMULTW */
4864 printf("Unsupported instruction: PMULTW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4865 break;
4866 case 0x0d: /* PDIVW */
4867 printf("Unsupported instruction: PDIVW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4868 break;
4869 case 0x0e: /* PCPYLD */
4870 if (rd)
4871 {
4872 m_core->rh[rd] = m_core->r[rs];
4873 m_core->r[rd] = m_core->r[rt];
4874 }
4875 break;
4876 case 0x10: /* PMADDH */
4877 printf("Unsupported instruction: PMADDH @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4878 break;
4879 case 0x11: /* PHMADH */
4880 printf("Unsupported instruction: PHMADH @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4881 break;
4882 case 0x12: /* PAND */
4883 if (rd)
4884 {
4885 m_core->rh[rd] = m_core->rh[rs] & m_core->rh[rt];
4886 m_core->r[rd] = m_core->r[rs] & m_core->r[rt];
4887 }
4888 break;
4889 case 0x13: /* PXOR */
4890 if (rd)
4891 {
4892 m_core->rh[rd] = m_core->rh[rs] ^ m_core->rh[rt];
4893 m_core->r[rd] = m_core->r[rs] ^ m_core->r[rt];
4894 }
4895 break;
4896 case 0x14: /* PMSUBH */
4897 printf("Unsupported instruction: PMSUBH @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4898 break;
4899 case 0x15: /* PHMSBH */
4900 printf("Unsupported instruction: PHMSBH @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4901 break;
4902 case 0x1a: /* PEXEH */
4903 printf("Unsupported instruction: PEXEH @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4904 break;
4905 case 0x1b: /* PREVH */
4906 printf("Unsupported instruction: PREVH @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4907 break;
4908 case 0x1c: /* PMULTH */
4909 printf("Unsupported instruction: PMULTH @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4910 break;
4911 case 0x1d: /* PDIVBW */
4912 printf("Unsupported instruction: PDIVBW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4913 break;
4914 case 0x1e: /* PEXEW */
4915 printf("Unsupported instruction: PEXEW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4916 break;
4917 case 0x1f: /* PROT3W */
4918 printf("Unsupported instruction: PROT3W @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4919 break;
4920 default:
4921 invalid_instruction(op);
4922 break;
4923 }
4924 }
4925
handle_mmi3(uint32_t op)4926 void r5900le_device::handle_mmi3(uint32_t op)
4927 {
4928 const int rs = (op >> 21) & 31;
4929 const int rt = (op >> 16) & 31;
4930 const int rd = (op >> 11) & 31;
4931
4932 switch ((op >> 6) & 0x1f)
4933 {
4934 case 0x00: /* PMADDUW */
4935 printf("Unsupported instruction: PMADDUW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4936 break;
4937 case 0x03: /* PSRAVW */
4938 if (rd)
4939 {
4940 const uint64_t rsval[2] = { m_core->rh[rs], m_core->r[rs] };
4941 const uint64_t rtval[2] = { m_core->rh[rt], m_core->r[rt] };
4942 uint64_t rdval[2] = { 0, 0 };
4943 for (int dword_idx = 0; dword_idx < 2; dword_idx++)
4944 {
4945 const uint32_t rsword = (uint32_t)rsval[dword_idx];
4946 const int32_t rtword = (int32_t)rtval[dword_idx];
4947 const int32_t result = rtword >> (rsword & 0x1f);
4948 rdval[dword_idx] = (uint64_t)(int64_t)result;
4949 }
4950 m_core->rh[rd] = rdval[0];
4951 m_core->r[rd] = rdval[1];
4952 }
4953 break;
4954 case 0x08: /* PMTHI */
4955 m_core->r[REG_HI] = m_core->r[rs];
4956 m_core->rh[REG_HI] = m_core->rh[rs];
4957 break;
4958 case 0x09: /* PTMLO */
4959 m_core->r[REG_LO] = m_core->r[rs];
4960 m_core->rh[REG_LO] = m_core->rh[rs];
4961 break;
4962 case 0x0a: /* PINTEH */
4963 printf("Unsupported instruction: PINTEH @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4964 break;
4965 case 0x0c: /* PMULTUW */
4966 printf("Unsupported instruction: PMULTUW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4967 break;
4968 case 0x0d: /* PDIVUW */
4969 printf("Unsupported instruction: PDIVUW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4970 break;
4971 case 0x0e: /* PCPYUD */
4972 if (rd)
4973 {
4974 m_core->rh[rd] = m_core->rh[rs];
4975 m_core->r[rd] = m_core->rh[rt];
4976 }
4977 break;
4978 case 0x12: /* POR */
4979 if (rd)
4980 {
4981 m_core->rh[rd] = m_core->rh[rs] | m_core->rh[rt];
4982 m_core->r[rd] = m_core->r[rs] | m_core->r[rt];
4983 }
4984 break;
4985 case 0x13: /* PNOR */
4986 if (rd)
4987 {
4988 m_core->rh[rd] = ~(m_core->rh[rs] | m_core->rh[rt]);
4989 m_core->r[rd] = ~(m_core->r[rs] | m_core->r[rt]);
4990 }
4991 break;
4992 case 0x1a: /* PEXCH */
4993 printf("Unsupported instruction: PEXCH @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
4994 break;
4995 case 0x1b: /* PCPYH */
4996 if (rd)
4997 {
4998 const uint16_t msh = (uint16_t)m_core->rh[rt];
4999 const uint16_t lsh = (uint16_t)m_core->r[rt];
5000 m_core->rh[rd] = msh * 0x0001000100010001ULL;
5001 m_core->r[rd] = lsh * 0x0001000100010001ULL;
5002 }
5003 m_core->icount--;
5004 break;
5005 case 0x1e: /* PEXCW */
5006 printf("Unsupported instruction: PEXCW @%08x\n", m_core->pc - 4); fflush(stdout); fatalerror("Unsupported parallel instruction\n");
5007 break;
5008 default:
5009 invalid_instruction(op);
5010 break;
5011 }
5012 }
5013
handle_ldc2(uint32_t op)5014 void mips3_device::handle_ldc2(uint32_t op)
5015 {
5016 uint64_t temp64 = 0;
5017 if (RDOUBLE(SIMMVAL+RSVAL32, &temp64)) set_cop2_reg(RTREG, temp64);
5018 }
5019
handle_sdc2(uint32_t op)5020 void mips3_device::handle_sdc2(uint32_t op)
5021 {
5022 WDOUBLE(SIMMVAL+RSVAL32, get_cop2_reg(RTREG));
5023 }
5024
handle_ldc2(uint32_t op)5025 void r5900le_device::handle_ldc2(uint32_t op)
5026 {
5027 /* LQC2 */
5028 const uint32_t base = SIMMVAL + RSVAL32;
5029 uint32_t *reg = reinterpret_cast<uint32_t*>(m_core->vfr[RTREG]);
5030 for (uint32_t i = 0; i < 4; i++)
5031 {
5032 uint32_t temp = 0;
5033 if (RWORD(base + (i << 2), &temp)) reg[i] = temp;
5034 }
5035 }
5036
handle_sdc2(uint32_t op)5037 void r5900le_device::handle_sdc2(uint32_t op)
5038 {
5039 /* SQC2 */
5040 const uint32_t base = SIMMVAL + RSVAL32;
5041 uint32_t *reg = reinterpret_cast<uint32_t*>(m_core->vfr[RTREG]);
5042 for (uint32_t i = 0; i < 4; i++)
5043 {
5044 WWORD(base + (i << 2), reg[i]);
5045 }
5046 }
5047
5048 #if ENABLE_O2_DPRINTF
5049 #include "o2dprintf.hxx"
5050 #endif
5051
execute_run()5052 void mips3_device::execute_run()
5053 {
5054 if (m_isdrc)
5055 {
5056 int execute_result;
5057
5058 /* reset the cache if dirty */
5059 if (m_drc_cache_dirty)
5060 code_flush_cache();
5061 m_drc_cache_dirty = false;
5062
5063 /* execute */
5064 do
5065 {
5066 /* run as much as we can */
5067 execute_result = m_drcuml->execute(*m_entry);
5068
5069 /* if we need to recompile, do it */
5070 if (execute_result == EXECUTE_MISSING_CODE)
5071 {
5072 code_compile_block(m_core->mode, m_core->pc);
5073 }
5074 else if (execute_result == EXECUTE_UNMAPPED_CODE)
5075 {
5076 fatalerror("Attempted to execute unmapped code at PC=%08X\n", m_core->pc);
5077 }
5078 else if (execute_result == EXECUTE_RESET_CACHE)
5079 {
5080 code_flush_cache();
5081 }
5082
5083 } while (execute_result != EXECUTE_OUT_OF_CYCLES);
5084
5085 return;
5086 }
5087
5088 /* count cycles and interrupt cycles */
5089 m_core->icount -= m_interrupt_cycles;
5090 m_interrupt_cycles = 0;
5091
5092 /* update timers & such */
5093 mips3com_update_cycle_counting();
5094
5095 /* check for IRQs */
5096 check_irqs();
5097
5098 /* core execution loop */
5099 do
5100 {
5101 uint32_t op;
5102 uint64_t temp64 = 0;
5103 uint32_t temp;
5104
5105 /* debugging */
5106 m_ppc = m_core->pc;
5107 debugger_instruction_hook(m_core->pc);
5108
5109 /* instruction fetch */
5110 if(!RWORD(m_core->pc, &op, true))
5111 {
5112 continue;
5113 }
5114
5115 /* adjust for next PC */
5116 if (m_nextpc != ~0)
5117 {
5118 /* Exceptions need to be able to see delayslot, since nextpc gets cleared before instruction execution */
5119 m_delayslot = true;
5120 m_core->pc = m_nextpc;
5121 m_nextpc = ~0;
5122 }
5123 else
5124 {
5125 m_delayslot = false;
5126 m_core->pc += 4;
5127 }
5128 /* parse the instruction */
5129 const int switch_val = (op >> 26) & 0x3f;
5130
5131 switch (switch_val)
5132 {
5133 case 0x00: /* SPECIAL */
5134 handle_special(op);
5135 break;
5136
5137 case 0x01: /* REGIMM */
5138 handle_regimm(op);
5139 break;
5140
5141 case 0x02: /* J */ ABSPC(LIMMVAL); break;
5142 case 0x03: /* JAL */
5143 ABSPCL(LIMMVAL,31);
5144 break;
5145 case 0x04: /* BEQ */ if (RSVAL64 == RTVAL64) ADDPC(SIMMVAL); break;
5146 case 0x05: /* BNE */ if (RSVAL64 != RTVAL64) ADDPC(SIMMVAL); break;
5147 case 0x06: /* BLEZ */ if ((int64_t)RSVAL64 <= 0) ADDPC(SIMMVAL); break;
5148 case 0x07: /* BGTZ */ if ((int64_t)RSVAL64 > 0) ADDPC(SIMMVAL); break;
5149 case 0x08: /* ADDI */
5150 if (ENABLE_OVERFLOWS && RSVAL32 > ~SIMMVAL) generate_exception(EXCEPTION_OVERFLOW, 1);
5151 else if (RTREG) RTVAL64 = (int32_t)(RSVAL32 + SIMMVAL);
5152 break;
5153 case 0x09: /* ADDIU */ if (RTREG) RTVAL64 = (int32_t)(RSVAL32 + SIMMVAL); break;
5154 case 0x0a: /* SLTI */ if (RTREG) RTVAL64 = (int64_t)RSVAL64 < (int64_t)SIMMVAL; break;
5155 case 0x0b: /* SLTIU */ if (RTREG) RTVAL64 = (uint64_t)RSVAL64 < (uint64_t)SIMMVAL; break;
5156 case 0x0c: /* ANDI */ if (RTREG) RTVAL64 = RSVAL64 & UIMMVAL; break;
5157 case 0x0d: /* ORI */ if (RTREG) RTVAL64 = RSVAL64 | UIMMVAL; break;
5158 case 0x0e: /* XORI */ if (RTREG) RTVAL64 = RSVAL64 ^ UIMMVAL; break;
5159 case 0x0f: /* LUI */ if (RTREG) RTVAL64 = (int32_t)(UIMMVAL << 16); break;
5160 case 0x10: /* COP0 */ handle_cop0(op); break;
5161 case 0x11: /* COP1 */
5162 if (IS_FR0)
5163 handle_cop1_fr0(op);
5164 else
5165 handle_cop1_fr1(op);
5166 break;
5167 case 0x12: /* COP2 */ handle_cop2(op); break;
5168 case 0x13: /* COP1X - R5000 */
5169 if (IS_FR0)
5170 handle_cop1x_fr0(op);
5171 else
5172 handle_cop1x_fr1(op);
5173 break;
5174 case 0x14: /* BEQL */ if (RSVAL64 == RTVAL64) ADDPC(SIMMVAL); else m_core->pc += 4; break;
5175 case 0x15: /* BNEL */ if (RSVAL64 != RTVAL64) ADDPC(SIMMVAL); else m_core->pc += 4; break;
5176 case 0x16: /* BLEZL */ if ((int64_t)RSVAL64 <= 0) ADDPC(SIMMVAL); else m_core->pc += 4; break;
5177 case 0x17: /* BGTZL */ if ((int64_t)RSVAL64 > 0) ADDPC(SIMMVAL); else m_core->pc += 4; break;
5178 case 0x18: /* DADDI */
5179 if (ENABLE_OVERFLOWS && (int64_t)RSVAL64 > ~SIMMVAL) generate_exception(EXCEPTION_OVERFLOW, 1);
5180 else if (RTREG) RTVAL64 = RSVAL64 + (int64_t)SIMMVAL;
5181 break;
5182 case 0x19: /* DADDIU */ if (RTREG) RTVAL64 = RSVAL64 + (uint64_t)SIMMVAL; break;
5183 case 0x1a: /* LDL */ (this->*m_ldl)(op); break;
5184 case 0x1b: /* LDR */ (this->*m_ldr)(op); break;
5185 case 0x1c: /* IDT-specific opcodes: mad/madu/mul on R4640/4650, msub on RC32364 */
5186 handle_idt(op);
5187 break;
5188 case 0x20: /* LB */ if (RBYTE(SIMMVAL+RSVAL32, &temp) && RTREG) RTVAL64 = (int8_t)temp; break;
5189 case 0x21: /* LH */ if (RHALF(SIMMVAL+RSVAL32, &temp) && RTREG) RTVAL64 = (int16_t)temp; break;
5190 case 0x22: /* LWL */ (this->*m_lwl)(op); break;
5191 case 0x23: /* LW */ if (RWORD(SIMMVAL+RSVAL32, &temp) && RTREG) RTVAL64 = (int32_t)temp; break;
5192 case 0x24: /* LBU */ if (RBYTE(SIMMVAL+RSVAL32, &temp) && RTREG) RTVAL64 = (uint8_t)temp; break;
5193 case 0x25: /* LHU */ if (RHALF(SIMMVAL+RSVAL32, &temp) && RTREG) RTVAL64 = (uint16_t)temp; break;
5194 case 0x26: /* LWR */ (this->*m_lwr)(op); break;
5195 case 0x27: /* LWU */ if (RWORD(SIMMVAL+RSVAL32, &temp) && RTREG) RTVAL64 = (uint32_t)temp; break;
5196 case 0x28: /* SB */ WBYTE(SIMMVAL+RSVAL32, RTVAL32); break;
5197 case 0x29: /* SH */ WHALF(SIMMVAL+RSVAL32, RTVAL32); break;
5198 case 0x2a: /* SWL */ (this->*m_swl)(op); break;
5199 case 0x2b: /* SW */ WWORD(SIMMVAL+RSVAL32, RTVAL32); break;
5200 case 0x2c: /* SDL */ (this->*m_sdl)(op); break;
5201 case 0x2d: /* SDR */ (this->*m_sdr)(op); break;
5202 case 0x2e: /* SWR */ (this->*m_swr)(op); break;
5203 case 0x2f: /* CACHE */ handle_cache(op); break;
5204 case 0x30: /* LL */
5205 if (RWORD(SIMMVAL + RSVAL32, &temp) && RTREG)
5206 {
5207 // Should actually use physical address
5208 m_core->cpr[0][COP0_LLAddr] = SIMMVAL + RSVAL32;
5209 RTVAL64 = temp;
5210 m_core->llbit = 1;
5211 if LL_BREAK
5212 machine().debug_break();
5213 break;
5214 }
5215 case 0x31: /* LWC1 */
5216 if (!(SR & SR_COP1))
5217 {
5218 m_badcop_value = 1;
5219 generate_exception(EXCEPTION_BADCOP, 1);
5220 break;
5221 }
5222 if (RWORD(SIMMVAL+RSVAL32, &temp))
5223 set_cop1_reg32(RTREG, temp);
5224 break;
5225 case 0x32: /* LWC2 */ if (RWORD(SIMMVAL+RSVAL32, &temp)) set_cop2_reg(RTREG, temp); break;
5226 case 0x33: /* PREF */ /* effective no-op */ break;
5227 case 0x34: /* LLD */
5228 if (RDOUBLE(SIMMVAL + RSVAL32, &temp64) && RTREG)
5229 {
5230 m_core->cpr[0][COP0_LLAddr] = SIMMVAL + RSVAL32;
5231 RTVAL64 = temp64;
5232 m_core->llbit = 1;
5233 if LL_BREAK
5234 machine().debug_break();
5235 break;
5236 }
5237 case 0x35: /* LDC1 */
5238 if (!(SR & SR_COP1))
5239 {
5240 m_badcop_value = 1;
5241 generate_exception(EXCEPTION_BADCOP, 1);
5242 break;
5243 }
5244 if (RDOUBLE(SIMMVAL+RSVAL32, &temp64))
5245 set_cop1_reg64(RTREG, temp64);
5246 break;
5247 case 0x36: handle_ldc2(op); break;
5248 case 0x37: /* LD */ if (RDOUBLE(SIMMVAL+RSVAL32, &temp64) && RTREG) RTVAL64 = temp64; break;
5249 case 0x38: /* SC */
5250 if (RWORD(SIMMVAL + RSVAL32, &temp) && RTREG && m_core->llbit && m_core->cpr[0][COP0_LLAddr] == SIMMVAL + RSVAL32)
5251 {
5252 WWORD(SIMMVAL + RSVAL32, RTVAL32);
5253 RTVAL64 = (uint32_t)1;
5254 }
5255 else
5256 RTVAL64 = (uint32_t)0;
5257 break;
5258 case 0x39: /* SWC1 */
5259 if (!(SR & SR_COP1))
5260 {
5261 m_badcop_value = 1;
5262 generate_exception(EXCEPTION_BADCOP, 1);
5263 break;
5264 }
5265 WWORD(SIMMVAL+RSVAL32, get_cop1_reg32(RTREG));
5266 break;
5267 case 0x3a: /* SWC2 */ WWORD(SIMMVAL+RSVAL32, get_cop2_reg(RTREG)); break;
5268 case 0x3b: /* SWC3 */ invalid_instruction(op); break;
5269 case 0x3c: /* SCD */
5270 if (RDOUBLE(SIMMVAL+RSVAL32, &temp64) && RTREG && m_core->llbit && m_core->cpr[0][COP0_LLAddr] == SIMMVAL + RSVAL32)
5271 {
5272 WDOUBLE(SIMMVAL + RSVAL32, RTVAL64);
5273 RTVAL64 = 1;
5274 }
5275 else
5276 RTVAL64 = 0;
5277 break;
5278 case 0x3d: /* SDC1 */
5279 if (!(SR & SR_COP1))
5280 {
5281 m_badcop_value = 1;
5282 generate_exception(EXCEPTION_BADCOP, 1);
5283 break;
5284 }
5285 WDOUBLE(SIMMVAL+RSVAL32, get_cop1_reg64(RTREG));
5286 break;
5287 case 0x3e: handle_sdc2(op); break;
5288 case 0x3f: /* SD */ WDOUBLE(SIMMVAL+RSVAL32, RTVAL64); break;
5289 default:
5290 handle_extra_base(op);
5291 break;
5292 }
5293
5294 #if ENABLE_EE_ELF_LOADER
5295 bool had_delay = m_delayslot;
5296 #endif
5297
5298 /* Clear this flag once instruction execution is finished, will interfere with interrupt exceptions otherwise */
5299 m_delayslot = false;
5300 m_core->icount--;
5301
5302 #if ENABLE_O2_DPRINTF
5303 if (m_core->pc == 0xbfc04d74)
5304 {
5305 do_o2_dprintf((uint32_t)m_core->r[4], (uint32_t)m_core->r[5], (uint32_t)m_core->r[6], (uint32_t)m_core->r[7], (uint32_t)m_core->r[29] + 16);
5306 }
5307 #endif
5308
5309 #if ENABLE_EE_ELF_LOADER
5310 static bool elf_loaded = false;
5311 if (had_delay && m_core->pc < 0x80000000 && m_core->pc >= 0x00100000 && !elf_loaded)
5312 {
5313 load_elf();
5314 m_core->icount = 0;
5315 elf_loaded = true;
5316 }
5317 #endif
5318 } while (m_core->icount > 0 || m_nextpc != ~0);
5319
5320 m_core->icount -= m_interrupt_cycles;
5321 m_interrupt_cycles = 0;
5322 }
5323
5324
5325
5326 /***************************************************************************
5327 COMPLEX OPCODE IMPLEMENTATIONS
5328 ***************************************************************************/
5329
lwl_be(uint32_t op)5330 void mips3_device::lwl_be(uint32_t op)
5331 {
5332 offs_t offs = SIMMVAL + RSVAL32;
5333 int shift = 8 * (offs & 3);
5334 uint32_t mask = 0xffffffffUL << shift;
5335 uint32_t temp;
5336
5337 if (RWORD_MASKED(offs & ~3, &temp, mask >> shift) && RTREG)
5338 RTVAL64 = (int32_t)((RTVAL32 & ~mask) | (temp << shift));
5339 }
5340
lwr_be(uint32_t op)5341 void mips3_device::lwr_be(uint32_t op)
5342 {
5343 offs_t offs = SIMMVAL + RSVAL32;
5344 int shift = 8 * (~offs & 3);
5345 uint32_t mask = 0xffffffffUL >> shift;
5346 uint32_t temp;
5347
5348 if (RWORD_MASKED(offs & ~3, &temp, mask << shift) && RTREG)
5349 RTVAL64 = (int32_t)((RTVAL32 & ~mask) | (temp >> shift));
5350 }
5351
ldl_be(uint32_t op)5352 void mips3_device::ldl_be(uint32_t op)
5353 {
5354 offs_t offs = SIMMVAL + RSVAL32;
5355 int shift = 8 * (offs & 7);
5356 uint64_t mask = 0xffffffffffffffffU << shift;
5357 uint64_t temp;
5358
5359 if (RDOUBLE_MASKED(offs & ~7, &temp, mask >> shift) && RTREG)
5360 RTVAL64 = (RTVAL64 & ~mask) | (temp << shift);
5361 }
5362
ldr_be(uint32_t op)5363 void mips3_device::ldr_be(uint32_t op)
5364 {
5365 offs_t offs = SIMMVAL + RSVAL32;
5366 int shift = 8 * (~offs & 7);
5367 uint64_t mask = 0xffffffffffffffffU >> shift;
5368 uint64_t temp;
5369
5370 if (RDOUBLE_MASKED(offs & ~7, &temp, mask << shift) && RTREG)
5371 RTVAL64 = (RTVAL64 & ~mask) | (temp >> shift);
5372 }
5373
swl_be(uint32_t op)5374 void mips3_device::swl_be(uint32_t op)
5375 {
5376 offs_t offs = SIMMVAL + RSVAL32;
5377 int shift = 8 * (offs & 3);
5378 uint32_t mask = 0xffffffffUL >> shift;
5379 WWORD_MASKED(offs & ~3, RTVAL32 >> shift, mask);
5380 }
5381
swr_be(uint32_t op)5382 void mips3_device::swr_be(uint32_t op)
5383 {
5384 offs_t offs = SIMMVAL + RSVAL32;
5385 int shift = 8 * (~offs & 3);
5386 uint32_t mask = 0xffffffffUL << shift;
5387 WWORD_MASKED(offs & ~3, RTVAL32 << shift, mask);
5388 }
5389
sdl_be(uint32_t op)5390 void mips3_device::sdl_be(uint32_t op)
5391 {
5392 offs_t offs = SIMMVAL + RSVAL32;
5393 int shift = 8 * (offs & 7);
5394 uint64_t mask = 0xffffffffffffffffU >> shift;
5395 WDOUBLE_MASKED(offs & ~7, RTVAL64 >> shift, mask);
5396 }
5397
sdr_be(uint32_t op)5398 void mips3_device::sdr_be(uint32_t op)
5399 {
5400 offs_t offs = SIMMVAL + RSVAL32;
5401 int shift = 8 * (~offs & 7);
5402 uint64_t mask = 0xffffffffffffffffU << shift;
5403 WDOUBLE_MASKED(offs & ~7, RTVAL64 << shift, mask);
5404 }
5405
5406
5407
lwl_le(uint32_t op)5408 void mips3_device::lwl_le(uint32_t op)
5409 {
5410 offs_t offs = SIMMVAL + RSVAL32;
5411 int shift = 8 * (~offs & 3);
5412 uint32_t mask = 0xffffffffUL << shift;
5413 uint32_t temp;
5414
5415 if (RWORD_MASKED(offs & ~3, &temp, mask >> shift) && RTREG)
5416 RTVAL64 = (int32_t)((RTVAL32 & ~mask) | (temp << shift));
5417 }
5418
lwr_le(uint32_t op)5419 void mips3_device::lwr_le(uint32_t op)
5420 {
5421 offs_t offs = SIMMVAL + RSVAL32;
5422 int shift = 8 * (offs & 3);
5423 uint32_t mask = 0xffffffffUL >> shift;
5424 uint32_t temp;
5425
5426 if (RWORD_MASKED(offs & ~3, &temp, mask << shift) && RTREG)
5427 RTVAL64 = (int32_t)((RTVAL32 & ~mask) | (temp >> shift));
5428 }
5429
ldl_le(uint32_t op)5430 void mips3_device::ldl_le(uint32_t op)
5431 {
5432 offs_t offs = SIMMVAL + RSVAL32;
5433 int shift = 8 * (~offs & 7);
5434 uint64_t mask = 0xffffffffffffffffU << shift;
5435 uint64_t temp;
5436
5437 if (RDOUBLE_MASKED(offs & ~7, &temp, mask >> shift) && RTREG)
5438 RTVAL64 = (RTVAL64 & ~mask) | (temp << shift);
5439 }
5440
ldr_le(uint32_t op)5441 void mips3_device::ldr_le(uint32_t op)
5442 {
5443 offs_t offs = SIMMVAL + RSVAL32;
5444 int shift = 8 * (offs & 7);
5445 uint64_t mask = 0xffffffffffffffffU >> shift;
5446 uint64_t temp;
5447
5448 if (RDOUBLE_MASKED(offs & ~7, &temp, mask << shift) && RTREG)
5449 RTVAL64 = (RTVAL64 & ~mask) | (temp >> shift);
5450 }
5451
swl_le(uint32_t op)5452 void mips3_device::swl_le(uint32_t op)
5453 {
5454 offs_t offs = SIMMVAL + RSVAL32;
5455 int shift = 8 * (~offs & 3);
5456 uint32_t mask = 0xffffffffUL >> shift;
5457 WWORD_MASKED(offs & ~3, RTVAL32 >> shift, mask);
5458 }
5459
swr_le(uint32_t op)5460 void mips3_device::swr_le(uint32_t op)
5461 {
5462 offs_t offs = SIMMVAL + RSVAL32;
5463 int shift = 8 * (offs & 3);
5464 uint32_t mask = 0xffffffffUL << shift;
5465 WWORD_MASKED(offs & ~3, RTVAL32 << shift, mask);
5466 }
5467
sdl_le(uint32_t op)5468 void mips3_device::sdl_le(uint32_t op)
5469 {
5470 offs_t offs = SIMMVAL + RSVAL32;
5471 int shift = 8 * (~offs & 7);
5472 uint64_t mask = 0xffffffffffffffffU >> shift;
5473 WDOUBLE_MASKED(offs & ~7, RTVAL64 >> shift, mask);
5474 }
5475
sdr_le(uint32_t op)5476 void mips3_device::sdr_le(uint32_t op)
5477 {
5478 offs_t offs = SIMMVAL + RSVAL32;
5479 int shift = 8 * (offs & 7);
5480 uint64_t mask = 0xffffffffffffffffU << shift;
5481 WDOUBLE_MASKED(offs & ~7, RTVAL64 << shift, mask);
5482 }
5483
load_elf()5484 void mips3_device::load_elf()
5485 {
5486 FILE *elf = fopen("alu.elf", "rb");
5487 fseek(elf, 0, SEEK_END);
5488 const uint32_t size = ftell(elf);
5489 fseek(elf, 0, SEEK_SET);
5490 uint8_t *buf = new uint8_t[size];
5491 fread(buf, 1, size, elf);
5492 fclose(elf);
5493
5494 const uint32_t header_offset = *reinterpret_cast<uint32_t*>(&buf[0x1c]);
5495 const uint16_t block_count = *reinterpret_cast<uint16_t*>(&buf[0x2c]);
5496
5497 for (uint32_t i = 0; i < block_count; i++)
5498 {
5499 const uint32_t *header_entry = reinterpret_cast<uint32_t*>(&buf[header_offset + i * 0x20]);
5500
5501 const uint32_t word_count = header_entry[4] >> 2;
5502 const uint32_t file_offset = header_entry[1];
5503 const uint32_t *file_data = reinterpret_cast<uint32_t*>(&buf[file_offset]);
5504 uint32_t addr = header_entry[3];
5505 for (uint32_t word = 0; word < word_count; word++)
5506 {
5507 WWORD(addr, file_data[word]);
5508 addr += 4;
5509 }
5510 }
5511
5512 const uint32_t entry_point = *reinterpret_cast<uint32_t*>(&buf[0x18]);
5513 m_core->pc = entry_point;
5514 m_ppc = entry_point;
5515
5516 delete [] buf;
5517 }
5518
handle_cache(uint32_t op)5519 void r5000be_device::handle_cache(uint32_t op)
5520 {
5521 if ((SR & SR_KSU_MASK) != SR_KSU_KERNEL && !(SR & SR_COP0) && !(SR & (SR_EXL | SR_ERL)))
5522 {
5523 m_badcop_value = 0;
5524 generate_exception(EXCEPTION_BADCOP, 1);
5525 return;
5526 }
5527
5528 const uint32_t vaddr = RSVAL32 + SIMMVAL;
5529
5530 switch (CACHE_TYPE)
5531 {
5532 case 0: // Primary Instruction
5533 switch (CACHE_OP)
5534 {
5535 case 0: // Index Invalidate
5536 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, I-Cache Index Invalidate\n", machine().describe_context(), vaddr);
5537 break;
5538 case 1: // Index Load Tag
5539 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, I-Cache Index Load Tag\n", machine().describe_context(), vaddr);
5540 break;
5541 case 2: // Index Store Tag
5542 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, I-Cache Index Store Tag\n", machine().describe_context(), vaddr);
5543 break;
5544 case 4: // Hit Invalidate
5545 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, I-Cache Hit Invalidate\n", machine().describe_context(), vaddr);
5546 break;
5547 case 5: // Fill
5548 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, I-Cache Fill \n", machine().describe_context(), vaddr);
5549 break;
5550 case 6: // Hit WriteBack
5551 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, I-Cache Hit WriteBack\n", machine().describe_context(), vaddr);
5552 break;
5553 default:
5554 logerror("%s: MIPS3: %08x specifies invalid I-Cache op %d, vaddr %08x\n", machine().describe_context(), op, CACHE_OP, vaddr);
5555 break;
5556 }
5557 break;
5558 case 1: // Primary Data
5559 switch (CACHE_OP)
5560 {
5561 case 0: // Index WriteBack Invalidate
5562 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, D-Cache Index WriteBack Invalidate\n", machine().describe_context(), vaddr);
5563 break;
5564 case 1: // Index Load Tag
5565 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, D-Cache Index Load Tag\n", machine().describe_context(), vaddr);
5566 break;
5567 case 2: // Index Store Tag
5568 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, D-Cache Index Store Tag\n", machine().describe_context(), vaddr);
5569 break;
5570 case 3: // Create Dirty Exclusive
5571 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, D-Cache Create Dirty Exclusive\n", machine().describe_context(), vaddr);
5572 break;
5573 case 4: // Hit Invalidate
5574 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, D-Cache Hit Invalidate\n", machine().describe_context(), vaddr);
5575 break;
5576 case 5: // Hit WriteBack Invalidate
5577 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, D-Cache Hit WriteBack Invalidate\n", machine().describe_context(), vaddr);
5578 break;
5579 case 6: // Hit WriteBack
5580 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, D-Cache Hit WriteBack\n", machine().describe_context(), vaddr);
5581 break;
5582 default:
5583 logerror("%s: MIPS3: %08x specifies invalid D-Cache op %d, vaddr %08x\n", machine().describe_context(), op, CACHE_OP, vaddr);
5584 break;
5585 }
5586 break;
5587 case 3: // Secondary Cache
5588 switch (CACHE_OP)
5589 {
5590 case 0: // Cache Clear
5591 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, SC Cache Clear\n", machine().describe_context(), vaddr);
5592 break;
5593 case 1: // Index Load Tag
5594 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, SC Index Load Tag\n", machine().describe_context(), vaddr);
5595 break;
5596 case 2: // Index Store Tag
5597 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, SC Index Store Tag\n", machine().describe_context(), vaddr);
5598 break;
5599 case 5: // Cache Page Invalidate
5600 logerror("%s: MIPS3: Not yet implemented: cache: vaddr %08x, SC Cache Page Invalidate\n", machine().describe_context(), vaddr);
5601 break;
5602 default:
5603 logerror("%s: MIPS3: %08x specifies invalid SC cache op %d, vaddr %08x\n", machine().describe_context(), op, CACHE_OP, vaddr);
5604 break;
5605 }
5606 break;
5607 default:
5608 logerror("%s: MIPS3: %08x specifies invalid cache type %d, vaddr %08x\n", machine().describe_context(), op, CACHE_TYPE, vaddr);
5609 break;
5610 }
5611 }
5612