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