xref: /netbsd/sys/arch/mips/mips/db_interface.c (revision bf9ec67e)
1 /*	$NetBSD: db_interface.c,v 1.42 2002/03/11 16:39:40 uch 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[0] = f->f_regs[AST];
179 		tfp[1] = f->f_regs[V0];
180 		tfp[2] = f->f_regs[V1];
181 		tfp[3] = f->f_regs[A0];
182 		tfp[4] = f->f_regs[A1];
183 		tfp[5] = f->f_regs[A2];
184 		tfp[6] = f->f_regs[A3];
185 		tfp[7] = f->f_regs[T0];
186 		tfp[8] = f->f_regs[T1];
187 		tfp[9] = f->f_regs[T2];
188 		tfp[10] = f->f_regs[T3];
189 		tfp[11] = f->f_regs[T4];
190 		tfp[12] = f->f_regs[T5];
191 		tfp[13] = f->f_regs[T6];
192 		tfp[14] = f->f_regs[T7];
193 		tfp[15] = f->f_regs[T8];
194 		tfp[16] = f->f_regs[T9];
195 		tfp[17] = f->f_regs[RA];
196 		tfp[18] = f->f_regs[SR];
197 		tfp[19] = f->f_regs[MULLO];
198 		tfp[20] = f->f_regs[MULHI];
199 		tfp[21] = 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[0];
236 		f->f_regs[V0] = tfp[1];
237 		f->f_regs[V1] = tfp[2];
238 		f->f_regs[A0] = tfp[3];
239 		f->f_regs[A1] = tfp[4];
240 		f->f_regs[A2] = tfp[5];
241 		f->f_regs[A3] = tfp[6];
242 		f->f_regs[T0] = tfp[7];
243 		f->f_regs[T1] = tfp[8];
244 		f->f_regs[T2] = tfp[9];
245 		f->f_regs[T3] = tfp[10];
246 		f->f_regs[T4] = tfp[11];
247 		f->f_regs[T5] = tfp[12];
248 		f->f_regs[T6] = tfp[13];
249 		f->f_regs[T7] = tfp[14];
250 		f->f_regs[T8] = tfp[15];
251 		f->f_regs[T9] = tfp[16];
252 		f->f_regs[RA] = tfp[17];
253 		f->f_regs[SR] = tfp[18];
254 		f->f_regs[MULLO] = tfp[19];
255 		f->f_regs[MULHI] = tfp[20];
256 		f->f_regs[PC] = tfp[21];
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 - strlen(name), "", __val); \
406 } while (0)
407 
408 /* XXX not 64-bit ABI safe! */
409 #define	SHOW64(reg, name)						\
410 do {									\
411 	uint64_t __val;							\
412 									\
413 	asm volatile(							\
414 		".set push 			\n\t"			\
415 		".set mips3			\n\t"			\
416 		".set noat			\n\t"			\
417 		"dmfc0 $1,$" ___STRING(reg) "	\n\t"			\
418 		"dsll %L0,$1,32			\n\t"			\
419 		"dsrl %L0,%L0,32		\n\t"			\
420 		"dsrl %M0,$1,32			\n\t"			\
421 		".set pop"						\
422 	    : "=r"(__val));						\
423 	printf("  %s:%*s %#llx\n", name, FLDWIDTH - strlen(name), "", __val); \
424 } while (0)
425 
426 void
427 db_cp0dump_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
428 {
429 
430 	SHOW32(MIPS_COP_0_TLB_INDEX, "index");
431 	SHOW32(MIPS_COP_0_TLB_RANDOM, "random");
432 
433 	if (!MIPS_HAS_R4K_MMU) {
434 		SHOW32(MIPS_COP_0_TLB_LOW, "entrylow");
435 	} else {
436 		if (CPUIS64BITS) {
437 			SHOW64(MIPS_COP_0_TLB_LO0, "entrylo0");
438 			SHOW64(MIPS_COP_0_TLB_LO1, "entrylo1");
439 		} else {
440 			SHOW32(MIPS_COP_0_TLB_LO0, "entrylo0");
441 			SHOW32(MIPS_COP_0_TLB_LO1, "entrylo1");
442 		}
443 	}
444 
445 	if (CPUIS64BITS) {
446 		SHOW64(MIPS_COP_0_TLB_CONTEXT, "context");
447 	} else {
448 		SHOW32(MIPS_COP_0_TLB_CONTEXT, "context");
449 	}
450 
451 	if (MIPS_HAS_R4K_MMU) {
452 		SHOW32(MIPS_COP_0_TLB_PG_MASK, "pagemask");
453 		SHOW32(MIPS_COP_0_TLB_WIRED, "wired");
454 	}
455 
456 	if (CPUIS64BITS) {
457 		SHOW64(MIPS_COP_0_BAD_VADDR, "badvaddr");
458 	} else {
459 		SHOW32(MIPS_COP_0_BAD_VADDR, "badvaddr");
460 	}
461 
462 	if (cpu_arch >= CPU_ARCH_MIPS3) {
463 		SHOW32(MIPS_COP_0_COUNT, "count");
464 	}
465 
466 	if (CPUIS64BITS) {
467 		SHOW64(MIPS_COP_0_TLB_HI, "entryhi");
468 	} else {
469 		SHOW32(MIPS_COP_0_TLB_HI, "entryhi");
470 	}
471 
472 	if (cpu_arch >= CPU_ARCH_MIPS3) {
473 		SHOW32(MIPS_COP_0_COMPARE, "compare");
474 	}
475 
476 	SHOW32(MIPS_COP_0_STATUS, "status");
477 	SHOW32(MIPS_COP_0_CAUSE, "cause");
478 
479 	if (CPUIS64BITS) {
480 		SHOW64(MIPS_COP_0_EXC_PC, "epc");
481 	} else {
482 		SHOW32(MIPS_COP_0_EXC_PC, "epc");
483 	}
484 
485 	SHOW32(MIPS_COP_0_PRID, "prid");
486 	SHOW32(MIPS_COP_0_CONFIG, "config");
487 
488 #if defined(MIPS32) || defined(MIPS64)
489 	if (CPUISMIPSNN) {
490 		uint32_t val;
491 
492 		val = mipsNN_cp0_config1_read();
493 		printf("  config1:    %#x\n", val);
494 	}
495 #endif
496 
497 	if (MIPS_HAS_LLSC) {
498 		if (CPUISMIPS64) {
499 			SHOW64(MIPS_COP_0_LLADDR, "lladdr");
500 			SHOW64(MIPS_COP_0_WATCH_LO, "watchlo");
501 		} else {
502 			SHOW32(MIPS_COP_0_LLADDR, "lladdr");
503 			SHOW32(MIPS_COP_0_WATCH_LO, "watchlo");
504 		}
505 
506 		SHOW32(MIPS_COP_0_WATCH_HI, "watchhi");
507 
508 		if (CPUIS64BITS) {
509 			SHOW64(MIPS_COP_0_TLB_XCONTEXT, "xcontext");
510 		}
511 
512 		if (CPUISMIPSNN) {
513 			if (CPUISMIPS64) {
514 				SHOW64(MIPS_COP_0_PERFCNT, "perfcnt");
515 			} else {
516 				SHOW32(MIPS_COP_0_PERFCNT, "perfcnt");
517 			}
518 		}
519 
520 		SHOW32(MIPS_COP_0_ECC, "ecc");
521 		SHOW32(MIPS_COP_0_CACHE_ERR, "cacherr");
522 		SHOW32(MIPS_COP_0_TAG_LO, "cachelo");
523 		SHOW32(MIPS_COP_0_TAG_HI, "cachehi");
524 
525 		if (CPUIS64BITS) {
526 			SHOW64(MIPS_COP_0_ERROR_PC, "errorpc");
527 		} else {
528 			SHOW32(MIPS_COP_0_ERROR_PC, "errorpc");
529 		}
530 	}
531 }
532 
533 const struct db_command db_machine_command_table[] = {
534 	{ "kvtop",	db_kvtophys_cmd,	0,	0 },
535 	{ "tlb",	db_tlbdump_cmd,		0,	0 },
536 	{ "cp0",	db_cp0dump_cmd,		0,	0 },
537 	{ (char *)0, }
538 };
539 #endif	/* !KGDB */
540 
541 /*
542  * Determine whether the instruction involves a delay slot.
543  */
544 boolean_t
545 inst_branch(int inst)
546 {
547 	InstFmt i;
548 	int delay;
549 
550 	i.word = inst;
551 	delay = 0;
552 	switch (i.JType.op) {
553 	case OP_BCOND:
554 	case OP_J:
555 	case OP_JAL:
556 	case OP_BEQ:
557 	case OP_BNE:
558 	case OP_BLEZ:
559 	case OP_BGTZ:
560 	case OP_BEQL:
561 	case OP_BNEL:
562 	case OP_BLEZL:
563 	case OP_BGTZL:
564 		delay = 1;
565 		break;
566 
567 	case OP_COP0:
568 	case OP_COP1:
569 		switch (i.RType.rs) {
570 		case OP_BCx:
571 		case OP_BCy:
572 			delay = 1;
573 		}
574 		break;
575 
576 	case OP_SPECIAL:
577 		if (i.RType.op == OP_JR || i.RType.op == OP_JALR)
578 			delay = 1;
579 		break;
580 	}
581 	return delay;
582 }
583 
584 /*
585  * Determine whether the instruction calls a function.
586  */
587 boolean_t
588 inst_call(int inst)
589 {
590 	boolean_t call;
591 	InstFmt i;
592 
593 	i.word = inst;
594 	if (i.JType.op == OP_SPECIAL
595 	    && ((i.RType.func == OP_JR && i.RType.rs != 31) ||
596 		i.RType.func == OP_JALR))
597 		call = 1;
598 	else if (i.JType.op == OP_JAL)
599 		call = 1;
600 	else
601 		call = 0;
602 	return call;
603 }
604 
605 /*
606  * Determine whether the instruction returns from a function (j ra).  The
607  * compiler can use this construct for other jumps, but usually will not.
608  * This lets the ddb "next" command to work (also need inst_trap_return()).
609  */
610 boolean_t
611 inst_return(int inst)
612 {
613 	InstFmt i;
614 
615 	i.word = inst;
616 
617 	return (i.JType.op == OP_SPECIAL && i.RType.func == OP_JR &&
618 		i.RType.rs == 31);
619 }
620 
621 /*
622  * Determine whether the instruction makes a jump.
623  */
624 boolean_t
625 inst_unconditional_flow_transfer(int inst)
626 {
627 	InstFmt i;
628 	boolean_t jump;
629 
630 	i.word = inst;
631 	jump = (i.JType.op == OP_J) ||
632 	       (i.JType.op == OP_SPECIAL && i.RType.func == OP_JR);
633 	return jump;
634 }
635 
636 /*
637  * Determine whether the instruction is a load/store as appropriate.
638  */
639 boolean_t
640 inst_load(int inst)
641 {
642 	InstFmt i;
643 
644 	i.word = inst;
645 
646 	switch (i.JType.op) {
647 	case OP_LWC1:
648 	case OP_LB:
649 	case OP_LH:
650 	case OP_LW:
651 	case OP_LD:
652 	case OP_LBU:
653 	case OP_LHU:
654 	case OP_LWU:
655 	case OP_LDL:
656 	case OP_LDR:
657 	case OP_LWL:
658 	case OP_LWR:
659 	case OP_LL:
660 		return 1;
661 	default:
662 		return 0;
663 	}
664 }
665 
666 boolean_t
667 inst_store(int inst)
668 {
669 	InstFmt i;
670 
671 	i.word = inst;
672 
673 	switch (i.JType.op) {
674 	case OP_SWC1:
675 	case OP_SB:
676 	case OP_SH:
677 	case OP_SW:
678 	case OP_SD:
679 	case OP_SDL:
680 	case OP_SDR:
681 	case OP_SWL:
682 	case OP_SWR:
683 	case OP_SCD:
684 		return 1;
685 	default:
686 		return 0;
687 	}
688 }
689 
690 /*
691  * Return the next pc if the given branch is taken.
692  * MachEmulateBranch() runs analysis for branch delay slot.
693  */
694 db_addr_t
695 branch_taken(int inst, db_addr_t pc, db_regs_t *regs)
696 {
697 	vaddr_t ra;
698 	unsigned fpucsr;
699 
700 	fpucsr = curproc ? PCB_FSR(&curproc->p_addr->u_pcb) : 0;
701 	ra = MachEmulateBranch((struct frame *)regs, pc, fpucsr, 0);
702 	return ra;
703 }
704 
705 /*
706  * Return the next pc of an arbitrary instruction.
707  */
708 db_addr_t
709 next_instr_address(db_addr_t pc, boolean_t bd)
710 {
711 	unsigned ins;
712 
713 	if (bd == FALSE)
714 		return (pc + 4);
715 
716 	if (pc < MIPS_KSEG0_START)
717 		ins = fuiword((void *)pc);
718 	else
719 		ins = *(unsigned *)pc;
720 
721 	if (inst_branch(ins) || inst_call(ins) || inst_return(ins))
722 		return (pc + 4);
723 
724 	return (pc);
725 }
726