xref: /netbsd/sys/arch/mips/mips/db_interface.c (revision c4a72b64)
1 /*	$NetBSD: db_interface.c,v 1.45 2002/11/04 20:02:09 thorpej Exp $	*/
2 
3 /*
4  * Mach Operating System
5  * Copyright (c) 1991,1990 Carnegie Mellon University
6  * All Rights Reserved.
7  *
8  * Permission to use, copy, modify and distribute this software and its
9  * documentation is hereby granted, provided that both the copyright
10  * notice and this permission notice appear in all copies of the
11  * software, derivative works or modified versions, and any portions
12  * thereof, and that both notices appear in supporting documentation.
13  *
14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17  *
18  * Carnegie Mellon requests users of this software to return to
19  *
20  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
21  *  School of Computer Science
22  *  Carnegie Mellon University
23  *  Pittsburgh PA 15213-3890
24  *
25  * any improvements or extensions that they make and grant Carnegie Mellon
26  * the rights to redistribute these changes.
27  */
28 
29 #include "opt_cputype.h"	/* which mips CPUs do we support? */
30 #include "opt_ddb.h"
31 #include "opt_kgdb.h"
32 
33 #include <sys/types.h>
34 #include <sys/systm.h>
35 #include <sys/param.h>
36 #include <sys/proc.h>
37 #include <sys/user.h>
38 #include <sys/reboot.h>
39 
40 #include <uvm/uvm_extern.h>
41 
42 #include <mips/cache.h>
43 #include <mips/pte.h>
44 #include <mips/cpu.h>
45 #include <mips/locore.h>
46 #include <mips/mips_opcode.h>
47 #include <dev/cons.h>
48 
49 #include <machine/db_machdep.h>
50 #include <ddb/db_access.h>
51 #ifndef KGDB
52 #include <ddb/db_command.h>
53 #include <ddb/db_output.h>
54 #include <ddb/db_sym.h>
55 #include <ddb/db_extern.h>
56 #include <ddb/db_interface.h>
57 #endif
58 
59 int		db_active = 0;
60 db_regs_t	ddb_regs;
61 mips_reg_t	kdbaux[11]; /* XXX struct switchframe: better inside curpcb? XXX */
62 
63 void db_tlbdump_cmd(db_expr_t, int, db_expr_t, char *);
64 void db_kvtophys_cmd(db_expr_t, int, db_expr_t, char *);
65 void db_cp0dump_cmd(db_expr_t, int, db_expr_t, char *);
66 
67 static void	kdbpoke_4(vaddr_t addr, int newval);
68 static void	kdbpoke_2(vaddr_t addr, short newval);
69 static void	kdbpoke_1(vaddr_t addr, char newval);
70 static short	kdbpeek_2(vaddr_t addr);
71 static char	kdbpeek_1(vaddr_t addr);
72 extern vaddr_t	MachEmulateBranch(struct frame *, vaddr_t, unsigned, int);
73 
74 extern paddr_t kvtophys(vaddr_t);
75 
76 #ifdef DDB_TRACE
77 int
78 kdbpeek(vaddr_t addr)
79 {
80 
81 	if (addr == 0 || (addr & 3))
82 		return 0;
83 	return *(int *)addr;
84 }
85 #endif
86 
87 static short
88 kdbpeek_2(vaddr_t addr)
89 {
90 
91 	return *(short *)addr;
92 }
93 
94 static char
95 kdbpeek_1(vaddr_t addr)
96 {
97 
98 	return *(char *)addr;
99 }
100 
101 /*
102  * kdbpoke -- write a value to a kernel virtual address.
103  *    XXX should handle KSEG2 addresses and check for unmapped pages.
104  *    XXX user-space addresess?
105  */
106 static void
107 kdbpoke_4(vaddr_t addr, int newval)
108 {
109 
110 	*(int*) addr = newval;
111 	wbflush();
112 }
113 
114 static void
115 kdbpoke_2(vaddr_t addr, short newval)
116 {
117 
118 	*(short*) addr = newval;
119 	wbflush();
120 }
121 
122 static void
123 kdbpoke_1(vaddr_t addr, char newval)
124 {
125 	*(char*) addr = newval;
126 	wbflush();
127 }
128 
129 #if 0 /* UNUSED */
130 /*
131  * Received keyboard interrupt sequence.
132  */
133 void
134 kdb_kbd_trap(int *tf)
135 {
136 
137 	if (db_active == 0 && (boothowto & RB_KDB)) {
138 		printf("\n\nkernel: keyboard interrupt\n");
139 		ddb_trap(-1, tf);
140 	}
141 }
142 #endif
143 
144 #ifndef KGDB
145 int
146 kdb_trap(int type, mips_reg_t /* struct trapframe */ *tfp)
147 {
148 
149 	struct frame *f = (struct frame *)&ddb_regs;
150 
151 #ifdef notyet
152 	switch (type) {
153 	case T_BREAK:		/* breakpoint */
154 	case -1:		/* keyboard interrupt */
155 		break;
156 	default:
157 		printf("kernel: %s trap", trap_type[type & 0xff]);
158 		if (db_recover != 0) {
159 			db_error("Faulted in DDB; continuing...\n");
160 			/*NOTREACHED*/
161 		}
162 		break;
163 	}
164 #endif
165 	/* Should switch to kdb`s own stack here. */
166 	db_set_ddb_regs(type, tfp);
167 
168 	db_active++;
169 	cnpollc(1);
170 	db_trap(type & ~T_USER, 0 /*code*/);
171 	cnpollc(0);
172 	db_active--;
173 
174 	if (type & T_USER)
175 		*(struct frame *)curproc->p_md.md_regs = *f;
176 	else {
177 		/* Synthetic full scale register context when trap happens */
178 		tfp[TF_AST] = f->f_regs[AST];
179 		tfp[TF_V0] = f->f_regs[V0];
180 		tfp[TF_V1] = f->f_regs[V1];
181 		tfp[TF_A0] = f->f_regs[A0];
182 		tfp[TF_A1] = f->f_regs[A1];
183 		tfp[TF_A2] = f->f_regs[A2];
184 		tfp[TF_A3] = f->f_regs[A3];
185 		tfp[TF_T0] = f->f_regs[T0];
186 		tfp[TF_T1] = f->f_regs[T1];
187 		tfp[TF_T2] = f->f_regs[T2];
188 		tfp[TF_T3] = f->f_regs[T3];
189 		tfp[TF_TA0] = f->f_regs[TA0];
190 		tfp[TF_TA1] = f->f_regs[TA1];
191 		tfp[TF_TA2] = f->f_regs[TA2];
192 		tfp[TF_TA3] = f->f_regs[TA3];
193 		tfp[TF_T8] = f->f_regs[T8];
194 		tfp[TF_T9] = f->f_regs[T9];
195 		tfp[TF_RA] = f->f_regs[RA];
196 		tfp[TF_SR] = f->f_regs[SR];
197 		tfp[TF_MULLO] = f->f_regs[MULLO];
198 		tfp[TF_MULHI] = f->f_regs[MULHI];
199 		tfp[TF_EPC] = f->f_regs[PC];
200 		kdbaux[0] = f->f_regs[S0];
201 		kdbaux[1] = f->f_regs[S1];
202 		kdbaux[2] = f->f_regs[S2];
203 		kdbaux[3] = f->f_regs[S3];
204 		kdbaux[4] = f->f_regs[S4];
205 		kdbaux[5] = f->f_regs[S5];
206 		kdbaux[6] = f->f_regs[S6];
207 		kdbaux[7] = f->f_regs[S7];
208 		kdbaux[8] = f->f_regs[SP];
209 		kdbaux[9] = f->f_regs[S8];
210 		kdbaux[10] = f->f_regs[GP];
211 	}
212 
213 	return (1);
214 }
215 
216 void
217 cpu_Debugger(void)
218 {
219 
220 	asm("break");
221 }
222 #endif	/* !KGDB */
223 
224 void
225 db_set_ddb_regs(int type, mips_reg_t *tfp)
226 {
227 	struct frame *f = (struct frame *)&ddb_regs;
228 
229 	/* Should switch to kdb`s own stack here. */
230 
231 	if (type & T_USER)
232 		*f = *(struct frame *)curproc->p_md.md_regs;
233 	else {
234 		/* Synthetic full scale register context when trap happens */
235 		f->f_regs[AST] = tfp[TF_AST];
236 		f->f_regs[V0] = tfp[TF_V0];
237 		f->f_regs[V1] = tfp[TF_V1];
238 		f->f_regs[A0] = tfp[TF_A0];
239 		f->f_regs[A1] = tfp[TF_A1];
240 		f->f_regs[A2] = tfp[TF_A2];
241 		f->f_regs[A3] = tfp[TF_A3];
242 		f->f_regs[T0] = tfp[TF_T0];
243 		f->f_regs[T1] = tfp[TF_T1];
244 		f->f_regs[T2] = tfp[TF_T2];
245 		f->f_regs[T3] = tfp[TF_T3];
246 		f->f_regs[TA0] = tfp[TF_TA0];
247 		f->f_regs[TA1] = tfp[TF_TA1];
248 		f->f_regs[TA2] = tfp[TF_TA2];
249 		f->f_regs[TA3] = tfp[TF_TA3];
250 		f->f_regs[T8] = tfp[TF_T8];
251 		f->f_regs[T9] = tfp[TF_T9];
252 		f->f_regs[RA] = tfp[TF_RA];
253 		f->f_regs[SR] = tfp[TF_SR];
254 		f->f_regs[MULLO] = tfp[TF_MULLO];
255 		f->f_regs[MULHI] = tfp[TF_MULHI];
256 		f->f_regs[PC] = tfp[TF_EPC];
257 		f->f_regs[S0] = kdbaux[0];
258 		f->f_regs[S1] = kdbaux[1];
259 		f->f_regs[S2] = kdbaux[2];
260 		f->f_regs[S3] = kdbaux[3];
261 		f->f_regs[S4] = kdbaux[4];
262 		f->f_regs[S5] = kdbaux[5];
263 		f->f_regs[S6] = kdbaux[6];
264 		f->f_regs[S7] = kdbaux[7];
265 		f->f_regs[SP] = kdbaux[8];
266 		f->f_regs[S8] = kdbaux[9];
267 		f->f_regs[GP] = kdbaux[10];
268 	}
269 }
270 
271 /*
272  * Read bytes from kernel address space for debugger.
273  */
274 void
275 db_read_bytes(vaddr_t addr, size_t size, char *data)
276 {
277 
278 	while (size >= 4)
279 		*((int*)data)++ = kdbpeek(addr), addr += 4, size -= 4;
280 	while (size >= 2)
281 		*((short*)data)++ = kdbpeek_2(addr), addr += 2, size -= 2;
282 	if (size == 1)
283 		*((char*)data)++ = kdbpeek_1(addr);
284 }
285 
286 /*
287  * Write bytes to kernel address space for debugger.
288  */
289 void
290 db_write_bytes(vaddr_t addr, size_t size, char *data)
291 {
292 	vaddr_t p = addr;
293 	size_t n = size;
294 
295 #ifdef DEBUG_DDB
296 	printf("db_write_bytes(%lx, %d, %p, val %x)\n", addr, size, data,
297 	       	(addr &3 ) == 0? *(u_int*)addr: -1);
298 #endif
299 
300 	while (n >= 4) {
301 		kdbpoke_4(p, *(int*)data);
302 		p += 4;
303 		data += 4;
304 		n -= 4;
305 	}
306 	if (n >= 2) {
307 		kdbpoke_2(p, *(short*)data);
308 		p += 2;
309 		data += 2;
310 		n -= 2;
311 	}
312 	if (n == 1) {
313 		kdbpoke_1(p, *(char*)data);
314 	}
315 
316 	mips_icache_sync_range((vaddr_t) addr, size);
317 }
318 
319 #ifndef KGDB
320 void
321 db_tlbdump_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
322 {
323 
324 #ifdef MIPS1
325 	if (!MIPS_HAS_R4K_MMU) {
326 		struct mips1_tlb {
327 			u_int32_t tlb_hi;
328 			u_int32_t tlb_lo;
329 		} tlb;
330 		int i;
331 		void mips1_TLBRead(int, struct mips1_tlb *);
332 
333 		for (i = 0; i < mips_num_tlb_entries; i++) {
334 			mips1_TLBRead(i, &tlb);
335 			db_printf("TLB%c%2d Hi 0x%08x Lo 0x%08x",
336 				(tlb.tlb_lo & MIPS1_PG_V) ? ' ' : '*',
337 				i, tlb.tlb_hi,
338 				tlb.tlb_lo & MIPS1_PG_FRAME);
339 			db_printf(" %c%c%c\n",
340 				(tlb.tlb_lo & MIPS1_PG_D) ? 'D' : ' ',
341 				(tlb.tlb_lo & MIPS1_PG_G) ? 'G' : ' ',
342 				(tlb.tlb_lo & MIPS1_PG_N) ? 'N' : ' ');
343 		}
344 	}
345 #endif
346 #ifdef MIPS3_PLUS
347 	if (MIPS_HAS_R4K_MMU) {
348 		struct tlb tlb;
349 		int i;
350 
351 		for (i = 0; i < mips_num_tlb_entries; i++) {
352 #if defined(MIPS3)
353 #if defined(MIPS3_5900)
354 			mips5900_TLBRead(i, &tlb);
355 #else
356 			mips3_TLBRead(i, &tlb);
357 #endif
358 #elif defined(MIPS32)
359 			mips32_TLBRead(i, &tlb);
360 #elif defined(MIPS64)
361 			mips64_TLBRead(i, &tlb);
362 #endif
363 			db_printf("TLB%c%2d Hi 0x%08x ",
364 			(tlb.tlb_lo0 | tlb.tlb_lo1) & MIPS3_PG_V ? ' ' : '*',
365 				i, tlb.tlb_hi);
366 			db_printf("Lo0=0x%08x %c%c attr %x ",
367 				(unsigned)mips_tlbpfn_to_paddr(tlb.tlb_lo0),
368 				(tlb.tlb_lo0 & MIPS3_PG_D) ? 'D' : ' ',
369 				(tlb.tlb_lo0 & MIPS3_PG_G) ? 'G' : ' ',
370 				(tlb.tlb_lo0 >> 3) & 7);
371 			db_printf("Lo1=0x%08x %c%c attr %x sz=%x\n",
372 				(unsigned)mips_tlbpfn_to_paddr(tlb.tlb_lo1),
373 				(tlb.tlb_lo1 & MIPS3_PG_D) ? 'D' : ' ',
374 				(tlb.tlb_lo1 & MIPS3_PG_G) ? 'G' : ' ',
375 				(tlb.tlb_lo1 >> 3) & 7,
376 				tlb.tlb_mask);
377 		}
378 	}
379 #endif
380 }
381 
382 void
383 db_kvtophys_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
384 {
385 
386 	if (!have_addr)
387 		return;
388 	if (MIPS_KSEG2_START <= addr) {
389 		/*
390 		 * Cast the physical address -- some platforms, while
391 		 * being ILP32, may be using 64-bit paddr_t's.
392 		 */
393 		db_printf("0x%lx -> 0x%qx\n", addr,
394 		    (unsigned long long) kvtophys(addr));
395 	} else
396 		printf("not a kernel virtual address\n");
397 }
398 
399 #define	FLDWIDTH	10
400 #define	SHOW32(reg, name)						\
401 do {									\
402 	uint32_t __val;							\
403 									\
404 	asm volatile("mfc0 %0,$" ___STRING(reg) : "=r"(__val));		\
405 	printf("  %s:%*s %#x\n", name, FLDWIDTH - (int) strlen(name),	\
406 	    "", __val);							\
407 } while (0)
408 
409 /* XXX not 64-bit ABI safe! */
410 #define	SHOW64(reg, name)						\
411 do {									\
412 	uint64_t __val;							\
413 									\
414 	asm volatile(							\
415 		".set push 			\n\t"			\
416 		".set mips3			\n\t"			\
417 		".set noat			\n\t"			\
418 		"dmfc0 $1,$" ___STRING(reg) "	\n\t"			\
419 		"dsll %L0,$1,32			\n\t"			\
420 		"dsrl %L0,%L0,32		\n\t"			\
421 		"dsrl %M0,$1,32			\n\t"			\
422 		".set pop"						\
423 	    : "=r"(__val));						\
424 	printf("  %s:%*s %#llx\n", name, FLDWIDTH - (int) strlen(name),	\
425 	    "", __val);							\
426 } while (0)
427 
428 void
429 db_cp0dump_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
430 {
431 
432 	SHOW32(MIPS_COP_0_TLB_INDEX, "index");
433 	SHOW32(MIPS_COP_0_TLB_RANDOM, "random");
434 
435 	if (!MIPS_HAS_R4K_MMU) {
436 		SHOW32(MIPS_COP_0_TLB_LOW, "entrylow");
437 	} else {
438 		if (CPUIS64BITS) {
439 			SHOW64(MIPS_COP_0_TLB_LO0, "entrylo0");
440 			SHOW64(MIPS_COP_0_TLB_LO1, "entrylo1");
441 		} else {
442 			SHOW32(MIPS_COP_0_TLB_LO0, "entrylo0");
443 			SHOW32(MIPS_COP_0_TLB_LO1, "entrylo1");
444 		}
445 	}
446 
447 	if (CPUIS64BITS) {
448 		SHOW64(MIPS_COP_0_TLB_CONTEXT, "context");
449 	} else {
450 		SHOW32(MIPS_COP_0_TLB_CONTEXT, "context");
451 	}
452 
453 	if (MIPS_HAS_R4K_MMU) {
454 		SHOW32(MIPS_COP_0_TLB_PG_MASK, "pagemask");
455 		SHOW32(MIPS_COP_0_TLB_WIRED, "wired");
456 	}
457 
458 	if (CPUIS64BITS) {
459 		SHOW64(MIPS_COP_0_BAD_VADDR, "badvaddr");
460 	} else {
461 		SHOW32(MIPS_COP_0_BAD_VADDR, "badvaddr");
462 	}
463 
464 	if (cpu_arch >= CPU_ARCH_MIPS3) {
465 		SHOW32(MIPS_COP_0_COUNT, "count");
466 	}
467 
468 	if (CPUIS64BITS) {
469 		SHOW64(MIPS_COP_0_TLB_HI, "entryhi");
470 	} else {
471 		SHOW32(MIPS_COP_0_TLB_HI, "entryhi");
472 	}
473 
474 	if (cpu_arch >= CPU_ARCH_MIPS3) {
475 		SHOW32(MIPS_COP_0_COMPARE, "compare");
476 	}
477 
478 	SHOW32(MIPS_COP_0_STATUS, "status");
479 	SHOW32(MIPS_COP_0_CAUSE, "cause");
480 
481 	if (CPUIS64BITS) {
482 		SHOW64(MIPS_COP_0_EXC_PC, "epc");
483 	} else {
484 		SHOW32(MIPS_COP_0_EXC_PC, "epc");
485 	}
486 
487 	SHOW32(MIPS_COP_0_PRID, "prid");
488 	SHOW32(MIPS_COP_0_CONFIG, "config");
489 
490 #if defined(MIPS32) || defined(MIPS64)
491 	if (CPUISMIPSNN) {
492 		uint32_t val;
493 
494 		val = mipsNN_cp0_config1_read();
495 		printf("  config1:    %#x\n", val);
496 	}
497 #endif
498 
499 	if (MIPS_HAS_LLSC) {
500 		if (CPUISMIPS64) {
501 			SHOW64(MIPS_COP_0_LLADDR, "lladdr");
502 			SHOW64(MIPS_COP_0_WATCH_LO, "watchlo");
503 		} else {
504 			SHOW32(MIPS_COP_0_LLADDR, "lladdr");
505 			SHOW32(MIPS_COP_0_WATCH_LO, "watchlo");
506 		}
507 
508 		SHOW32(MIPS_COP_0_WATCH_HI, "watchhi");
509 
510 		if (CPUIS64BITS) {
511 			SHOW64(MIPS_COP_0_TLB_XCONTEXT, "xcontext");
512 		}
513 
514 		if (CPUISMIPSNN) {
515 			if (CPUISMIPS64) {
516 				SHOW64(MIPS_COP_0_PERFCNT, "perfcnt");
517 			} else {
518 				SHOW32(MIPS_COP_0_PERFCNT, "perfcnt");
519 			}
520 		}
521 
522 		SHOW32(MIPS_COP_0_ECC, "ecc");
523 		SHOW32(MIPS_COP_0_CACHE_ERR, "cacherr");
524 		SHOW32(MIPS_COP_0_TAG_LO, "cachelo");
525 		SHOW32(MIPS_COP_0_TAG_HI, "cachehi");
526 
527 		if (CPUIS64BITS) {
528 			SHOW64(MIPS_COP_0_ERROR_PC, "errorpc");
529 		} else {
530 			SHOW32(MIPS_COP_0_ERROR_PC, "errorpc");
531 		}
532 	}
533 }
534 
535 const struct db_command db_machine_command_table[] = {
536 	{ "kvtop",	db_kvtophys_cmd,	0,	0 },
537 	{ "tlb",	db_tlbdump_cmd,		0,	0 },
538 	{ "cp0",	db_cp0dump_cmd,		0,	0 },
539 	{ (char *)0, }
540 };
541 #endif	/* !KGDB */
542 
543 /*
544  * Determine whether the instruction involves a delay slot.
545  */
546 boolean_t
547 inst_branch(int inst)
548 {
549 	InstFmt i;
550 	int delay;
551 
552 	i.word = inst;
553 	delay = 0;
554 	switch (i.JType.op) {
555 	case OP_BCOND:
556 	case OP_J:
557 	case OP_JAL:
558 	case OP_BEQ:
559 	case OP_BNE:
560 	case OP_BLEZ:
561 	case OP_BGTZ:
562 	case OP_BEQL:
563 	case OP_BNEL:
564 	case OP_BLEZL:
565 	case OP_BGTZL:
566 		delay = 1;
567 		break;
568 
569 	case OP_COP0:
570 	case OP_COP1:
571 		switch (i.RType.rs) {
572 		case OP_BCx:
573 		case OP_BCy:
574 			delay = 1;
575 		}
576 		break;
577 
578 	case OP_SPECIAL:
579 		if (i.RType.op == OP_JR || i.RType.op == OP_JALR)
580 			delay = 1;
581 		break;
582 	}
583 	return delay;
584 }
585 
586 /*
587  * Determine whether the instruction calls a function.
588  */
589 boolean_t
590 inst_call(int inst)
591 {
592 	boolean_t call;
593 	InstFmt i;
594 
595 	i.word = inst;
596 	if (i.JType.op == OP_SPECIAL
597 	    && ((i.RType.func == OP_JR && i.RType.rs != 31) ||
598 		i.RType.func == OP_JALR))
599 		call = 1;
600 	else if (i.JType.op == OP_JAL)
601 		call = 1;
602 	else
603 		call = 0;
604 	return call;
605 }
606 
607 /*
608  * Determine whether the instruction returns from a function (j ra).  The
609  * compiler can use this construct for other jumps, but usually will not.
610  * This lets the ddb "next" command to work (also need inst_trap_return()).
611  */
612 boolean_t
613 inst_return(int inst)
614 {
615 	InstFmt i;
616 
617 	i.word = inst;
618 
619 	return (i.JType.op == OP_SPECIAL && i.RType.func == OP_JR &&
620 		i.RType.rs == 31);
621 }
622 
623 /*
624  * Determine whether the instruction makes a jump.
625  */
626 boolean_t
627 inst_unconditional_flow_transfer(int inst)
628 {
629 	InstFmt i;
630 	boolean_t jump;
631 
632 	i.word = inst;
633 	jump = (i.JType.op == OP_J) ||
634 	       (i.JType.op == OP_SPECIAL && i.RType.func == OP_JR);
635 	return jump;
636 }
637 
638 /*
639  * Determine whether the instruction is a load/store as appropriate.
640  */
641 boolean_t
642 inst_load(int inst)
643 {
644 	InstFmt i;
645 
646 	i.word = inst;
647 
648 	switch (i.JType.op) {
649 	case OP_LWC1:
650 	case OP_LB:
651 	case OP_LH:
652 	case OP_LW:
653 	case OP_LD:
654 	case OP_LBU:
655 	case OP_LHU:
656 	case OP_LWU:
657 	case OP_LDL:
658 	case OP_LDR:
659 	case OP_LWL:
660 	case OP_LWR:
661 	case OP_LL:
662 		return 1;
663 	default:
664 		return 0;
665 	}
666 }
667 
668 boolean_t
669 inst_store(int inst)
670 {
671 	InstFmt i;
672 
673 	i.word = inst;
674 
675 	switch (i.JType.op) {
676 	case OP_SWC1:
677 	case OP_SB:
678 	case OP_SH:
679 	case OP_SW:
680 	case OP_SD:
681 	case OP_SDL:
682 	case OP_SDR:
683 	case OP_SWL:
684 	case OP_SWR:
685 	case OP_SCD:
686 		return 1;
687 	default:
688 		return 0;
689 	}
690 }
691 
692 /*
693  * Return the next pc if the given branch is taken.
694  * MachEmulateBranch() runs analysis for branch delay slot.
695  */
696 db_addr_t
697 branch_taken(int inst, db_addr_t pc, db_regs_t *regs)
698 {
699 	vaddr_t ra;
700 	unsigned fpucsr;
701 
702 	fpucsr = curproc ? PCB_FSR(&curproc->p_addr->u_pcb) : 0;
703 	ra = MachEmulateBranch((struct frame *)regs, pc, fpucsr, 0);
704 	return ra;
705 }
706 
707 /*
708  * Return the next pc of an arbitrary instruction.
709  */
710 db_addr_t
711 next_instr_address(db_addr_t pc, boolean_t bd)
712 {
713 	unsigned ins;
714 
715 	if (bd == FALSE)
716 		return (pc + 4);
717 
718 	if (pc < MIPS_KSEG0_START)
719 		ins = fuiword((void *)pc);
720 	else
721 		ins = *(unsigned *)pc;
722 
723 	if (inst_branch(ins) || inst_call(ins) || inst_return(ins))
724 		return (pc + 4);
725 
726 	return (pc);
727 }
728