1 /* MIPS R3000 CPU emulation.
2    Copyright 2001, 2002, 2003, 2004 Brian R. Gaeke.
3 
4 This file is part of VMIPS.
5 
6 VMIPS is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2 of the License, or (at your
9 option) any later version.
10 
11 VMIPS is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License along
17 with VMIPS; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
19 
20 #include <string.h>
21 #include "cpu.h"
22 #include "cpzero.h"
23 #include "debug.h"
24 #include "fpu.h"
25 #include "mapper.h"
26 #include "vmips.h"
27 #include "options.h"
28 #include "excnames.h"
29 #include "cpzeroreg.h"
30 #include "error.h"
31 #include "remotegdb.h"
32 #include "fileutils.h"
33 #include "stub-dis.h"
34 #include <cstring>
35 
36 /* states of the delay-slot state machine -- see CPU::step() */
37 static const int NORMAL = 0, DELAYING = 1, DELAYSLOT = 2;
38 
39 /* certain fixed register numbers which are handy to know */
40 static const int reg_zero = 0;  /* always zero */
41 static const int reg_sp = 29;   /* stack pointer */
42 static const int reg_ra = 31;   /* return address */
43 
44 /* pointer to CPU method returning void and taking two uint32's */
45 typedef void (CPU::*emulate_funptr)(uint32, uint32);
46 
strdelaystate(const int state)47 static const char *strdelaystate(const int state) {
48 	static const char *const statestr[] = {
49 		"NORMAL", "DELAYING", "DELAYSLOT"
50 	};
51 	return statestr[state];
52 }
53 
CPU(Mapper & m,IntCtrl & i)54 CPU::CPU (Mapper &m, IntCtrl &i)
55   : tracing (false), last_epc (0), last_prio (0), mem (&m),
56     cpzero (new CPZero (this, &i)), fpu (0), delay_state (NORMAL)
57 {
58 	opt_fpu = machine->opt->option("fpu")->flag;
59 	if (opt_fpu)
60 		fpu = new FPU (this);
61 	reg[reg_zero] = 0;
62 	opt_excmsg = machine->opt->option("excmsg")->flag;
63 	opt_reportirq = machine->opt->option("reportirq")->flag;
64 	opt_excpriomsg = machine->opt->option("excpriomsg")->flag;
65 	opt_haltbreak = machine->opt->option("haltbreak")->flag,
66 	opt_haltibe = machine->opt->option("haltibe")->flag;
67 	opt_instdump = machine->opt->option("instdump")->flag;
68 	opt_tracing = machine->opt->option("tracing")->flag;
69 	opt_tracesize = machine->opt->option("tracesize")->num;
70 	opt_tracestartpc = machine->opt->option("tracestartpc")->num;
71 	opt_traceendpc = machine->opt->option("traceendpc")->num;
72 	opt_bigendian = machine->opt->option("bigendian")->flag;
73 	if (opt_tracing)
74 		open_trace_file ();
75 }
76 
~CPU()77 CPU::~CPU ()
78 {
79 	if (opt_tracing)
80 		close_trace_file ();
81 }
82 
83 void
reset(void)84 CPU::reset(void)
85 {
86 #ifdef INTENTIONAL_CONFUSION
87 	int r;
88 	for (r = 0; r < 32; r++) {
89 		reg[r] = random();
90 	}
91 #endif /* INTENTIONAL_CONFUSION */
92 	reg[reg_zero] = 0;
93 	pc = 0xbfc00000;
94 	cpzero->reset();
95 }
96 
97 void
dump_regs(FILE * f)98 CPU::dump_regs(FILE *f)
99 {
100 	int i;
101 
102 	fprintf(f,"Reg Dump: [ PC=%08x  LastInstr=%08x  HI=%08x  LO=%08x\n",
103 		pc,instr,hi,lo);
104 	fprintf(f,"            DelayState=%s  DelayPC=%08x  NextEPC=%08x\n",
105 		strdelaystate(delay_state), delay_pc, next_epc);
106 	for (i = 0; i < 32; i++) {
107 		fprintf(f," R%02d=%08x ",i,reg[i]);
108 		if (i % 5 == 4) {
109 			fputc('\n',f);
110 		} else if (i == 31) {
111 			fprintf(f, " ]\n");
112 		}
113 	}
114 }
115 
116 void
dump_stack(FILE * f)117 CPU::dump_stack(FILE *f)
118 {
119 	uint32 stackphys;
120 	if (cpzero->debug_tlb_translate(reg[reg_sp], &stackphys)) {
121 		mem->dump_stack(f, stackphys);
122 	} else {
123 		fprintf(f, "Stack: (not mapped in TLB)\n");
124 	}
125 }
126 
127 void
dump_mem(FILE * f,uint32 addr)128 CPU::dump_mem(FILE *f, uint32 addr)
129 {
130 	uint32 phys;
131         fprintf(f, "0x%08x: ", addr);
132 	if (cpzero->debug_tlb_translate(addr, &phys)) {
133 		mem->dump_mem(f, phys);
134 	} else {
135 		fprintf(f, "(not mapped in TLB)");
136 	}
137 	fprintf(f, "\n");
138 }
139 
140 /* Disassemble a word at addr and print the result to f.
141  * FIXME: currently, f must be stderr, for the disassembler.
142  */
143 void
dis_mem(FILE * f,uint32 addr)144 CPU::dis_mem(FILE *f, uint32 addr)
145 {
146 	uint32 phys;
147 	uint32 instr;
148 	if (cpzero->debug_tlb_translate(addr, &phys)) {
149 		fprintf(f,"PC=0x%08x [%08x]      %s",addr,phys,(addr==pc?"=>":"  "));
150 		instr = mem->fetch_word(phys,INSTFETCH,false, this);
151 		fprintf(f,"%08x ",instr);
152 		machine->disasm->disassemble(addr,instr);
153 	} else {
154 		fprintf(f,"PC=0x%08x [%08x]      %s",addr,phys,(addr==pc?"=>":"  "));
155 		fprintf(f, "(not mapped in TLB)\n");
156 	}
157 }
158 
159 void
cpzero_dump_regs_and_tlb(FILE * f)160 CPU::cpzero_dump_regs_and_tlb(FILE *f)
161 {
162 	cpzero->dump_regs_and_tlb(f);
163 }
164 
165 /* exception handling */
strexccode(const uint16 excCode)166 static const char *strexccode(const uint16 excCode) {
167 	static const char *const exception_strs[] =
168 	{
169 		/* 0 */ "Interrupt",
170 		/* 1 */ "TLB modification exception",
171 		/* 2 */ "TLB exception (load or instr fetch)",
172 		/* 3 */ "TLB exception (store)",
173 		/* 4 */ "Address error exception (load or instr fetch)",
174 		/* 5 */ "Address error exception (store)",
175 		/* 6 */ "Instruction bus error",
176 		/* 7 */ "Data (load or store) bus error",
177 		/* 8 */ "SYSCALL exception",
178 		/* 9 */ "Breakpoint32 exception (BREAK instr)",
179 		/* 10 */ "Reserved instr exception",
180 		/* 11 */ "Coprocessor Unusable",
181 		/* 12 */ "Arithmetic Overflow",
182 		/* 13 */ "Trap (R4k/R6k only)",
183 		/* 14 */ "LDCz or SDCz to uncached address (R6k)",
184 		/* 14 */ "Virtual Coherency Exception (instr) (R4k)",
185 		/* 15 */ "Machine check exception (R6k)",
186 		/* 15 */ "Floating-point32 exception (R4k)",
187 		/* 16 */ "Exception 16 (reserved)",
188 		/* 17 */ "Exception 17 (reserved)",
189 		/* 18 */ "Exception 18 (reserved)",
190 		/* 19 */ "Exception 19 (reserved)",
191 		/* 20 */ "Exception 20 (reserved)",
192 		/* 21 */ "Exception 21 (reserved)",
193 		/* 22 */ "Exception 22 (reserved)",
194 		/* 23 */ "Reference to WatchHi/WatchLo address detected (R4k)",
195 		/* 24 */ "Exception 24 (reserved)",
196 		/* 25 */ "Exception 25 (reserved)",
197 		/* 26 */ "Exception 26 (reserved)",
198 		/* 27 */ "Exception 27 (reserved)",
199 		/* 28 */ "Exception 28 (reserved)",
200 		/* 29 */ "Exception 29 (reserved)",
201 		/* 30 */ "Exception 30 (reserved)",
202 		/* 31 */ "Virtual Coherency Exception (data) (R4k)"
203 	};
204 
205 	return exception_strs[excCode];
206 }
207 
strmemmode(const int memmode)208 static const char *strmemmode(const int memmode) {
209 	static const char *const memmode_strs[] =
210 	{
211 		"instruction fetch", /* INSTFETCH */
212 		"data load", /* DATALOAD */
213 		"data store", /* DATASTORE */
214 		"not applicable" /* ANY */
215 	};
216 
217 	return memmode_strs[memmode];
218 }
219 
220 int
exception_priority(uint16 excCode,int mode) const221 CPU::exception_priority(uint16 excCode, int mode) const
222 {
223 	/* See doc/excprio for an explanation of this table. */
224 	static const struct excPriority prio[] = {
225 		{1, AdEL, INSTFETCH},
226 		{2, TLBL, INSTFETCH}, {2, TLBS, INSTFETCH},
227 		{3, IBE, ANY},
228 		{4, Ov, ANY}, {4, Tr, ANY}, {4, Sys, ANY},
229 		{4, Bp, ANY}, {4, RI, ANY}, {4, CpU, ANY},
230 		{5, AdEL, DATALOAD}, {5, AdES, ANY},
231 		{6, TLBL, DATALOAD}, {6, TLBS, DATALOAD},
232 		{6, TLBL, DATASTORE}, {6, TLBS, DATASTORE},
233 		{7, Mod, ANY},
234 		{8, DBE, ANY},
235 		{9, Int, ANY},
236 		{0, ANY, ANY} /* catch-all */
237 	};
238 	const struct excPriority *p;
239 
240 	for (p = prio; p->priority != 0; p++) {
241 		if (excCode == p->excCode || p->excCode == ANY) {
242 			if (mode == p->mode || p->mode == ANY) {
243 				return p->priority;
244 			} else if (opt_excpriomsg) {
245 				fprintf(stderr,
246 					"exception code matches but mode %d != table %d\n",
247 					mode,p->mode);
248 			}
249 		} else if (opt_excpriomsg) {
250 			fprintf(stderr, "exception code %d != table %d\n", excCode,
251 				p->excCode);
252 		}
253 	}
254 	return 0;
255 }
256 
257 void
exception(uint16 excCode,int mode,int coprocno)258 CPU::exception(uint16 excCode, int mode /* = ANY */, int coprocno /* = -1 */)
259 {
260 	int prio;
261 	uint32 base, vector, epc;
262 	bool delaying = (delay_state == DELAYSLOT);
263 
264 	if (opt_haltbreak) {
265 		if (excCode == Bp) {
266 			fprintf(stderr,"* BREAK instruction reached -- HALTING *\n");
267 			machine->halt();
268 		}
269 	}
270 	if (opt_haltibe) {
271 		if (excCode == IBE) {
272 			fprintf(stderr,"* Instruction bus error occurred -- HALTING *\n");
273 			machine->halt();
274 		}
275 	}
276 
277 	/* step() ensures that next_epc will always contain the correct
278 	 * EPC whenever exception() is called.
279 	 */
280 	epc = next_epc;
281 
282 	/* Prioritize exception -- if the last exception to occur _also_ was
283 	 * caused by this EPC, only report this exception if it has a higher
284 	 * priority.  Otherwise, exception handling terminates here,
285 	 * because only one exception will be reported per instruction
286 	 * (as per MIPS RISC Architecture, p. 6-35). Note that this only
287 	 * applies IFF the previous exception was caught during the current
288 	 * _execution_ of the instruction at this EPC, so we check that
289 	 * EXCEPTION_PENDING is true before aborting exception handling.
290 	 * (This flag is reset by each call to step().)
291 	 */
292 	prio = exception_priority(excCode, mode);
293 	if (epc == last_epc) {
294 		if (prio <= last_prio && exception_pending) {
295 			if (opt_excpriomsg) {
296 				fprintf(stderr,
297 					"(Ignoring additional lower priority exception...)\n");
298 			}
299 			return;
300 		} else {
301 			last_prio = prio;
302 		}
303 	}
304 	last_epc = epc;
305 
306 	/* Set processor to Kernel mode, disable interrupts, and save
307 	 * exception PC.
308 	 */
309 	cpzero->enter_exception(epc,excCode,coprocno,delaying);
310 
311 	/* Calculate the exception handler address; this is of the form BASE +
312 	 * VECTOR. The BASE is determined by whether we're using boot-time
313 	 * exception vectors, according to the BEV bit in the CP0 Status register.
314 	 */
315 	if (cpzero->use_boot_excp_address()) {
316 		base = 0xbfc00100;
317 	} else {
318 		base = 0x80000000;
319 	}
320 
321 	/* Do we have a User TLB Miss exception? If so, jump to the
322 	 * User TLB Miss exception vector, otherwise jump to the
323 	 * common exception vector.
324 	 */
325 	if ((excCode == TLBL || excCode == TLBS) && (cpzero->tlb_miss_user)) {
326 		vector = 0x000;
327 	} else {
328 		vector = 0x080;
329 	}
330 
331 	if (opt_excmsg && (excCode != Int || opt_reportirq)) {
332 		fprintf(stderr,"Exception %d (%s) triggered, EPC=%08x\n", excCode,
333 			strexccode(excCode), epc);
334 		fprintf(stderr,
335 			" Priority is %d; delay state is %s; mem access mode is %s\n",
336 			prio, strdelaystate(delay_state), strmemmode(mode));
337 		if (excCode == Int) {
338 		  uint32 status, bad, cause;
339 		  cpzero->read_debug_info(&status, &bad, &cause);
340 		  fprintf (stderr, " Interrupt cause = %x, status = %x\n", cause, status);
341 		}
342 	}
343     if (opt_tracing) {
344 		if (tracing) {
345 			current_trace.exception_happened = true;
346 			current_trace.last_exception_code = excCode;
347 		}
348 	}
349 	pc = base + vector;
350 	exception_pending = true;
351 }
352 
353 /* emulation of instructions */
354 void
cpzero_emulate(uint32 instr,uint32 pc)355 CPU::cpzero_emulate(uint32 instr, uint32 pc)
356 {
357 	cpzero->cpzero_emulate(instr, pc);
358 	mem->cache_set_control_bits(cpzero->caches_isolated(),
359 		cpzero->caches_swapped());
360 }
361 
362 /* Called when the program wants to use coprocessor COPROCNO, and there
363  * isn't any implementation for that coprocessor.
364  * Results in a Coprocessor Unusable exception, along with an error
365  * message being printed if the coprocessor is marked usable in the
366  * CP0 Status register.
367  */
368 void
cop_unimpl(int coprocno,uint32 instr,uint32 pc)369 CPU::cop_unimpl (int coprocno, uint32 instr, uint32 pc)
370 {
371 	if (cpzero->cop_usable (coprocno)) {
372 		/* Since they were expecting this to work, the least we
373 		 * can do is print an error message. */
374 		fprintf (stderr, "CP%d instruction %x not implemented at pc=0x%x:\n",
375 				 coprocno, instr, pc);
376 		machine->disasm->disassemble (pc, instr);
377 		exception (CpU, ANY, coprocno);
378 	} else {
379 		/* It's fair game to just throw an exception, if they
380 		 * haven't even bothered to twiddle the status bits first. */
381 		exception (CpU, ANY, coprocno);
382 	}
383 }
384 
385 void
cpone_emulate(uint32 instr,uint32 pc)386 CPU::cpone_emulate(uint32 instr, uint32 pc)
387 {
388 	if (opt_fpu) {
389 		// FIXME: check cpzero->cop_usable
390 		fpu->cpone_emulate (instr, pc);
391 	} else {
392 		/* If it's a cfc1 <reg>, $0 then we copy 0 into reg,
393 		 * which is supposed to mean there is NO cp1...
394 		 * for now, though, ANYTHING else asked of cp1 results
395 		 * in the default "unimplemented" behavior. */
396 		if (cpzero->cop_usable (1) && rs (instr) == 2
397                     && rd (instr) == 0) {
398 			reg[rt (instr)] = 0; /* No cp1. */
399 		} else {
400 			cop_unimpl (1, instr, pc);
401 		}
402         }
403 }
404 
405 void
cptwo_emulate(uint32 instr,uint32 pc)406 CPU::cptwo_emulate(uint32 instr, uint32 pc)
407 {
408 	cop_unimpl (2, instr, pc);
409 }
410 
411 void
cpthree_emulate(uint32 instr,uint32 pc)412 CPU::cpthree_emulate(uint32 instr, uint32 pc)
413 {
414 	cop_unimpl (3, instr, pc);
415 }
416 
417 void
control_transfer(uint32 new_pc)418 CPU::control_transfer (uint32 new_pc)
419 {
420 	if (!new_pc) warning ("Jumping to zero (PC = 0x%x)\n", pc);
421 	delay_state = DELAYING;
422     delay_pc = new_pc;
423 }
424 
425 /// calc_jump_target - Calculate the address to jump to as a result of
426 /// the J-format (jump) instruction INSTR at address PC.  (PC is the address
427 /// of the jump instruction, and INSTR is the jump instruction word.)
428 ///
429 uint32
calc_jump_target(uint32 instr,uint32 pc)430 CPU::calc_jump_target (uint32 instr, uint32 pc)
431 {
432     // Must use address of delay slot (pc + 4) to calculate.
433 	return ((pc + 4) & 0xf0000000) | (jumptarg(instr) << 2);
434 }
435 
436 void
jump(uint32 instr,uint32 pc)437 CPU::jump(uint32 instr, uint32 pc)
438 {
439     control_transfer (calc_jump_target (instr, pc));
440 }
441 
442 void
j_emulate(uint32 instr,uint32 pc)443 CPU::j_emulate(uint32 instr, uint32 pc)
444 {
445 	jump (instr, pc);
446 }
447 
448 void
jal_emulate(uint32 instr,uint32 pc)449 CPU::jal_emulate(uint32 instr, uint32 pc)
450 {
451     jump (instr, pc);
452 	// RA gets addr of instr after delay slot (2 words after this one).
453 	reg[reg_ra] = pc + 8;
454 }
455 
456 /// calc_branch_target - Calculate the address to jump to for the
457 /// PC-relative branch for which the offset is specified by the immediate field
458 /// of the branch instruction word INSTR, with the program counter equal to PC.
459 ///
460 uint32
calc_branch_target(uint32 instr,uint32 pc)461 CPU::calc_branch_target(uint32 instr, uint32 pc)
462 {
463 	return (pc + 4) + (s_immed(instr) << 2);
464 }
465 
466 void
branch(uint32 instr,uint32 pc)467 CPU::branch(uint32 instr, uint32 pc)
468 {
469     control_transfer (calc_branch_target (instr, pc));
470 }
471 
472 void
beq_emulate(uint32 instr,uint32 pc)473 CPU::beq_emulate(uint32 instr, uint32 pc)
474 {
475 	if (reg[rs(instr)] == reg[rt(instr)])
476         branch (instr, pc);
477 }
478 
479 void
bne_emulate(uint32 instr,uint32 pc)480 CPU::bne_emulate(uint32 instr, uint32 pc)
481 {
482 	if (reg[rs(instr)] != reg[rt(instr)])
483         branch (instr, pc);
484 }
485 
486 void
blez_emulate(uint32 instr,uint32 pc)487 CPU::blez_emulate(uint32 instr, uint32 pc)
488 {
489 	if (rt(instr) != 0) {
490 		exception(RI);
491 		return;
492     }
493 	if (reg[rs(instr)] == 0 || (reg[rs(instr)] & 0x80000000))
494 		branch(instr, pc);
495 }
496 
497 void
bgtz_emulate(uint32 instr,uint32 pc)498 CPU::bgtz_emulate(uint32 instr, uint32 pc)
499 {
500 	if (rt(instr) != 0) {
501 		exception(RI);
502 		return;
503 	}
504 	if (reg[rs(instr)] != 0 && (reg[rs(instr)] & 0x80000000) == 0)
505 		branch(instr, pc);
506 }
507 
508 void
addi_emulate(uint32 instr,uint32 pc)509 CPU::addi_emulate(uint32 instr, uint32 pc)
510 {
511 	int32 a, b, sum;
512 
513 	a = (int32)reg[rs(instr)];
514 	b = s_immed(instr);
515 	sum = a + b;
516 	if ((a < 0 && b < 0 && !(sum < 0)) || (a >= 0 && b >= 0 && !(sum >= 0))) {
517 		exception(Ov);
518 		return;
519 	} else {
520 		reg[rt(instr)] = (uint32)sum;
521 	}
522 }
523 
524 void
addiu_emulate(uint32 instr,uint32 pc)525 CPU::addiu_emulate(uint32 instr, uint32 pc)
526 {
527 	int32 a, b, sum;
528 
529 	a = (int32)reg[rs(instr)];
530 	b = s_immed(instr);
531 	sum = a + b;
532 	reg[rt(instr)] = (uint32)sum;
533 }
534 
535 void
slti_emulate(uint32 instr,uint32 pc)536 CPU::slti_emulate(uint32 instr, uint32 pc)
537 {
538 	int32 s_rs = reg[rs(instr)];
539 
540 	if (s_rs < s_immed(instr)) {
541 		reg[rt(instr)] = 1;
542 	} else {
543 		reg[rt(instr)] = 0;
544 	}
545 }
546 
547 void
sltiu_emulate(uint32 instr,uint32 pc)548 CPU::sltiu_emulate(uint32 instr, uint32 pc)
549 {
550 	if (reg[rs(instr)] < (uint32)(int32)s_immed(instr)) {
551 		reg[rt(instr)] = 1;
552 	} else {
553 		reg[rt(instr)] = 0;
554 	}
555 }
556 
557 void
andi_emulate(uint32 instr,uint32 pc)558 CPU::andi_emulate(uint32 instr, uint32 pc)
559 {
560 	reg[rt(instr)] = (reg[rs(instr)] & 0x0ffff) & immed(instr);
561 }
562 
563 void
ori_emulate(uint32 instr,uint32 pc)564 CPU::ori_emulate(uint32 instr, uint32 pc)
565 {
566 	reg[rt(instr)] = reg[rs(instr)] | immed(instr);
567 }
568 
569 void
xori_emulate(uint32 instr,uint32 pc)570 CPU::xori_emulate(uint32 instr, uint32 pc)
571 {
572 	reg[rt(instr)] = reg[rs(instr)] ^ immed(instr);
573 }
574 
575 void
lui_emulate(uint32 instr,uint32 pc)576 CPU::lui_emulate(uint32 instr, uint32 pc)
577 {
578 	reg[rt(instr)] = immed(instr) << 16;
579 }
580 
581 void
lb_emulate(uint32 instr,uint32 pc)582 CPU::lb_emulate(uint32 instr, uint32 pc)
583 {
584 	uint32 phys, virt, base;
585 	int8 byte;
586 	int32 offset;
587 	bool cacheable;
588 
589 	/* Calculate virtual address. */
590 	base = reg[rs(instr)];
591 	offset = s_immed(instr);
592 	virt = base + offset;
593 
594 	/* Translate virtual address to physical address. */
595 	phys = cpzero->address_trans(virt, DATALOAD, &cacheable, this);
596 	if (exception_pending) return;
597 
598 	/* Fetch byte.
599 	 * Because it is assigned to a signed variable (int32 byte)
600 	 * it will be sign-extended.
601 	 */
602 	byte = mem->fetch_byte(phys, cacheable, this);
603 	if (exception_pending) return;
604 
605 	/* Load target register with data. */
606 	reg[rt(instr)] = byte;
607 }
608 
609 void
lh_emulate(uint32 instr,uint32 pc)610 CPU::lh_emulate(uint32 instr, uint32 pc)
611 {
612 	uint32 phys, virt, base;
613 	int16 halfword;
614 	int32 offset;
615 	bool cacheable;
616 
617 	/* Calculate virtual address. */
618 	base = reg[rs(instr)];
619 	offset = s_immed(instr);
620 	virt = base + offset;
621 
622 	/* This virtual address must be halfword-aligned. */
623 	if (virt % 2 != 0) {
624 		exception(AdEL,DATALOAD);
625 		return;
626 	}
627 
628 	/* Translate virtual address to physical address. */
629 	phys = cpzero->address_trans(virt, DATALOAD, &cacheable, this);
630 	if (exception_pending) return;
631 
632 	/* Fetch halfword.
633 	 * Because it is assigned to a signed variable (int32 halfword)
634 	 * it will be sign-extended.
635 	 */
636 	halfword = mem->fetch_halfword(phys, cacheable, this);
637 	if (exception_pending) return;
638 
639 	/* Load target register with data. */
640 	reg[rt(instr)] = halfword;
641 }
642 
643 /* The lwr and lwl algorithms here are taken from SPIM 6.0,
644  * since I didn't manage to come up with a better way to write them.
645  * Improvements are welcome.
646  */
647 uint32
lwr(uint32 regval,uint32 memval,uint8 offset)648 CPU::lwr(uint32 regval, uint32 memval, uint8 offset)
649 {
650 	if (opt_bigendian) {
651 		switch (offset)
652 		{
653 			case 0: return (regval & 0xffffff00) |
654 						((unsigned)(memval & 0xff000000) >> 24);
655 			case 1: return (regval & 0xffff0000) |
656 						((unsigned)(memval & 0xffff0000) >> 16);
657 			case 2: return (regval & 0xff000000) |
658 						((unsigned)(memval & 0xffffff00) >> 8);
659 			case 3: return memval;
660 		}
661 	} else /* if MIPS target is little endian */ {
662 		switch (offset)
663 		{
664 			/* The SPIM source claims that "The description of the
665 			 * little-endian case in Kane is totally wrong." The fact
666 			 * that I ripped off the LWR algorithm from them could be
667 			 * viewed as a sort of passive assumption that their claim
668 			 * is correct.
669 			 */
670 			case 0: /* 3 in book */
671 				return memval;
672 			case 1: /* 0 in book */
673 				return (regval & 0xff000000) | ((memval & 0xffffff00) >> 8);
674 			case 2: /* 1 in book */
675 				return (regval & 0xffff0000) | ((memval & 0xffff0000) >> 16);
676 			case 3: /* 2 in book */
677 				return (regval & 0xffffff00) | ((memval & 0xff000000) >> 24);
678 		}
679 	}
680 	fatal_error("Invalid offset %x passed to lwr\n", offset);
681 }
682 
683 uint32
lwl(uint32 regval,uint32 memval,uint8 offset)684 CPU::lwl(uint32 regval, uint32 memval, uint8 offset)
685 {
686 	if (opt_bigendian) {
687 		switch (offset)
688 		{
689 			case 0: return memval;
690 			case 1: return (memval & 0xffffff) << 8 | (regval & 0xff);
691 			case 2: return (memval & 0xffff) << 16 | (regval & 0xffff);
692 			case 3: return (memval & 0xff) << 24 | (regval & 0xffffff);
693 		}
694 	} else /* if MIPS target is little endian */ {
695 		switch (offset)
696 		{
697 			case 0: return (memval & 0xff) << 24 | (regval & 0xffffff);
698 			case 1: return (memval & 0xffff) << 16 | (regval & 0xffff);
699 			case 2: return (memval & 0xffffff) << 8 | (regval & 0xff);
700 			case 3: return memval;
701 		}
702 	}
703 	fatal_error("Invalid offset %x passed to lwl\n", offset);
704 }
705 
706 void
lwl_emulate(uint32 instr,uint32 pc)707 CPU::lwl_emulate(uint32 instr, uint32 pc)
708 {
709 	uint32 phys, virt, wordvirt, base, memword;
710 	uint8 which_byte;
711 	int32 offset;
712 	bool cacheable;
713 
714 	/* Calculate virtual address. */
715 	base = reg[rs(instr)];
716 	offset = s_immed(instr);
717 	virt = base + offset;
718 	/* We request the word containing the byte-address requested. */
719 	wordvirt = virt & ~0x03UL;
720 
721 	/* Translate virtual address to physical address. */
722 	phys = cpzero->address_trans(wordvirt, DATALOAD, &cacheable, this);
723 	if (exception_pending) return;
724 
725 	/* Fetch word. */
726 	memword = mem->fetch_word(phys, DATALOAD, cacheable, this);
727 	if (exception_pending) return;
728 
729 	/* Insert bytes into the left side of the register. */
730 	which_byte = virt & 0x03;
731 	reg[rt(instr)] = lwl(reg[rt(instr)], memword, which_byte);
732 }
733 
734 void
lw_emulate(uint32 instr,uint32 pc)735 CPU::lw_emulate(uint32 instr, uint32 pc)
736 {
737 	uint32 phys, virt, base, word;
738 	int32 offset;
739 	bool cacheable;
740 
741 	/* Calculate virtual address. */
742 	base = reg[rs(instr)];
743 	offset = s_immed(instr);
744 	virt = base + offset;
745 
746 	/* This virtual address must be word-aligned. */
747 	if (virt % 4 != 0) {
748 		exception(AdEL,DATALOAD);
749 		return;
750 	}
751 
752 	/* Translate virtual address to physical address. */
753 	phys = cpzero->address_trans(virt, DATALOAD, &cacheable, this);
754 	if (exception_pending) return;
755 
756 	/* Fetch word. */
757 	word = mem->fetch_word(phys, DATALOAD, cacheable, this);
758 	if (exception_pending) return;
759 
760 	/* Load target register with data. */
761 	reg[rt(instr)] = word;
762 }
763 
764 void
lbu_emulate(uint32 instr,uint32 pc)765 CPU::lbu_emulate(uint32 instr, uint32 pc)
766 {
767 	uint32 phys, virt, base, byte;
768 	int32 offset;
769 	bool cacheable;
770 
771 	/* Calculate virtual address. */
772 	base = reg[rs(instr)];
773 	offset = s_immed(instr);
774 	virt = base + offset;
775 
776 	/* Translate virtual address to physical address. */
777 	phys = cpzero->address_trans(virt, DATALOAD, &cacheable, this);
778 	if (exception_pending) return;
779 
780 	/* Fetch byte.  */
781 	byte = mem->fetch_byte(phys, cacheable, this) & 0x000000ff;
782 	if (exception_pending) return;
783 
784 	/* Load target register with data. */
785 	reg[rt(instr)] = byte;
786 }
787 
788 void
lhu_emulate(uint32 instr,uint32 pc)789 CPU::lhu_emulate(uint32 instr, uint32 pc)
790 {
791 	uint32 phys, virt, base, halfword;
792 	int32 offset;
793 	bool cacheable;
794 
795 	/* Calculate virtual address. */
796 	base = reg[rs(instr)];
797 	offset = s_immed(instr);
798 	virt = base + offset;
799 
800 	/* This virtual address must be halfword-aligned. */
801 	if (virt % 2 != 0) {
802 		exception(AdEL,DATALOAD);
803 		return;
804 	}
805 
806 	/* Translate virtual address to physical address. */
807 	phys = cpzero->address_trans(virt, DATALOAD, &cacheable, this);
808 	if (exception_pending) return;
809 
810 	/* Fetch halfword.  */
811 	halfword = mem->fetch_halfword(phys, cacheable, this) & 0x0000ffff;
812 	if (exception_pending) return;
813 
814 	/* Load target register with data. */
815 	reg[rt(instr)] = halfword;
816 }
817 
818 void
lwr_emulate(uint32 instr,uint32 pc)819 CPU::lwr_emulate(uint32 instr, uint32 pc)
820 {
821 	uint32 phys, virt, wordvirt, base, memword;
822 	uint8 which_byte;
823 	int32 offset;
824 	bool cacheable;
825 
826 	/* Calculate virtual address. */
827 	base = reg[rs(instr)];
828 	offset = s_immed(instr);
829 	virt = base + offset;
830 	/* We request the word containing the byte-address requested. */
831 	wordvirt = virt & ~0x03UL;
832 
833 	/* Translate virtual address to physical address. */
834 	phys = cpzero->address_trans(wordvirt, DATALOAD, &cacheable, this);
835 	if (exception_pending) return;
836 
837 	/* Fetch word. */
838 	memword = mem->fetch_word(phys, DATALOAD, cacheable, this);
839 	if (exception_pending) return;
840 
841 	/* Insert bytes into the left side of the register. */
842 	which_byte = virt & 0x03;
843 	reg[rt(instr)] = lwr(reg[rt(instr)], memword, which_byte);
844 }
845 
846 void
sb_emulate(uint32 instr,uint32 pc)847 CPU::sb_emulate(uint32 instr, uint32 pc)
848 {
849 	uint32 phys, virt, base;
850 	uint8 data;
851 	int32 offset;
852 	bool cacheable;
853 
854 	/* Load data from register. */
855 	data = reg[rt(instr)] & 0x0ff;
856 
857 	/* Calculate virtual address. */
858 	base = reg[rs(instr)];
859 	offset = s_immed(instr);
860 	virt = base + offset;
861 
862 	/* Translate virtual address to physical address. */
863 	phys = cpzero->address_trans(virt, DATASTORE, &cacheable, this);
864 	if (exception_pending) return;
865 
866 	/* Store byte. */
867 	mem->store_byte(phys, data, cacheable, this);
868 }
869 
870 void
sh_emulate(uint32 instr,uint32 pc)871 CPU::sh_emulate(uint32 instr, uint32 pc)
872 {
873 	uint32 phys, virt, base;
874 	uint16 data;
875 	int32 offset;
876 	bool cacheable;
877 
878 	/* Load data from register. */
879 	data = reg[rt(instr)] & 0x0ffff;
880 
881 	/* Calculate virtual address. */
882 	base = reg[rs(instr)];
883 	offset = s_immed(instr);
884 	virt = base + offset;
885 
886 	/* This virtual address must be halfword-aligned. */
887 	if (virt % 2 != 0) {
888 		exception(AdES,DATASTORE);
889 		return;
890 	}
891 
892 	/* Translate virtual address to physical address. */
893 	phys = cpzero->address_trans(virt, DATASTORE, &cacheable, this);
894 	if (exception_pending) return;
895 
896 	/* Store halfword. */
897 	mem->store_halfword(phys, data, cacheable, this);
898 }
899 
900 uint32
swl(uint32 regval,uint32 memval,uint8 offset)901 CPU::swl(uint32 regval, uint32 memval, uint8 offset)
902 {
903 	if (opt_bigendian) {
904 		switch (offset) {
905 			case 0: return regval;
906 			case 1: return (memval & 0xff000000) | (regval >> 8 & 0xffffff);
907 			case 2: return (memval & 0xffff0000) | (regval >> 16 & 0xffff);
908 			case 3: return (memval & 0xffffff00) | (regval >> 24 & 0xff);
909 		}
910 	} else /* if MIPS target is little endian */ {
911 		switch (offset) {
912 			case 0: return (memval & 0xffffff00) | (regval >> 24 & 0xff);
913 			case 1: return (memval & 0xffff0000) | (regval >> 16 & 0xffff);
914 			case 2: return (memval & 0xff000000) | (regval >> 8 & 0xffffff);
915 			case 3: return regval;
916 		}
917 	}
918 	fatal_error("Invalid offset %x passed to swl\n", offset);
919 }
920 
921 uint32
swr(uint32 regval,uint32 memval,uint8 offset)922 CPU::swr(uint32 regval, uint32 memval, uint8 offset)
923 {
924 	if (opt_bigendian) {
925 		switch (offset) {
926 			case 0: return ((regval << 24) & 0xff000000) | (memval & 0xffffff);
927 			case 1: return ((regval << 16) & 0xffff0000) | (memval & 0xffff);
928 			case 2: return ((regval << 8) & 0xffffff00) | (memval & 0xff);
929 			case 3: return regval;
930 		}
931 	} else /* if MIPS target is little endian */ {
932 		switch (offset) {
933 			case 0: return regval;
934 			case 1: return ((regval << 8) & 0xffffff00) | (memval & 0xff);
935 			case 2: return ((regval << 16) & 0xffff0000) | (memval & 0xffff);
936 			case 3: return ((regval << 24) & 0xff000000) | (memval & 0xffffff);
937 		}
938 	}
939 	fatal_error("Invalid offset %x passed to swr\n", offset);
940 }
941 
942 void
swl_emulate(uint32 instr,uint32 pc)943 CPU::swl_emulate(uint32 instr, uint32 pc)
944 {
945 	uint32 phys, virt, wordvirt, base, regdata, memdata;
946 	int32 offset;
947 	uint8 which_byte;
948 	bool cacheable;
949 
950 	/* Load data from register. */
951 	regdata = reg[rt(instr)];
952 
953 	/* Calculate virtual address. */
954 	base = reg[rs(instr)];
955 	offset = s_immed(instr);
956 	virt = base + offset;
957 	/* We request the word containing the byte-address requested. */
958 	wordvirt = virt & ~0x03UL;
959 
960 	/* Translate virtual address to physical address. */
961 	phys = cpzero->address_trans(wordvirt, DATASTORE, &cacheable, this);
962 	if (exception_pending) return;
963 
964 	/* Read data from memory. */
965 	memdata = mem->fetch_word(phys, DATASTORE, cacheable, this);
966 	if (exception_pending) return;
967 
968 	/* Write back the left side of the register. */
969 	which_byte = virt & 0x03UL;
970 	mem->store_word(phys, swl(regdata, memdata, which_byte), cacheable, this);
971 }
972 
973 void
sw_emulate(uint32 instr,uint32 pc)974 CPU::sw_emulate(uint32 instr, uint32 pc)
975 {
976 	uint32 phys, virt, base, data;
977 	int32 offset;
978 	bool cacheable;
979 
980 	/* Load data from register. */
981 	data = reg[rt(instr)];
982 
983 	/* Calculate virtual address. */
984 	base = reg[rs(instr)];
985 	offset = s_immed(instr);
986 	virt = base + offset;
987 
988 	/* This virtual address must be word-aligned. */
989 	if (virt % 4 != 0) {
990 		exception(AdES,DATASTORE);
991 		return;
992 	}
993 
994 	/* Translate virtual address to physical address. */
995 	phys = cpzero->address_trans(virt, DATASTORE, &cacheable, this);
996 	if (exception_pending) return;
997 
998 	/* Store word. */
999 	mem->store_word(phys, data, cacheable, this);
1000 }
1001 
1002 void
swr_emulate(uint32 instr,uint32 pc)1003 CPU::swr_emulate(uint32 instr, uint32 pc)
1004 {
1005 	uint32 phys, virt, wordvirt, base, regdata, memdata;
1006 	int32 offset;
1007 	uint8 which_byte;
1008 	bool cacheable;
1009 
1010 	/* Load data from register. */
1011 	regdata = reg[rt(instr)];
1012 
1013 	/* Calculate virtual address. */
1014 	base = reg[rs(instr)];
1015 	offset = s_immed(instr);
1016 	virt = base + offset;
1017 	/* We request the word containing the byte-address requested. */
1018 	wordvirt = virt & ~0x03UL;
1019 
1020 	/* Translate virtual address to physical address. */
1021 	phys = cpzero->address_trans(wordvirt, DATASTORE, &cacheable, this);
1022 	if (exception_pending) return;
1023 
1024 	/* Read data from memory. */
1025 	memdata = mem->fetch_word(phys, DATASTORE, cacheable, this);
1026 	if (exception_pending) return;
1027 
1028 	/* Write back the right side of the register. */
1029 	which_byte = virt & 0x03UL;
1030 	mem->store_word(phys, swr(regdata, memdata, which_byte), cacheable, this);
1031 }
1032 
1033 void
lwc1_emulate(uint32 instr,uint32 pc)1034 CPU::lwc1_emulate(uint32 instr, uint32 pc)
1035 {
1036 	if (opt_fpu) {
1037 		uint32 phys, virt, base, word;
1038 		int32 offset;
1039 		bool cacheable;
1040 
1041 		/* Calculate virtual address. */
1042 		base = reg[rs(instr)];
1043 		offset = s_immed(instr);
1044 		virt = base + offset;
1045 
1046 		/* This virtual address must be word-aligned. */
1047 		if (virt % 4 != 0) {
1048 			exception(AdEL,DATALOAD);
1049 			return;
1050 		}
1051 
1052 		/* Translate virtual address to physical address. */
1053 		phys = cpzero->address_trans(virt, DATALOAD, &cacheable, this);
1054 		if (exception_pending) return;
1055 
1056 		/* Fetch word. */
1057 		word = mem->fetch_word(phys, DATALOAD, cacheable, this);
1058 		if (exception_pending) return;
1059 
1060 		/* Load target register with data. */
1061 		fpu->write_reg (rt (instr), word);
1062 	} else {
1063 		cop_unimpl (1, instr, pc);
1064 	}
1065 }
1066 
1067 void
lwc2_emulate(uint32 instr,uint32 pc)1068 CPU::lwc2_emulate(uint32 instr, uint32 pc)
1069 {
1070 	cop_unimpl (2, instr, pc);
1071 }
1072 
1073 void
lwc3_emulate(uint32 instr,uint32 pc)1074 CPU::lwc3_emulate(uint32 instr, uint32 pc)
1075 {
1076 	cop_unimpl (3, instr, pc);
1077 }
1078 
1079 void
swc1_emulate(uint32 instr,uint32 pc)1080 CPU::swc1_emulate(uint32 instr, uint32 pc)
1081 {
1082 	if (opt_fpu) {
1083 		uint32 phys, virt, base, data;
1084 		int32 offset;
1085 		bool cacheable;
1086 
1087 		/* Load data from register. */
1088 		data = fpu->read_reg (rt (instr));
1089 
1090 		/* Calculate virtual address. */
1091 		base = reg[rs(instr)];
1092 		offset = s_immed(instr);
1093 		virt = base + offset;
1094 
1095 		/* This virtual address must be word-aligned. */
1096 		if (virt % 4 != 0) {
1097 			exception(AdES,DATASTORE);
1098 			return;
1099 		}
1100 
1101 		/* Translate virtual address to physical address. */
1102 		phys = cpzero->address_trans(virt, DATASTORE, &cacheable, this);
1103 		if (exception_pending) return;
1104 
1105 		/* Store word. */
1106 		mem->store_word(phys, data, cacheable, this);
1107 	} else {
1108 		cop_unimpl (1, instr, pc);
1109 	}
1110 }
1111 
1112 void
swc2_emulate(uint32 instr,uint32 pc)1113 CPU::swc2_emulate(uint32 instr, uint32 pc)
1114 {
1115 	cop_unimpl (2, instr, pc);
1116 }
1117 
1118 void
swc3_emulate(uint32 instr,uint32 pc)1119 CPU::swc3_emulate(uint32 instr, uint32 pc)
1120 {
1121 	cop_unimpl (3, instr, pc);
1122 }
1123 
1124 void
sll_emulate(uint32 instr,uint32 pc)1125 CPU::sll_emulate(uint32 instr, uint32 pc)
1126 {
1127 	reg[rd(instr)] = reg[rt(instr)] << shamt(instr);
1128 }
1129 
1130 int32
srl(int32 a,int32 b)1131 srl(int32 a, int32 b)
1132 {
1133 	if (b == 0) {
1134 		return a;
1135 	} else if (b == 32) {
1136 		return 0;
1137 	} else {
1138 		return (a >> b) & ((1 << (32 - b)) - 1);
1139 	}
1140 }
1141 
1142 int32
sra(int32 a,int32 b)1143 sra(int32 a, int32 b)
1144 {
1145 	if (b == 0) {
1146 		return a;
1147 	} else {
1148 		return (a >> b) | (((a >> 31) & 0x01) * (((1 << b) - 1) << (32 - b)));
1149 	}
1150 }
1151 
1152 void
srl_emulate(uint32 instr,uint32 pc)1153 CPU::srl_emulate(uint32 instr, uint32 pc)
1154 {
1155 	reg[rd(instr)] = srl(reg[rt(instr)], shamt(instr));
1156 }
1157 
1158 void
sra_emulate(uint32 instr,uint32 pc)1159 CPU::sra_emulate(uint32 instr, uint32 pc)
1160 {
1161 	reg[rd(instr)] = sra(reg[rt(instr)], shamt(instr));
1162 }
1163 
1164 void
sllv_emulate(uint32 instr,uint32 pc)1165 CPU::sllv_emulate(uint32 instr, uint32 pc)
1166 {
1167 	reg[rd(instr)] = reg[rt(instr)] << (reg[rs(instr)] & 0x01f);
1168 }
1169 
1170 void
srlv_emulate(uint32 instr,uint32 pc)1171 CPU::srlv_emulate(uint32 instr, uint32 pc)
1172 {
1173 	reg[rd(instr)] = srl(reg[rt(instr)], reg[rs(instr)] & 0x01f);
1174 }
1175 
1176 void
srav_emulate(uint32 instr,uint32 pc)1177 CPU::srav_emulate(uint32 instr, uint32 pc)
1178 {
1179 	reg[rd(instr)] = sra(reg[rt(instr)], reg[rs(instr)] & 0x01f);
1180 }
1181 
1182 void
jr_emulate(uint32 instr,uint32 pc)1183 CPU::jr_emulate(uint32 instr, uint32 pc)
1184 {
1185 	if (reg[rd(instr)] != 0) {
1186 		exception(RI);
1187 		return;
1188 	}
1189 	control_transfer (reg[rs(instr)]);
1190 }
1191 
1192 void
jalr_emulate(uint32 instr,uint32 pc)1193 CPU::jalr_emulate(uint32 instr, uint32 pc)
1194 {
1195 	control_transfer (reg[rs(instr)]);
1196 	/* RA gets addr of instr after delay slot (2 words after this one). */
1197 	reg[rd(instr)] = pc + 8;
1198 }
1199 
1200 void
syscall_emulate(uint32 instr,uint32 pc)1201 CPU::syscall_emulate(uint32 instr, uint32 pc)
1202 {
1203 	exception(Sys);
1204 }
1205 
1206 void
break_emulate(uint32 instr,uint32 pc)1207 CPU::break_emulate(uint32 instr, uint32 pc)
1208 {
1209 	exception(Bp);
1210 }
1211 
1212 void
mfhi_emulate(uint32 instr,uint32 pc)1213 CPU::mfhi_emulate(uint32 instr, uint32 pc)
1214 {
1215 	reg[rd(instr)] = hi;
1216 }
1217 
1218 void
mthi_emulate(uint32 instr,uint32 pc)1219 CPU::mthi_emulate(uint32 instr, uint32 pc)
1220 {
1221 	if (rd(instr) != 0) {
1222 		exception(RI);
1223 		return;
1224 	}
1225 	hi = reg[rs(instr)];
1226 }
1227 
1228 void
mflo_emulate(uint32 instr,uint32 pc)1229 CPU::mflo_emulate(uint32 instr, uint32 pc)
1230 {
1231 	reg[rd(instr)] = lo;
1232 }
1233 
1234 void
mtlo_emulate(uint32 instr,uint32 pc)1235 CPU::mtlo_emulate(uint32 instr, uint32 pc)
1236 {
1237 	if (rd(instr) != 0) {
1238 		exception(RI);
1239 		return;
1240 	}
1241 	lo = reg[rs(instr)];
1242 }
1243 
1244 void
mult_emulate(uint32 instr,uint32 pc)1245 CPU::mult_emulate(uint32 instr, uint32 pc)
1246 {
1247 	if (rd(instr) != 0) {
1248 		exception(RI);
1249 		return;
1250 	}
1251 	mult64s(&hi, &lo, reg[rs(instr)], reg[rt(instr)]);
1252 }
1253 
1254 void
mult64(uint32 * hi,uint32 * lo,uint32 n,uint32 m)1255 CPU::mult64(uint32 *hi, uint32 *lo, uint32 n, uint32 m)
1256 {
1257 #ifdef HAVE_LONG_LONG
1258 	uint64 result;
1259 	result = ((uint64)n) * ((uint64)m);
1260 	*hi = (uint32) (result >> 32);
1261 	*lo = (uint32) result;
1262 #else /* HAVE_LONG_LONG */
1263 	/*           n = (w << 16) | x ; m = (y << 16) | z
1264 	 *     w x   g = a + e ; h = b + f ; p = 65535
1265 	 *   X y z   c = (z * x) mod p
1266 	 *   -----   b = (z * w + ((z * x) div p)) mod p
1267 	 *   a b c   a = (z * w + ((z * x) div p)) div p
1268 	 * d e f     f = (y * x) mod p
1269 	 * -------   e = (y * w + ((y * x) div p)) mod p
1270 	 * i g h c   d = (y * w + ((y * x) div p)) div p
1271 	 */
1272 	uint16 w,x,y,z,a,b,c,d,e,f,g,h,i;
1273 	uint32 p;
1274 	p = 65536;
1275 	w = (n >> 16) & 0x0ffff;
1276 	x = n & 0x0ffff;
1277 	y = (m >> 16) & 0x0ffff;
1278 	z = m & 0x0ffff;
1279 	c = (z * x) % p;
1280 	b = (z * w + ((z * x) / p)) % p;
1281 	a = (z * w + ((z * x) / p)) / p;
1282 	f = (y * x) % p;
1283 	e = (y * w + ((y * x) / p)) % p;
1284 	d = (y * w + ((y * x) / p)) / p;
1285 	h = (b + f) % p;
1286 	g = ((a + e) + ((b + f) / p)) % p;
1287 	i = d + (((a + e) + ((b + f) / p)) / p);
1288 	*hi = (i << 16) | g;
1289 	*lo = (h << 16) | c;
1290 #endif /* HAVE_LONG_LONG */
1291 }
1292 
1293 void
mult64s(uint32 * hi,uint32 * lo,int32 n,int32 m)1294 CPU::mult64s(uint32 *hi, uint32 *lo, int32 n, int32 m)
1295 {
1296 #ifdef HAVE_LONG_LONG
1297 	int64 result;
1298 	result = ((int64)n) * ((int64)m);
1299 	*hi = (uint32) (result >> 32);
1300 	*lo = (uint32) result;
1301 #else /* HAVE_LONG_LONG */
1302 	int32 result_sign = (n<0)^(m<0);
1303 	int32 n_abs = n;
1304 	int32 m_abs = m;
1305 
1306 	if (n_abs < 0) n_abs = -n_abs;
1307 	if (m_abs < 0) m_abs = -m_abs;
1308 
1309 	mult64(hi,lo,n_abs,m_abs);
1310 	if (result_sign)
1311 	{
1312 		*hi = ~*hi;
1313 		*lo = ~*lo;
1314 		if (*lo & 0x80000000)
1315 		{
1316 			*lo += 1;
1317 			if (!(*lo & 0x80000000))
1318 			{
1319 				*hi += 1;
1320 			}
1321 		}
1322 		else
1323 		{
1324 			*lo += 1;
1325 		}
1326 	}
1327 #endif /* HAVE_LONG_LONG */
1328 }
1329 
1330 void
multu_emulate(uint32 instr,uint32 pc)1331 CPU::multu_emulate(uint32 instr, uint32 pc)
1332 {
1333 	if (rd(instr) != 0) {
1334 		exception(RI);
1335 		return;
1336 	}
1337 	mult64(&hi, &lo, reg[rs(instr)], reg[rt(instr)]);
1338 }
1339 
1340 void
div_emulate(uint32 instr,uint32 pc)1341 CPU::div_emulate(uint32 instr, uint32 pc)
1342 {
1343 	int32 signed_rs = (int32)reg[rs(instr)];
1344 	int32 signed_rt = (int32)reg[rt(instr)];
1345 	lo = signed_rs / signed_rt;
1346 	hi = signed_rs % signed_rt;
1347 }
1348 
1349 void
divu_emulate(uint32 instr,uint32 pc)1350 CPU::divu_emulate(uint32 instr, uint32 pc)
1351 {
1352 	lo = reg[rs(instr)] / reg[rt(instr)];
1353 	hi = reg[rs(instr)] % reg[rt(instr)];
1354 }
1355 
1356 void
add_emulate(uint32 instr,uint32 pc)1357 CPU::add_emulate(uint32 instr, uint32 pc)
1358 {
1359 	int32 a, b, sum;
1360 	a = (int32)reg[rs(instr)];
1361 	b = (int32)reg[rt(instr)];
1362 	sum = a + b;
1363 	if ((a < 0 && b < 0 && !(sum < 0)) || (a >= 0 && b >= 0 && !(sum >= 0))) {
1364 		exception(Ov);
1365 		return;
1366 	} else {
1367 		reg[rd(instr)] = (uint32)sum;
1368 	}
1369 }
1370 
1371 void
addu_emulate(uint32 instr,uint32 pc)1372 CPU::addu_emulate(uint32 instr, uint32 pc)
1373 {
1374 	int32 a, b, sum;
1375 	a = (int32)reg[rs(instr)];
1376 	b = (int32)reg[rt(instr)];
1377 	sum = a + b;
1378 	reg[rd(instr)] = (uint32)sum;
1379 }
1380 
1381 void
sub_emulate(uint32 instr,uint32 pc)1382 CPU::sub_emulate(uint32 instr, uint32 pc)
1383 {
1384 	int32 a, b, diff;
1385 	a = (int32)reg[rs(instr)];
1386 	b = (int32)reg[rt(instr)];
1387 	diff = a - b;
1388 	if ((a < 0 && !(b < 0) && !(diff < 0)) || (!(a < 0) && b < 0 && diff < 0)) {
1389 		exception(Ov);
1390 		return;
1391 	} else {
1392 		reg[rd(instr)] = (uint32)diff;
1393 	}
1394 }
1395 
1396 void
subu_emulate(uint32 instr,uint32 pc)1397 CPU::subu_emulate(uint32 instr, uint32 pc)
1398 {
1399 	int32 a, b, diff;
1400 	a = (int32)reg[rs(instr)];
1401 	b = (int32)reg[rt(instr)];
1402 	diff = a - b;
1403 	reg[rd(instr)] = (uint32)diff;
1404 }
1405 
1406 void
and_emulate(uint32 instr,uint32 pc)1407 CPU::and_emulate(uint32 instr, uint32 pc)
1408 {
1409 	reg[rd(instr)] = reg[rs(instr)] & reg[rt(instr)];
1410 }
1411 
1412 void
or_emulate(uint32 instr,uint32 pc)1413 CPU::or_emulate(uint32 instr, uint32 pc)
1414 {
1415 	reg[rd(instr)] = reg[rs(instr)] | reg[rt(instr)];
1416 }
1417 
1418 void
xor_emulate(uint32 instr,uint32 pc)1419 CPU::xor_emulate(uint32 instr, uint32 pc)
1420 {
1421 	reg[rd(instr)] = reg[rs(instr)] ^ reg[rt(instr)];
1422 }
1423 
1424 void
nor_emulate(uint32 instr,uint32 pc)1425 CPU::nor_emulate(uint32 instr, uint32 pc)
1426 {
1427 	reg[rd(instr)] = ~(reg[rs(instr)] | reg[rt(instr)]);
1428 }
1429 
1430 void
slt_emulate(uint32 instr,uint32 pc)1431 CPU::slt_emulate(uint32 instr, uint32 pc)
1432 {
1433 	int32 s_rs = (int32)reg[rs(instr)];
1434 	int32 s_rt = (int32)reg[rt(instr)];
1435 	if (s_rs < s_rt) {
1436 		reg[rd(instr)] = 1;
1437 	} else {
1438 		reg[rd(instr)] = 0;
1439 	}
1440 }
1441 
1442 void
sltu_emulate(uint32 instr,uint32 pc)1443 CPU::sltu_emulate(uint32 instr, uint32 pc)
1444 {
1445 	if (reg[rs(instr)] < reg[rt(instr)]) {
1446 		reg[rd(instr)] = 1;
1447 	} else {
1448 		reg[rd(instr)] = 0;
1449 	}
1450 }
1451 
1452 void
bltz_emulate(uint32 instr,uint32 pc)1453 CPU::bltz_emulate(uint32 instr, uint32 pc)
1454 {
1455 	if ((int32)reg[rs(instr)] < 0)
1456 		branch(instr, pc);
1457 }
1458 
1459 void
bgez_emulate(uint32 instr,uint32 pc)1460 CPU::bgez_emulate(uint32 instr, uint32 pc)
1461 {
1462 	if ((int32)reg[rs(instr)] >= 0)
1463 		branch(instr, pc);
1464 }
1465 
1466 /* As with JAL, BLTZAL and BGEZAL cause RA to get the address of the
1467  * instruction two words after the current one (pc + 8).
1468  */
1469 void
bltzal_emulate(uint32 instr,uint32 pc)1470 CPU::bltzal_emulate(uint32 instr, uint32 pc)
1471 {
1472 	reg[reg_ra] = pc + 8;
1473 	if ((int32)reg[rs(instr)] < 0)
1474 		branch(instr, pc);
1475 }
1476 
1477 void
bgezal_emulate(uint32 instr,uint32 pc)1478 CPU::bgezal_emulate(uint32 instr, uint32 pc)
1479 {
1480 	reg[reg_ra] = pc + 8;
1481 	if ((int32)reg[rs(instr)] >= 0)
1482 		branch(instr, pc);
1483 }
1484 
1485 /* reserved instruction */
1486 void
RI_emulate(uint32 instr,uint32 pc)1487 CPU::RI_emulate(uint32 instr, uint32 pc)
1488 {
1489 	exception(RI);
1490 }
1491 
1492 void
open_trace_file()1493 CPU::open_trace_file ()
1494 {
1495 	char tracefilename[80];
1496 	for (unsigned i = 0; ; ++i) {
1497 		sprintf (tracefilename, "traceout%d.txt", i);
1498 		if (!can_read_file (tracefilename))
1499 			break;
1500 	}
1501 	traceout = fopen (tracefilename, "w");
1502 }
1503 
1504 void
close_trace_file()1505 CPU::close_trace_file ()
1506 {
1507 	fclose (traceout);
1508 }
1509 
1510 void
write_trace_to_file()1511 CPU::write_trace_to_file ()
1512 {
1513 	for (Trace::record_iterator ri = current_trace.rbegin (), re =
1514          current_trace.rend (); ri != re; ++ri) {
1515         Trace::Record &tr = *ri;
1516 		fprintf (traceout, "(TraceRec (PC #x%08x) (Insn #x%08x) ", tr.pc, tr.instr);
1517 
1518 		if (! tr.inputs.empty ()) {
1519 
1520 		fprintf (traceout, "(Inputs (");
1521 		for (std::vector<Trace::Operand>::iterator oi = tr.inputs.begin (),
1522 			oe = tr.inputs.end (); oi != oe; ++oi) {
1523 			Trace::Operand &op = *oi;
1524 			if (op.regno != -1) {
1525 				fprintf (traceout, "(%s %d #x%08x) ", op.tag, op.regno, op.val);
1526 			} else {
1527 				fprintf (traceout, "(%s #x%08x) ", op.tag, op.val);
1528 			}
1529 		}
1530 		fprintf (traceout, "))");
1531 
1532 		}
1533 
1534 		if (!tr.outputs.empty ()) {
1535 
1536 		fprintf (traceout, "(Outputs (");
1537 		for (std::vector<Trace::Operand>::iterator oi = tr.outputs.begin (),
1538 			oe = tr.outputs.end (); oi != oe; ++oi) {
1539 			Trace::Operand &op = *oi;
1540 			if (op.regno != -1) {
1541 				fprintf (traceout, "(%s %d #x%08x) ", op.tag, op.regno, op.val);
1542 			} else {
1543 				fprintf (traceout, "(%s #x%08x) ", op.tag, op.val);
1544 			}
1545 		}
1546 		fprintf (traceout, "))");
1547 
1548 		}
1549 		fprintf (traceout, ")\n");
1550 	}
1551 	// print lastchanges
1552 	fprintf (traceout, "(LastChanges (");
1553 	for (unsigned i = 0; i < 32; ++i) {
1554 		if (current_trace.last_change_for_reg.find (i) !=
1555 				current_trace.last_change_for_reg.end ()) {
1556 			last_change &lc = current_trace.last_change_for_reg[i];
1557 			fprintf (traceout,
1558 				"(Reg %d PC %x Instr %x OldValue %x CurValue %x) ",
1559 				i, lc.pc, lc.instr, lc.old_value, reg[i]);
1560 		}
1561 	}
1562 	fprintf (traceout, "))\n");
1563 }
1564 
1565 void
flush_trace()1566 CPU::flush_trace()
1567 {
1568 	if (!opt_tracing) return;
1569 	write_trace_to_file ();
1570 	current_trace.clear ();
1571 }
1572 
1573 void
start_tracing()1574 CPU::start_tracing()
1575 {
1576 	if (!opt_tracing) return;
1577 	tracing = true;
1578 	current_trace.clear ();
1579 }
1580 
1581 void
write_trace_instr_inputs(uint32 instr)1582 CPU::write_trace_instr_inputs (uint32 instr)
1583 {
1584     // rs,rt:  add,addu,and,beq,bne,div,divu,mult,multu,nor,or,sb,sh,sllv,slt,
1585     //         sltu,srav,srlv,sub,subu,sw,swl,swr,xor
1586     // rs:     addi,addiu,andi,bgez,bgezal,bgtz,blez,bltz,bltzal,jal,jr,lb,lbu,
1587     //         lh,lhu,lw,lwl,lwr,mthi,mtlo,ori,slti,sltiu,xori
1588     // hi:     mfhi
1589     // lo:     mflo
1590     // rt:     mtc0
1591     // rt,shamt: sll,sra,srl
1592 	// NOT HANDLED: syscall,break,jalr,cpone,cpthree,cptwo,cpzero,
1593 	//              j,lui,lwc1,lwc2,lwc3,mtc0,swc1,swc2,swc3
1594 	switch(opcode(instr))
1595 	{
1596 		case 0:
1597 			switch(funct(instr))
1598 			{
1599 				case 4: //sllv
1600 				case 6: //srlv
1601 				case 7: //srav
1602 				case 24: //mult
1603 				case 25: //multu
1604 				case 26: //div
1605 				case 27: //divu
1606 				case 32: //add
1607 				case 33: //addu
1608 				case 34: //sub
1609 				case 35: //subu
1610 				case 36: //and
1611 				case 37: //or
1612 				case 38: //xor
1613 				case 39: //nor
1614 				case 42: //slt
1615 				case 43: //sltu
1616 					current_trace_record.inputs_push_back_op("rs",
1617                         rs(instr), reg[rs(instr)]);
1618 					current_trace_record.inputs_push_back_op("rt",
1619                         rt(instr), reg[rt(instr)]);
1620 					break;
1621 				case 0: //sll
1622 				case 2: //srl
1623 				case 3: //sra
1624 					current_trace_record.inputs_push_back_op("rt",
1625                         rt(instr), reg[rt(instr)]);
1626 					break;
1627 				case 8: //jr
1628 				case 17: //mthi
1629 				case 19: //mtlo
1630 					current_trace_record.inputs_push_back_op("rs",
1631                         rs(instr), reg[rs(instr)]);
1632 					break;
1633 				case 16: //mfhi
1634 					current_trace_record.inputs_push_back_op("hi",
1635                         hi);
1636 					break;
1637 				case 18: //mflo
1638 					current_trace_record.inputs_push_back_op("lo",
1639                         lo);
1640 					break;
1641 			}
1642 			break;
1643 		case 1:
1644 			switch(rt(instr)) {
1645 				case 0: //bltz
1646 				case 1: //bgez
1647 				case 16: //bltzal
1648 				case 17: //bgezal
1649 					current_trace_record.inputs_push_back_op("rs",
1650                         rs(instr), reg[rs(instr)]);
1651 					break;
1652 			}
1653 			break;
1654 		case 3: //jal
1655 		case 6: //blez
1656 		case 7: //bgtz
1657 		case 8: //addi
1658 		case 9: //addiu
1659 		case 12: //andi
1660 		case 32: //lb
1661 		case 33: //lh
1662 		case 35: //lw
1663 		case 36: //lbu
1664 		case 37: //lhu
1665 		case 40: //sb
1666 		case 41: //sh
1667 		case 42: //swl
1668 		case 43: //sw
1669 		case 46: //swr
1670 			current_trace_record.inputs_push_back_op("rs",
1671 				rs(instr), reg[rs(instr)]);
1672 			current_trace_record.inputs_push_back_op("rt",
1673 				rt(instr), reg[rt(instr)]);
1674 			break;
1675 		case 4: //beq
1676 		case 5: //bne
1677 		case 10: //slti
1678 		case 11: //sltiu
1679 		case 13: //ori
1680 		case 14: //xori
1681 		case 34: //lwl
1682 		case 38: //lwr
1683 			current_trace_record.inputs_push_back_op("rs",
1684 				rs(instr), reg[rs(instr)]);
1685 			break;
1686 	}
1687 }
1688 
1689 
1690 void
write_trace_instr_outputs(uint32 instr)1691 CPU::write_trace_instr_outputs (uint32 instr)
1692 {
1693     // hi,lo: div,divu,mult,multu
1694     // hi:    mthi
1695     // lo:    mtlo
1696     // rt:    addi,addiu,andi,lb,lbu,lh,lhu,lui,lw,lwl,lwr,mfc0,ori,slti,sltiu,
1697     //        xori
1698     // rd:    add,addu,and,jalr,mfhi,mflo,nor,or,sllv,slt,sltu,sll,sra,srav,srl,
1699     //        srlv,sub,subu,xor
1700     // r31:   jal
1701 	// NOT HANDLED: syscall,break,jalr,cpone,cpthree,cptwo,cpzero,j,lwc1,lwc2,
1702     //              lwc3,mtc0,swc1,swc2,swc3,jr,jalr,mfc0,bgtz,blez,sb,sh,sw,
1703     //              swl,swr,beq,bne
1704 	switch(opcode(instr))
1705 	{
1706 		case 0:
1707 			switch(funct(instr))
1708 			{
1709 				case 26: //div
1710 				case 27: //divu
1711 				case 24: //mult
1712 				case 25: //multu
1713 					current_trace_record.outputs_push_back_op("lo",
1714                         lo);
1715 					current_trace_record.outputs_push_back_op("hi",
1716                         hi);
1717 					break;
1718 				case 17: //mthi
1719 					current_trace_record.outputs_push_back_op("hi",
1720                         hi);
1721 					break;
1722 				case 19: //mtlo
1723 					current_trace_record.outputs_push_back_op("lo",
1724                         lo);
1725 					break;
1726 				case 32: //add
1727 				case 33: //addu
1728 				case 36: //and
1729 				case 39: //nor
1730 				case 37: //or
1731 				case 4: //sllv
1732 				case 42: //slt
1733 				case 43: //sltu
1734 				case 7: //srav
1735 				case 6: //srlv
1736 				case 34: //sub
1737 				case 35: //subu
1738 				case 38: //xor
1739 				case 0: //sll
1740 				case 3: //sra
1741 				case 2: //srl
1742 				case 16: //mfhi
1743 				case 18: //mflo
1744 					current_trace_record.outputs_push_back_op("rd",
1745                         rd(instr),reg[rd(instr)]);
1746 					break;
1747 			}
1748 			break;
1749 		case 8: //addi
1750 		case 9: //addiu
1751 		case 12: //andi
1752 		case 32: //lb
1753 		case 36: //lbu
1754 		case 33: //lh
1755 		case 37: //lhu
1756 		case 35: //lw
1757 		case 34: //lwl
1758 		case 38: //lwr
1759 		case 13: //ori
1760 		case 10: //slti
1761 		case 11: //sltiu
1762 		case 14: //xori
1763 		case 15: //lui
1764 			current_trace_record.outputs_push_back_op("rt",rt(instr),
1765                 reg[rt(instr)]);
1766 			break;
1767 		case 3: //jal
1768 			current_trace_record.outputs_push_back_op("ra",
1769                 reg[reg_ra]);
1770 			break;
1771 	}
1772 }
1773 
1774 void
write_trace_record_1(uint32 pc,uint32 instr)1775 CPU::write_trace_record_1(uint32 pc, uint32 instr)
1776 {
1777 	current_trace_record.clear ();
1778 	current_trace_record.pc = pc;
1779 	current_trace_record.instr = instr;
1780 	write_trace_instr_inputs (instr);
1781 	std::copy (&reg[0], &reg[32], &current_trace_record.saved_reg[0]);
1782 }
1783 
1784 void
write_trace_record_2(uint32 pc,uint32 instr)1785 CPU::write_trace_record_2 (uint32 pc, uint32 instr)
1786 {
1787 	write_trace_instr_outputs (instr);
1788 	// which insn was the last to change each reg?
1789 	for (unsigned i = 0; i < 32; ++i) {
1790 		if (current_trace_record.saved_reg[i] != reg[i]) {
1791 			current_trace.last_change_for_reg[i] = last_change::make (pc, instr,
1792 				current_trace_record.saved_reg[i]);
1793 		}
1794 	}
1795 	current_trace.push_back_record (current_trace_record);
1796     if (current_trace.record_size () > opt_tracesize)
1797 		flush_trace ();
1798 }
1799 
1800 void
stop_tracing()1801 CPU::stop_tracing()
1802 {
1803 	tracing = false;
1804 }
1805 
1806 /* dispatching */
1807 void
step()1808 CPU::step()
1809 {
1810 	// Table of emulation functions.
1811 	static const emulate_funptr opcodeJumpTable[] = {
1812         &CPU::funct_emulate, &CPU::regimm_emulate,  &CPU::j_emulate,
1813         &CPU::jal_emulate,   &CPU::beq_emulate,     &CPU::bne_emulate,
1814         &CPU::blez_emulate,  &CPU::bgtz_emulate,    &CPU::addi_emulate,
1815         &CPU::addiu_emulate, &CPU::slti_emulate,    &CPU::sltiu_emulate,
1816         &CPU::andi_emulate,  &CPU::ori_emulate,     &CPU::xori_emulate,
1817         &CPU::lui_emulate,   &CPU::cpzero_emulate,  &CPU::cpone_emulate,
1818         &CPU::cptwo_emulate, &CPU::cpthree_emulate, &CPU::RI_emulate,
1819         &CPU::RI_emulate,    &CPU::RI_emulate,      &CPU::RI_emulate,
1820         &CPU::RI_emulate,    &CPU::RI_emulate,      &CPU::RI_emulate,
1821         &CPU::RI_emulate,    &CPU::RI_emulate,      &CPU::RI_emulate,
1822         &CPU::RI_emulate,    &CPU::RI_emulate,      &CPU::lb_emulate,
1823         &CPU::lh_emulate,    &CPU::lwl_emulate,     &CPU::lw_emulate,
1824         &CPU::lbu_emulate,   &CPU::lhu_emulate,     &CPU::lwr_emulate,
1825         &CPU::RI_emulate,    &CPU::sb_emulate,      &CPU::sh_emulate,
1826         &CPU::swl_emulate,   &CPU::sw_emulate,      &CPU::RI_emulate,
1827         &CPU::RI_emulate,    &CPU::swr_emulate,     &CPU::RI_emulate,
1828         &CPU::RI_emulate,    &CPU::lwc1_emulate,    &CPU::lwc2_emulate,
1829         &CPU::lwc3_emulate,  &CPU::RI_emulate,      &CPU::RI_emulate,
1830         &CPU::RI_emulate,    &CPU::RI_emulate,      &CPU::RI_emulate,
1831         &CPU::swc1_emulate,  &CPU::swc2_emulate,    &CPU::swc3_emulate,
1832         &CPU::RI_emulate,    &CPU::RI_emulate,      &CPU::RI_emulate,
1833         &CPU::RI_emulate
1834     };
1835 
1836 	// Clear exception_pending flag if it was set by a prior instruction.
1837 	exception_pending = false;
1838 
1839 	// Decrement Random register every clock cycle.
1840 	cpzero->adjust_random();
1841 
1842     // Check whether we should start tracing with this instruction.
1843 	if (opt_tracing && !tracing && pc == opt_tracestartpc)
1844 		start_tracing();
1845 
1846 	// Save address of instruction responsible for exceptions which may occur.
1847 	if (delay_state != DELAYSLOT)
1848 		next_epc = pc;
1849 
1850 	// Get physical address of next instruction.
1851 	bool cacheable;
1852 	uint32 real_pc = cpzero->address_trans(pc,INSTFETCH,&cacheable, this);
1853 	if (exception_pending) {
1854 		if (opt_excmsg)
1855 			fprintf(stderr,
1856 				"** PC address translation caused the exception! **\n");
1857 		goto out;
1858 	}
1859 
1860 	// Fetch next instruction.
1861 	instr = mem->fetch_word(real_pc,INSTFETCH,cacheable, this);
1862 	if (exception_pending) {
1863 		if (opt_excmsg)
1864 			fprintf(stderr, "** Instruction fetch caused the exception! **\n");
1865 		goto out;
1866 	}
1867 
1868 	// Disassemble the instruction, if the user requested it.
1869 	if (opt_instdump) {
1870 		fprintf(stderr,"PC=0x%08x [%08x]\t%08x ",pc,real_pc,instr);
1871 		machine->disasm->disassemble(pc,instr);
1872 	}
1873 
1874 	// Perform first half of trace recording for this instruction.
1875 	if (tracing)
1876 		write_trace_record_1 (pc, instr);
1877 
1878 	// Check for a (hardware or software) interrupt.
1879 	if (cpzero->interrupt_pending()) {
1880 		exception(Int);
1881 		goto out;
1882 	}
1883 
1884 	// Emulate the instruction by jumping to the appropriate emulation method.
1885 	(this->*opcodeJumpTable[opcode(instr)])(instr, pc);
1886 
1887 out:
1888 	// Force register zero to contain zero.
1889 	reg[reg_zero] = 0;
1890 
1891 	// Perform second half of trace recording for this instruction.
1892 	if (tracing) {
1893 		write_trace_record_2 (pc, instr);
1894 		if (pc == opt_traceendpc)
1895 			stop_tracing();
1896 	}
1897 
1898 	// If an exception is pending, then the PC has already been changed to
1899 	// contain the exception vector.  Return now, so that we don't clobber it.
1900 	if (exception_pending) {
1901 		// Instruction at beginning of exception handler is NOT in delay slot,
1902 		// no matter what the last instruction was.
1903 		delay_state = NORMAL;
1904 		return;
1905 	}
1906 
1907 	// Recall the delay_state values: 0=NORMAL, 1=DELAYING, 2=DELAYSLOT.
1908 	// This is what the delay_state values mean (at this point in the code):
1909 	// DELAYING: The last instruction caused a branch to be taken.
1910 	//  The next instruction is in the delay slot.
1911 	//  The next instruction EPC will be PC - 4.
1912 	// DELAYSLOT: The last instruction was executed in a delay slot.
1913 	//  The next instruction is on the other end of the branch.
1914 	//  The next instruction EPC will be PC.
1915 	// NORMAL: No branch was executed; next instruction is at PC + 4.
1916 	//  Next instruction EPC is PC.
1917 
1918 	// Update the pc and delay_state values.
1919 	pc += 4;
1920 	if (delay_state == DELAYSLOT)
1921 		pc = delay_pc;
1922 	delay_state = (delay_state << 1) & 0x03; // 0->0, 1->2, 2->0
1923 }
1924 
1925 void
funct_emulate(uint32 instr,uint32 pc)1926 CPU::funct_emulate(uint32 instr, uint32 pc)
1927 {
1928 	static const emulate_funptr functJumpTable[] = {
1929 		&CPU::sll_emulate,     &CPU::RI_emulate,
1930 		&CPU::srl_emulate,     &CPU::sra_emulate,
1931 		&CPU::sllv_emulate,    &CPU::RI_emulate,
1932 		&CPU::srlv_emulate,    &CPU::srav_emulate,
1933 		&CPU::jr_emulate,      &CPU::jalr_emulate,
1934 		&CPU::RI_emulate,      &CPU::RI_emulate,
1935 		&CPU::syscall_emulate, &CPU::break_emulate,
1936 		&CPU::RI_emulate,      &CPU::RI_emulate,
1937 		&CPU::mfhi_emulate,    &CPU::mthi_emulate,
1938 		&CPU::mflo_emulate,    &CPU::mtlo_emulate,
1939 		&CPU::RI_emulate,      &CPU::RI_emulate,
1940 		&CPU::RI_emulate,      &CPU::RI_emulate,
1941 		&CPU::mult_emulate,    &CPU::multu_emulate,
1942 		&CPU::div_emulate,     &CPU::divu_emulate,
1943 		&CPU::RI_emulate,      &CPU::RI_emulate,
1944 		&CPU::RI_emulate,      &CPU::RI_emulate,
1945 		&CPU::add_emulate,     &CPU::addu_emulate,
1946 		&CPU::sub_emulate,     &CPU::subu_emulate,
1947 		&CPU::and_emulate,     &CPU::or_emulate,
1948 		&CPU::xor_emulate,     &CPU::nor_emulate,
1949 		&CPU::RI_emulate,      &CPU::RI_emulate,
1950 		&CPU::slt_emulate,     &CPU::sltu_emulate,
1951 		&CPU::RI_emulate,      &CPU::RI_emulate,
1952 		&CPU::RI_emulate,      &CPU::RI_emulate,
1953 		&CPU::RI_emulate,      &CPU::RI_emulate,
1954 		&CPU::RI_emulate,      &CPU::RI_emulate,
1955 		&CPU::RI_emulate,      &CPU::RI_emulate,
1956 		&CPU::RI_emulate,      &CPU::RI_emulate,
1957 		&CPU::RI_emulate,      &CPU::RI_emulate,
1958 		&CPU::RI_emulate,      &CPU::RI_emulate,
1959 		&CPU::RI_emulate,      &CPU::RI_emulate,
1960 		&CPU::RI_emulate,      &CPU::RI_emulate
1961 	};
1962 	(this->*functJumpTable[funct(instr)])(instr, pc);
1963 }
1964 
1965 void
regimm_emulate(uint32 instr,uint32 pc)1966 CPU::regimm_emulate(uint32 instr, uint32 pc)
1967 {
1968 	switch(rt(instr))
1969 	{
1970 		case 0: bltz_emulate(instr, pc); break;
1971 		case 1: bgez_emulate(instr, pc); break;
1972 		case 16: bltzal_emulate(instr, pc); break;
1973 		case 17: bgezal_emulate(instr, pc); break;
1974 		default: exception(RI); break; /* reserved instruction */
1975 	}
1976 }
1977 
1978 /* Debug functions.
1979  *
1980  * These functions are primarily intended to support the Debug class,
1981  * which interfaces with GDB's remote serial protocol.
1982  */
1983 
1984 /* Copy registers into an ASCII-encoded packet of hex numbers to send
1985  * to the remote GDB, and return the packet (allocated with malloc).
1986  */
1987 char *
debug_registers_to_packet(void)1988 CPU::debug_registers_to_packet(void)
1989 {
1990 	char *packet = new char [PBUFSIZ];
1991 	int i, r;
1992 
1993 	/* order of regs:  (gleaned from gdb/gdb/config/mips/tm-mips.h)
1994 	 *
1995 	 * cpu->reg[0]...cpu->reg[31]
1996 	 * cpzero->reg[Status]
1997 	 * cpu->lo
1998 	 * cpu->hi
1999 	 * cpzero->reg[BadVAddr]
2000 	 * cpzero->reg[Cause]
2001 	 * cpu->pc
2002 	 * fpu stuff: 35 zeroes (Unimplemented registers read as
2003 	 *  all bits zero.)
2004 	 */
2005 	packet[0] = '\0';
2006 	r = 0;
2007 	for (i = 0; i < 32; i++) {
2008 		debug_packet_push_word(packet, reg[i]); r++;
2009 	}
2010 	uint32 sr, bad, cause;
2011 	cpzero->read_debug_info(&sr, &bad, &cause);
2012 	debug_packet_push_word(packet, sr); r++;
2013 	debug_packet_push_word(packet, lo); r++;
2014 	debug_packet_push_word(packet, hi); r++;
2015 	debug_packet_push_word(packet, bad); r++;
2016 	debug_packet_push_word(packet, cause); r++;
2017 	debug_packet_push_word(packet, pc); r++;
2018 	for (; r < 90; r++) { /* unimplemented regs at end */
2019 		debug_packet_push_word(packet, 0);
2020 	}
2021 	return packet;
2022 }
2023 
2024 /* Copy the register values in the ASCII-encoded hex PACKET received from
2025  * the remote GDB and store them in the appropriate registers.
2026  */
2027 void
debug_packet_to_registers(char * packet)2028 CPU::debug_packet_to_registers(char *packet)
2029 {
2030 	int i;
2031 
2032 	for (i = 0; i < 32; i++)
2033 		reg[i] = machine->dbgr->packet_pop_word(&packet);
2034 	uint32 sr, bad, cause;
2035 	sr = machine->dbgr->packet_pop_word(&packet);
2036 	lo = machine->dbgr->packet_pop_word(&packet);
2037 	hi = machine->dbgr->packet_pop_word(&packet);
2038 	bad = machine->dbgr->packet_pop_word(&packet);
2039 	cause = machine->dbgr->packet_pop_word(&packet);
2040 	pc = machine->dbgr->packet_pop_word(&packet);
2041 	cpzero->write_debug_info(sr, bad, cause);
2042 }
2043 
2044 /* Returns the exception code of any pending exception, or 0 if no
2045  * exception is pending.
2046  */
2047 uint8
pending_exception(void)2048 CPU::pending_exception(void)
2049 {
2050 	uint32 sr, bad, cause;
2051 
2052 	if (! exception_pending) return 0;
2053 	cpzero->read_debug_info(&sr, &bad, &cause);
2054 	return ((cause & Cause_ExcCode_MASK) >> 2);
2055 }
2056 
2057 /* Sets the program counter register to the value given in NEWPC. */
2058 void
debug_set_pc(uint32 newpc)2059 CPU::debug_set_pc(uint32 newpc)
2060 {
2061 	pc = newpc;
2062 }
2063 
2064 /* Returns the current program counter register. */
2065 uint32
debug_get_pc(void)2066 CPU::debug_get_pc(void)
2067 {
2068 	return pc;
2069 }
2070 
2071 void
debug_packet_push_word(char * packet,uint32 n)2072 CPU::debug_packet_push_word(char *packet, uint32 n)
2073 {
2074 	if (!opt_bigendian) {
2075 		n = Mapper::swap_word(n);
2076 	}
2077 	char packetpiece[10];
2078 	sprintf(packetpiece, "%08x", n);
2079 	strcat(packet, packetpiece);
2080 }
2081 
2082 void
debug_packet_push_byte(char * packet,uint8 n)2083 CPU::debug_packet_push_byte(char *packet, uint8 n)
2084 {
2085 	char packetpiece[4];
2086 	sprintf(packetpiece, "%02x", n);
2087 	strcat(packet, packetpiece);
2088 }
2089 
2090 /* Fetch LEN bytes starting from virtual address ADDR into the packet
2091  * PACKET, sending exceptions (if any) to CLIENT. Returns -1 if an exception
2092  * was encountered, 0 otherwise.  If an exception was encountered, the
2093  * contents of PACKET are undefined, and CLIENT->exception() will have
2094  * been called.
2095  */
2096 int
debug_fetch_region(uint32 addr,uint32 len,char * packet,DeviceExc * client)2097 CPU::debug_fetch_region(uint32 addr, uint32 len, char *packet,
2098 	DeviceExc *client)
2099 {
2100 	uint8 byte;
2101 	uint32 real_addr;
2102 	bool cacheable = false;
2103 
2104 	for (; len; addr++, len--) {
2105 		real_addr = cpzero->address_trans(addr, DATALOAD, &cacheable, client);
2106 		/* Stop now and return an error code if translation
2107 		 * caused an exception.
2108 		 */
2109 		if (client->exception_pending) {
2110 			return -1;
2111 		}
2112 		byte = mem->fetch_byte(real_addr, true, client);
2113 		/* Stop now and return an error code if the fetch
2114 		 * caused an exception.
2115 		 */
2116 		if (client->exception_pending) {
2117 			return -1;
2118 		}
2119 		debug_packet_push_byte(packet, byte);
2120 	}
2121 	return 0;
2122 }
2123 
2124 /* Store LEN bytes starting from virtual address ADDR from data in the packet
2125  * PACKET, sending exceptions (if any) to CLIENT. Returns -1 if an exception
2126  * was encountered, 0 otherwise.  If an exception was encountered, the
2127  * contents of the region of virtual memory from ADDR to ADDR+LEN are undefined,
2128  * and CLIENT->exception() will have been called.
2129  */
2130 int
debug_store_region(uint32 addr,uint32 len,char * packet,DeviceExc * client)2131 CPU::debug_store_region(uint32 addr, uint32 len, char *packet,
2132 	DeviceExc *client)
2133 {
2134 	uint8 byte;
2135 	uint32 real_addr;
2136 	bool cacheable = false;
2137 
2138 	for (; len; addr++, len--) {
2139 		byte = machine->dbgr->packet_pop_byte(&packet);
2140 		real_addr = cpzero->address_trans(addr, DATALOAD, &cacheable, client);
2141 		if (client->exception_pending) {
2142 			return -1;
2143 		}
2144 		mem->store_byte(real_addr, byte, true, client);
2145 		if (client->exception_pending) {
2146 			return -1;
2147 		}
2148 	}
2149 	return 0;
2150 }
2151