Home | History | Annotate | Line # | Download | only in mips
      1 /*	$NetBSD: mips_emul.c,v 1.32 2025/05/03 02:00:46 riastradh Exp $ */
      2 
      3 /*
      4  * Copyright (c) 1999 Shuichiro URATA.  All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. The name of the author may not be used to endorse or promote products
     15  *    derived from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 __KERNEL_RCSID(0, "$NetBSD: mips_emul.c,v 1.32 2025/05/03 02:00:46 riastradh Exp $");
     31 
     32 #ifdef _KERNEL_OPT
     33 #include "opt_cputype.h"
     34 #endif
     35 
     36 #include <sys/param.h>
     37 #include <sys/systm.h>
     38 #include <sys/cpu.h>
     39 #include <sys/proc.h>
     40 
     41 #include <mips/locore.h>
     42 #include <mips/mips_opcode.h>
     43 
     44 #include <mips/reg.h>
     45 #include <mips/regnum.h>			/* symbolic register indices */
     46 #include <mips/pcb.h>
     47 #include <mips/vmparam.h>			/* for VM_MAX_ADDRESS */
     48 #include <mips/trap.h>
     49 
     50 static inline void	send_sigsegv(intptr_t, uint32_t, struct trapframe *,
     51 			    uint32_t);
     52 static inline void	update_pc(struct trapframe *, uint32_t);
     53 
     54 static void	mips_emul_ll(uint32_t, struct trapframe *, uint32_t);
     55 static void	mips_emul_sc(uint32_t, struct trapframe *, uint32_t);
     56 
     57 /*
     58  * MIPS2 LL instruction emulation state
     59  */
     60 struct {
     61 	struct lwp *lwp;
     62 	vaddr_t addr;
     63 	uint32_t value;
     64 } llstate;
     65 
     66 /*
     67  * Analyse 'next' PC address taking account of branch/jump instructions
     68  */
     69 vaddr_t
     70 mips_emul_branch(struct trapframe *tf, vaddr_t instpc, uint32_t fpuCSR,
     71     bool allowNonBranch)
     72 {
     73 #define	BRANCHTARGET(pc, i) (4 + (pc) + ((short)(i).IType.imm << 2))
     74 	InstFmt inst;
     75 	vaddr_t nextpc;
     76 
     77 	if (instpc < MIPS_KSEG0_START) {
     78 		inst.word = mips_ufetch32((void *)instpc);
     79 	} else {
     80 		inst.word = *(uint32_t *)instpc;
     81 	}
     82 
     83 	switch ((int)inst.JType.op) {
     84 	case OP_SPECIAL:
     85 		if (inst.RType.func == OP_JR || inst.RType.func == OP_JALR)
     86 			nextpc = tf->tf_regs[inst.RType.rs];
     87 		else if (allowNonBranch)
     88 			nextpc = instpc + 4;
     89 		else
     90 			panic("%s: %s instruction %08x at pc 0x%"PRIxVADDR,
     91 			    __func__, "non-branch", inst.word, instpc);
     92 		break;
     93 
     94 	case OP_REGIMM:
     95 		switch ((int)inst.IType.rt) {
     96 		case OP_BLTZ:
     97 		case OP_BLTZAL:
     98 		case OP_BLTZL:		/* squashed */
     99 		case OP_BLTZALL:	/* squashed */
    100 			if ((int)(tf->tf_regs[inst.RType.rs]) < 0)
    101 				nextpc = BRANCHTARGET(instpc, inst);
    102 			else
    103 				nextpc = instpc + 8;
    104 			break;
    105 
    106 		case OP_BGEZ:
    107 		case OP_BGEZAL:
    108 		case OP_BGEZL:		/* squashed */
    109 		case OP_BGEZALL:	/* squashed */
    110 			if ((int)(tf->tf_regs[inst.RType.rs]) >= 0)
    111 				nextpc = BRANCHTARGET(instpc, inst);
    112 			else
    113 				nextpc = instpc + 8;
    114 			break;
    115 
    116 		default:
    117 			panic("%s: %s instruction 0x%08x at pc 0x%"PRIxVADDR,
    118 			    __func__, "bad branch", inst.word, instpc);
    119 		}
    120 		break;
    121 
    122 	case OP_J:
    123 	case OP_JAL:
    124 		nextpc = (inst.JType.target << 2) |
    125 			((intptr_t)instpc & 0xF0000000);
    126 		break;
    127 
    128 	case OP_BEQ:
    129 	case OP_BEQL:	/* squashed */
    130 		if (tf->tf_regs[inst.RType.rs] == tf->tf_regs[inst.RType.rt])
    131 			nextpc = BRANCHTARGET(instpc, inst);
    132 		else
    133 			nextpc = instpc + 8;
    134 		break;
    135 
    136 	case OP_BNE:
    137 	case OP_BNEL:	/* squashed */
    138 		if (tf->tf_regs[inst.RType.rs] != tf->tf_regs[inst.RType.rt])
    139 			nextpc = BRANCHTARGET(instpc, inst);
    140 		else
    141 			nextpc = instpc + 8;
    142 		break;
    143 
    144 	case OP_BLEZ:
    145 	case OP_BLEZL:	/* squashed */
    146 		if ((int)(tf->tf_regs[inst.RType.rs]) <= 0)
    147 			nextpc = BRANCHTARGET(instpc, inst);
    148 		else
    149 			nextpc = instpc + 8;
    150 		break;
    151 
    152 	case OP_BGTZ:
    153 	case OP_BGTZL:	/* squashed */
    154 		if ((int)(tf->tf_regs[inst.RType.rs]) > 0)
    155 			nextpc = BRANCHTARGET(instpc, inst);
    156 		else
    157 			nextpc = instpc + 8;
    158 		break;
    159 
    160 	case OP_COP1:
    161 		if (inst.RType.rs == OP_BCx || inst.RType.rs == OP_BCy) {
    162 			int condition = (fpuCSR & MIPS_FCSR_FCC0) != 0;
    163 			if ((inst.RType.rt & COPz_BC_TF_MASK) != COPz_BC_TRUE)
    164 				condition = !condition;
    165 			if (condition)
    166 				nextpc = BRANCHTARGET(instpc, inst);
    167 			else
    168 				nextpc = instpc + 8;
    169 		}
    170 		else if (allowNonBranch)
    171 			nextpc = instpc + 4;
    172 		else
    173 			panic("%s: %s instruction 0x%08x at pc 0x%"PRIxVADDR,
    174 			    __func__, "bad COP1 branch", inst.word, instpc);
    175 		break;
    176 
    177 	default:
    178 		if (!allowNonBranch)
    179 			panic("%s: %s instruction 0x%08x at pc 0x%"PRIxVADDR,
    180 			    __func__, "non-branch", inst.word, instpc);
    181 		nextpc = instpc + 4;
    182 	}
    183 	KASSERT((nextpc & 0x3) == 0);
    184 	return nextpc;
    185 #undef	BRANCHTARGET
    186 }
    187 
    188 /*
    189  * Emulate instructions (including floating-point instructions)
    190  */
    191 void
    192 mips_emul_inst(uint32_t status, uint32_t cause, vaddr_t opc,
    193     struct trapframe *tf)
    194 {
    195 	uint32_t inst;
    196 	ksiginfo_t ksi;
    197 	int code = ILL_ILLOPC;
    198 
    199 	/*
    200 	 *  Fetch the instruction.
    201 	 */
    202 	if (cause & MIPS_CR_BR_DELAY)
    203 		inst = mips_ufetch32((uint32_t *)opc+1);
    204 	else
    205 		inst = mips_ufetch32((uint32_t *)opc);
    206 
    207 	switch (((InstFmt)inst).FRType.op) {
    208 	case OP_LL:
    209 		mips_emul_ll(inst, tf, cause);
    210 		break;
    211 	case OP_SC:
    212 		mips_emul_sc(inst, tf, cause);
    213 		break;
    214 	case OP_SPECIAL:
    215 		mips_emul_special(inst, tf, cause);
    216 		break;
    217 	case OP_SPECIAL3:
    218 		mips_emul_special3(inst, tf, cause);
    219 		break;
    220 	case OP_COP1:
    221 #if defined(FPEMUL)
    222 		mips_emul_fp(inst, tf, cause);
    223 		break;
    224 #endif
    225 	case OP_LWC1:
    226 #if defined(FPEMUL)
    227 		mips_emul_lwc1(inst, tf, cause);
    228 		break;
    229 #endif
    230 	case OP_LDC1:
    231 #if defined(FPEMUL)
    232 		mips_emul_ldc1(inst, tf, cause);
    233 		break;
    234 #endif
    235 	case OP_SWC1:
    236 #if defined(FPEMUL)
    237 		mips_emul_swc1(inst, tf, cause);
    238 		break;
    239 #endif
    240 	case OP_SDC1:
    241 #if defined(FPEMUL)
    242 		mips_emul_sdc1(inst, tf, cause);
    243 		break;
    244 #else
    245 		code = ILL_COPROC;
    246 		/* FALLTHROUGH */
    247 #endif
    248 	default:
    249 #ifdef DEBUG
    250 		printf("pid %d (%s): trap: bad insn @ %#"PRIxVADDR
    251 		    " cause %#x status %#"PRIxREGISTER" insn %#x code %d\n",
    252 		    curproc->p_pid, curproc->p_comm, opc,
    253 		    cause, tf->tf_regs[_R_SR], inst, code);
    254 #endif
    255 		tf->tf_regs[_R_CAUSE] = cause;
    256 		tf->tf_regs[_R_BADVADDR] = opc;
    257 		KSI_INIT_TRAP(&ksi);
    258 		ksi.ksi_signo = SIGILL;
    259 		ksi.ksi_trap = cause; /* XXX */
    260 		ksi.ksi_code = code;
    261 		ksi.ksi_addr = (void *)opc;
    262 		(*curproc->p_emul->e_trapsignal)(curlwp, &ksi);
    263 		break;
    264 	}
    265 }
    266 
    267 static inline void
    268 send_sigsegv(intptr_t vaddr, uint32_t exccode, struct trapframe *tf,
    269     uint32_t cause)
    270 {
    271 	ksiginfo_t ksi;
    272 	cause = (cause & ~0xFF) | (exccode << MIPS_CR_EXC_CODE_SHIFT);
    273 	tf->tf_regs[_R_CAUSE] = cause;
    274 	tf->tf_regs[_R_BADVADDR] = vaddr;
    275 	KSI_INIT_TRAP(&ksi);
    276 	ksi.ksi_signo = SIGSEGV;
    277 	ksi.ksi_trap = cause;
    278 	ksi.ksi_code = SEGV_MAPERR;
    279 	ksi.ksi_addr = (void *)vaddr;
    280 	(*curproc->p_emul->e_trapsignal)(curlwp, &ksi);
    281 }
    282 
    283 static inline void
    284 update_pc(struct trapframe *tf, uint32_t cause)
    285 {
    286 
    287 	if (cause & MIPS_CR_BR_DELAY)
    288 		tf->tf_regs[_R_PC] =
    289 		    mips_emul_branch(tf, tf->tf_regs[_R_PC],
    290 			PCB_FSR(curpcb), 0);
    291 	else
    292 		tf->tf_regs[_R_PC] += 4;
    293 }
    294 
    295 /*
    296  * MIPS2 LL instruction
    297  */
    298 void
    299 mips_emul_ll(uint32_t inst, struct trapframe *tf, uint32_t cause)
    300 {
    301 	intptr_t	vaddr;
    302 	int16_t		offset;
    303 	void		*t;
    304 
    305 	offset = inst & 0xFFFF;
    306 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    307 
    308 	/* segment and alignment check */
    309 	if (vaddr < 0 || (vaddr & 3)) {
    310 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    311 		return;
    312 	}
    313 
    314 	t = &(tf->tf_regs[(inst>>16)&0x1F]);
    315 
    316 	if (copyin((void *)vaddr, t, 4) != 0) {
    317 		send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    318 		return;
    319 	}
    320 
    321 	llstate.lwp = curlwp;
    322 	llstate.addr = vaddr;
    323 	llstate.value = *((uint32_t *)t);
    324 
    325 	update_pc(tf, cause);
    326 }
    327 
    328 /*
    329  * MIPS2 SC instruction
    330  */
    331 void
    332 mips_emul_sc(uint32_t inst, struct trapframe *tf, uint32_t cause)
    333 {
    334 	intptr_t	vaddr;
    335 	uint32_t	value;
    336 	int16_t		offset;
    337 	mips_reg_t	*t;
    338 
    339 	offset = inst & 0xFFFF;
    340 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    341 
    342 	/* segment and alignment check */
    343 	if (vaddr < 0 || (vaddr & 3)) {
    344 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    345 		return;
    346 	}
    347 
    348 	t = (mips_reg_t *)&(tf->tf_regs[(inst>>16)&0x1F]);
    349 
    350 	/*
    351 	 * Check that the process and address match the last
    352 	 * LL instruction.
    353 	 */
    354 	if (curlwp == llstate.lwp && vaddr == llstate.addr) {
    355 		llstate.lwp = NULL;
    356 		/*
    357 		 * Check that the data at the address hasn't changed
    358 		 * since the LL instruction.
    359 		 */
    360 		if (copyin((void *)vaddr, &value, 4) != 0) {
    361 			send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    362 			return;
    363 		}
    364 		if (value == llstate.value) {
    365 			/* SC successful */
    366 			if (copyout(t, (void *)vaddr, 4) != 0) {
    367 				send_sigsegv(vaddr, T_TLB_ST_MISS,
    368 				    tf, cause);
    369 				return;
    370 			}
    371 			*t = 1;
    372 			update_pc(tf, cause);
    373 			return;
    374 		}
    375 	}
    376 
    377 	/* SC failed */
    378 	*t = 0;
    379 	update_pc(tf, cause);
    380 }
    381 
    382 void
    383 mips_emul_special(uint32_t inst, struct trapframe *tf, uint32_t cause)
    384 {
    385 	ksiginfo_t ksi;
    386 	const InstFmt instfmt = { .word = inst };
    387 
    388 	switch (instfmt.RType.func) {
    389 	case OP_SYNC:
    390 		/* nothing */
    391 		break;
    392 	default:
    393 		tf->tf_regs[_R_CAUSE] = cause;
    394 		tf->tf_regs[_R_BADVADDR] = tf->tf_regs[_R_PC];
    395 		KSI_INIT_TRAP(&ksi);
    396 		ksi.ksi_signo = SIGILL;
    397 		ksi.ksi_trap = cause;
    398 		ksi.ksi_code = ILL_ILLOPC;
    399 		ksi.ksi_addr = (void *)(intptr_t)tf->tf_regs[_R_PC];
    400 		(*curproc->p_emul->e_trapsignal)(curlwp, &ksi);
    401 		break;
    402 	}
    403 
    404 	update_pc(tf, cause);
    405 }
    406 
    407 void
    408 mips_emul_special3(uint32_t inst, struct trapframe *tf, uint32_t cause)
    409 {
    410 	ksiginfo_t ksi;
    411 	const InstFmt instfmt = { .word = inst };
    412 	switch (instfmt.RType.func) {
    413 	case OP_LX: {
    414 		const intptr_t vaddr = tf->tf_regs[instfmt.RType.rs]
    415 		    + tf->tf_regs[instfmt.RType.rt];
    416 		mips_reg_t r;
    417 		int error = EFAULT;
    418 		if (vaddr < 0) {
    419 		    addr_err:
    420 			send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    421 			return;
    422 		}
    423 		switch (instfmt.RType.shamt) {
    424 #if !defined(__mips_o32)
    425 		case OP_LX_LDX: {
    426 			uint64_t tmp64;
    427 			if (vaddr & 7)
    428 				goto addr_err;
    429 			error = copyin((void *)vaddr, &tmp64, sizeof(tmp64));
    430 			r = tmp64;
    431 			break;
    432 		}
    433 #endif
    434 		case OP_LX_LWX: {
    435 			int32_t tmp32;
    436 			if (vaddr & 3)
    437 				goto addr_err;
    438 			error = copyin((void *)vaddr, &tmp32, sizeof(tmp32));
    439 			r = tmp32;
    440 			break;
    441 		}
    442 		case OP_LX_LHX: {
    443 			int16_t tmp16;
    444 			if (vaddr & 1)
    445 				goto addr_err;
    446 			error = copyin((void *)vaddr, &tmp16, sizeof(tmp16));
    447 			r = tmp16;
    448 			break;
    449 		}
    450 		case OP_LX_LBUX: {
    451 			uint8_t tmp8;
    452 			error = copyin((void *)vaddr, &tmp8, sizeof(tmp8));
    453 			r = tmp8;
    454 			break;
    455 		}
    456 		default:
    457 			goto illopc;
    458 		}
    459 		if (error) {
    460 			send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    461 			return;
    462 		}
    463 		tf->tf_regs[instfmt.RType.rd] = r;
    464 		break;
    465 	}
    466 	case OP_RDHWR:
    467 		switch (instfmt.RType.rd) {
    468 		case MIPS_HWR_ULR:
    469 			tf->tf_regs[instfmt.RType.rt] =
    470 			    (mips_reg_t)(intptr_t)curlwp->l_private;
    471 			goto done;
    472 		}
    473 		/* FALLTHROUGH */
    474 	illopc:
    475 	default:
    476 		tf->tf_regs[_R_CAUSE] = cause;
    477 		tf->tf_regs[_R_BADVADDR] = tf->tf_regs[_R_PC];
    478 		KSI_INIT_TRAP(&ksi);
    479 		ksi.ksi_signo = SIGILL;
    480 		ksi.ksi_trap = cause;
    481 		ksi.ksi_code = ILL_ILLOPC;
    482 		ksi.ksi_addr = (void *)(intptr_t)tf->tf_regs[_R_PC];
    483 		(*curproc->p_emul->e_trapsignal)(curlwp, &ksi);
    484 		return;
    485 	}
    486 done:
    487 	update_pc(tf, cause);
    488 }
    489 
    490 #if defined(FPEMUL)
    491 
    492 #define LWSWC1_MAXLOOP	12
    493 
    494 void
    495 mips_emul_lwc1(uint32_t inst, struct trapframe *tf, uint32_t cause)
    496 {
    497 	intptr_t	vaddr;
    498 	int16_t		offset;
    499 	void		*t;
    500 	mips_reg_t	pc;
    501 	int		i;
    502 
    503 	offset = inst & 0xFFFF;
    504 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    505 
    506 	/* segment and alignment check */
    507 	if (vaddr < 0 || (vaddr & 3)) {
    508 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    509 		return;
    510 	}
    511 
    512 	/* NewABI FIXME */
    513 	t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]);
    514 
    515 	if (copyin((void *)vaddr, t, 4) != 0) {
    516 		send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    517 		return;
    518 	}
    519 
    520 	pc = tf->tf_regs[_R_PC];
    521 	update_pc(tf, cause);
    522 
    523 	if (cause & MIPS_CR_BR_DELAY)
    524 		return;
    525 
    526 	for (i = 1; i < LWSWC1_MAXLOOP; i++) {
    527 		if (mips_btop(tf->tf_regs[_R_PC]) != mips_btop(pc))
    528 			return;
    529 
    530 		vaddr = tf->tf_regs[_R_PC];	/* XXX truncates to 32 bits */
    531 		inst = mips_ufetch32((uint32_t *)vaddr);
    532 		if (((InstFmt)inst).FRType.op != OP_LWC1)
    533 			return;
    534 
    535 		offset = inst & 0xFFFF;
    536 		vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    537 
    538 		/* segment and alignment check */
    539 		if (vaddr < 0 || (vaddr & 3)) {
    540 			send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    541 			return;
    542 		}
    543 
    544 		/* NewABI FIXME */
    545 		t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]);
    546 
    547 		if (copyin((void *)vaddr, t, 4) != 0) {
    548 			send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    549 			return;
    550 		}
    551 
    552 		pc = tf->tf_regs[_R_PC];
    553 		update_pc(tf, cause);
    554 	}
    555 }
    556 
    557 void
    558 mips_emul_ldc1(uint32_t inst, struct trapframe *tf, uint32_t cause)
    559 {
    560 	intptr_t	vaddr;
    561 	int16_t		offset;
    562 	void		*t;
    563 
    564 	offset = inst & 0xFFFF;
    565 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    566 
    567 	/* segment and alignment check */
    568 	if (vaddr < 0  || (vaddr & 7)) {
    569 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    570 		return;
    571 	}
    572 
    573 	/* NewABI FIXME */
    574 	t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1E]);
    575 
    576 	if (copyin((void *)vaddr, t, 8) != 0) {
    577 		send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    578 		return;
    579 	}
    580 
    581 	update_pc(tf, cause);
    582 }
    583 
    584 void
    585 mips_emul_swc1(uint32_t inst, struct trapframe *tf, uint32_t cause)
    586 {
    587 	intptr_t	vaddr;
    588 	int16_t		offset;
    589 	void		*t;
    590 	mips_reg_t	pc;
    591 	int		i;
    592 
    593 	offset = inst & 0xFFFF;
    594 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    595 
    596 	/* segment and alignment check */
    597 	if (vaddr < 0 || (vaddr & 3)) {
    598 		send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
    599 		return;
    600 	}
    601 
    602 	/* NewABI FIXME */
    603 	t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]);
    604 
    605 	if (copyout(t, (void *)vaddr, 4) != 0) {
    606 		send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
    607 		return;
    608 	}
    609 
    610 	pc = tf->tf_regs[_R_PC];
    611 	update_pc(tf, cause);
    612 
    613 	if (cause & MIPS_CR_BR_DELAY)
    614 		return;
    615 
    616 	for (i = 1; i < LWSWC1_MAXLOOP; i++) {
    617 		if (mips_btop(tf->tf_regs[_R_PC]) != mips_btop(pc))
    618 			return;
    619 
    620 		vaddr = tf->tf_regs[_R_PC];	/* XXX truncates to 32 bits */
    621 		inst = mips_ufetch32((uint32_t *)vaddr);
    622 		if (((InstFmt)inst).FRType.op != OP_SWC1)
    623 			return;
    624 
    625 		offset = inst & 0xFFFF;
    626 		vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    627 
    628 		/* segment and alignment check */
    629 		if (vaddr < 0 || (vaddr & 3)) {
    630 			send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
    631 			return;
    632 		}
    633 
    634 		/* NewABI FIXME */
    635 		t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1F]);
    636 
    637 		if (copyout(t, (void *)vaddr, 4) != 0) {
    638 			send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
    639 			return;
    640 		}
    641 
    642 		pc = tf->tf_regs[_R_PC];
    643 		update_pc(tf, cause);
    644 	}
    645 }
    646 
    647 void
    648 mips_emul_sdc1(uint32_t inst, struct trapframe *tf, uint32_t cause)
    649 {
    650 	intptr_t	vaddr;
    651 	int16_t		offset;
    652 	void		*t;
    653 
    654 	offset = inst & 0xFFFF;
    655 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    656 
    657 	/* segment and alignment check */
    658 	if (vaddr < 0 || (vaddr & 7)) {
    659 		send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
    660 		return;
    661 	}
    662 
    663 	/* NewABI FIXME */
    664 	t = &(curpcb->pcb_fpregs.r_regs[(inst>>16)&0x1E]);
    665 
    666 	if (copyout(t, (void *)vaddr, 8) != 0) {
    667 		send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
    668 		return;
    669 	}
    670 
    671 	update_pc(tf, cause);
    672 }
    673 
    674 void
    675 mips_emul_lb(uint32_t inst, struct trapframe *tf, uint32_t cause)
    676 {
    677 	intptr_t	vaddr;
    678 	int16_t		offset;
    679 	int8_t		x;
    680 
    681 	offset = inst & 0xFFFF;
    682 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    683 
    684 	/* segment check */
    685 	if (vaddr < 0) {
    686 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    687 		return;
    688 	}
    689 
    690 	if (copyin((void *)vaddr, &x, 1) != 0) {
    691 		send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    692 		return;
    693 	}
    694 
    695 	tf->tf_regs[(inst>>16)&0x1F] = x;
    696 
    697 	update_pc(tf, cause);
    698 }
    699 
    700 void
    701 mips_emul_lbu(uint32_t inst, struct trapframe *tf, uint32_t cause)
    702 {
    703 	intptr_t	vaddr;
    704 	int16_t		offset;
    705 	uint8_t		x;
    706 
    707 	offset = inst & 0xFFFF;
    708 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    709 
    710 	/* segment check */
    711 	if (vaddr < 0) {
    712 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    713 		return;
    714 	}
    715 
    716 	if (copyin((void *)vaddr, &x, 1) != 0) {
    717 		send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    718 		return;
    719 	}
    720 
    721 	tf->tf_regs[(inst>>16)&0x1F] = x;
    722 
    723 	update_pc(tf, cause);
    724 }
    725 
    726 void
    727 mips_emul_lh(uint32_t inst, struct trapframe *tf, uint32_t cause)
    728 {
    729 	intptr_t	vaddr;
    730 	int16_t		offset;
    731 	int16_t		x;
    732 
    733 	offset = inst & 0xFFFF;
    734 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    735 
    736 	/* segment and alignment check */
    737 	if (vaddr < 0 || (vaddr & 1)) {
    738 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    739 		return;
    740 	}
    741 
    742 	if (copyin((void *)vaddr, &x, 2) != 0) {
    743 		send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    744 		return;
    745 	}
    746 
    747 	tf->tf_regs[(inst>>16)&0x1F] = x;
    748 
    749 	update_pc(tf, cause);
    750 }
    751 
    752 void
    753 mips_emul_lhu(uint32_t inst, struct trapframe *tf, uint32_t cause)
    754 {
    755 	intptr_t	vaddr;
    756 	int16_t		offset;
    757 	uint16_t	x;
    758 
    759 	offset = inst & 0xFFFF;
    760 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    761 
    762 	/* segment and alignment check */
    763 	if (vaddr < 0 || (vaddr & 1)) {
    764 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    765 		return;
    766 	}
    767 
    768 	if (copyin((void *)vaddr, &x, 2) != 0) {
    769 		send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    770 		return;
    771 	}
    772 
    773 	tf->tf_regs[(inst>>16)&0x1F] = (mips_ureg_t)x;
    774 
    775 	update_pc(tf, cause);
    776 }
    777 
    778 void
    779 mips_emul_lw(uint32_t inst, struct trapframe *tf, uint32_t cause)
    780 {
    781 	intptr_t	vaddr;
    782 	int16_t		offset;
    783 	int32_t		x;
    784 
    785 	offset = inst & 0xFFFF;
    786 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    787 
    788 	/* segment and alignment check */
    789 	if (vaddr < 0 || (vaddr & 3)) {
    790 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    791 		return;
    792 	}
    793 
    794 	if (copyin((void *)vaddr, &x, 4) != 0) {
    795 		send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    796 		return;
    797 	}
    798 
    799 	tf->tf_regs[(inst>>16)&0x1F] = x;
    800 
    801 	update_pc(tf, cause);
    802 }
    803 
    804 void
    805 mips_emul_lwl(uint32_t inst, struct trapframe *tf, uint32_t cause)
    806 {
    807 	intptr_t	vaddr;
    808 	uint32_t	a, x, shift;
    809 	int16_t		offset;
    810 
    811 	offset = inst & 0xFFFF;
    812 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    813 
    814 	/* segment check */
    815 	if (vaddr < 0) {
    816 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    817 		return;
    818 	}
    819 
    820 	if (copyin((void *)(vaddr & ~3), &a, 4) != 0) {
    821 		send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    822 		return;
    823 	}
    824 
    825 	x = tf->tf_regs[(inst>>16)&0x1F];
    826 
    827 	shift = (3 - (vaddr & 0x00000003)) * 8;
    828 	a <<= shift;
    829 	x &= ~(0xFFFFFFFFUL << shift);
    830 	x |= a;
    831 
    832 	tf->tf_regs[(inst>>16)&0x1F] = x;
    833 
    834 	update_pc(tf, cause);
    835 }
    836 
    837 void
    838 mips_emul_lwr(uint32_t inst, struct trapframe *tf, uint32_t cause)
    839 {
    840 	intptr_t	vaddr;
    841 	uint32_t	a, x, shift;
    842 	int16_t		offset;
    843 
    844 	offset = inst & 0xFFFF;
    845 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    846 
    847 	/* segment check */
    848 	if (vaddr & 0x80000000) {
    849 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    850 		return;
    851 	}
    852 
    853 	if (copyin((void *)(vaddr & ~3), &a, 4) != 0) {
    854 		send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    855 		return;
    856 	}
    857 
    858 	x = tf->tf_regs[(inst>>16)&0x1F];
    859 
    860 	shift = (vaddr & 0x00000003) * 8;
    861 	a >>= shift;
    862 	x &= ~(0xFFFFFFFFUL >> shift);
    863 	x |= a;
    864 
    865 	tf->tf_regs[(inst>>16)&0x1F] = x;
    866 
    867 	update_pc(tf, cause);
    868 }
    869 
    870 #if defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64)
    871 void
    872 mips_emul_lwu(uint32_t inst, struct trapframe *tf, uint32_t cause)
    873 {
    874 	intptr_t	vaddr;
    875 	int16_t		offset;
    876 	uint32_t	x;
    877 
    878 	offset = inst & 0xFFFF;
    879 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    880 
    881 	/* segment and alignment check */
    882 	if (vaddr > VM_MAX_ADDRESS || vaddr & 0x3) {
    883 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    884 		return;
    885 	}
    886 
    887 	if (copyin((void *)vaddr, &x, 4) != 0) {
    888 		send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    889 		return;
    890 	}
    891 
    892 	tf->tf_regs[(inst>>16)&0x1F] = x;
    893 
    894 	update_pc(tf, cause);
    895 }
    896 
    897 void
    898 mips_emul_ld(uint32_t inst, struct trapframe *tf, uint32_t cause)
    899 {
    900 	intptr_t	vaddr;
    901 	int16_t		offset;
    902 
    903 	offset = inst & 0xFFFF;
    904 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    905 
    906 	/* segment and alignment check */
    907 	if (vaddr > VM_MAX_ADDRESS || vaddr & 0x7) {
    908 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    909 		return;
    910 	}
    911 
    912 	if (copyin((void *)vaddr, &(tf->tf_regs[(inst>>16)&0x1F]), 8) != 0) {
    913 		send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    914 		return;
    915 	}
    916 
    917 	update_pc(tf, cause);
    918 }
    919 
    920 void
    921 mips_emul_ldl(uint32_t inst, struct trapframe *tf, uint32_t cause)
    922 {
    923 	intptr_t	vaddr;
    924 	uint64_t	a, x;
    925 	uint32_t	shift;
    926 	int16_t		offset;
    927 
    928 	offset = inst & 0xFFFF;
    929 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    930 
    931 	/* segment check */
    932 	if (vaddr & 0x80000000) {
    933 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    934 		return;
    935 	}
    936 
    937 	if (copyin((void *)(vaddr & ~0x7), &a, 8) != 0) {
    938 		send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    939 		return;
    940 	}
    941 
    942 	x = tf->tf_regs[(inst>>16)&0x1F];
    943 
    944 	shift = (7 - (vaddr & 0x7)) * 8;
    945 	a <<= shift;
    946 	x &= ~(~(uint64_t)0UL << shift);
    947 	x |= a;
    948 
    949 	tf->tf_regs[(inst>>16)&0x1F] = x;
    950 
    951 	update_pc(tf, cause);
    952 }
    953 
    954 void
    955 mips_emul_ldr(uint32_t inst, struct trapframe *tf, uint32_t cause)
    956 {
    957 	intptr_t	vaddr;
    958 	uint64_t	a, x;
    959 	uint32_t	shift;
    960 	int16_t		offset;
    961 
    962 	offset = inst & 0xFFFF;
    963 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    964 
    965 	/* segment check */
    966 	if (vaddr < 0) {
    967 		send_sigsegv(vaddr, T_ADDR_ERR_LD, tf, cause);
    968 		return;
    969 	}
    970 
    971 	if (copyin((void *)(vaddr & ~0x7), &a, 8) != 0) {
    972 		send_sigsegv(vaddr, T_TLB_LD_MISS, tf, cause);
    973 		return;
    974 	}
    975 
    976 	x = tf->tf_regs[(inst>>16)&0x1F];
    977 
    978 	shift = (vaddr & 0x7) * 8;
    979 	a >>= shift;
    980 	x &= ~(~(uint64_t)0UL >> shift);
    981 	x |= a;
    982 
    983 	tf->tf_regs[(inst>>16)&0x1F] = x;
    984 
    985 	update_pc(tf, cause);
    986 }
    987 #endif /* defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64) */
    988 
    989 void
    990 mips_emul_sb(uint32_t inst, struct trapframe *tf, uint32_t cause)
    991 {
    992 	intptr_t	vaddr;
    993 	int16_t		offset;
    994 
    995 	offset = inst & 0xFFFF;
    996 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
    997 
    998 	/* segment check */
    999 	if (vaddr < 0) {
   1000 		send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
   1001 		return;
   1002 	}
   1003 
   1004 	if (ustore_8((void *)vaddr, tf->tf_regs[(inst>>16)&0x1F]) != 0) {
   1005 		send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
   1006 		return;
   1007 	}
   1008 
   1009 	update_pc(tf, cause);
   1010 }
   1011 
   1012 void
   1013 mips_emul_sh(uint32_t inst, struct trapframe *tf, uint32_t cause)
   1014 {
   1015 	intptr_t	vaddr;
   1016 	int16_t		offset;
   1017 
   1018 	offset = inst & 0xFFFF;
   1019 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
   1020 
   1021 	/* segment and alignment check */
   1022 	if (vaddr < 0 || vaddr & 1) {
   1023 		send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
   1024 		return;
   1025 	}
   1026 
   1027 	if (ustore_16((void *)vaddr, tf->tf_regs[(inst>>16)&0x1F]) != 0) {
   1028 		send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
   1029 		return;
   1030 	}
   1031 
   1032 	update_pc(tf, cause);
   1033 }
   1034 
   1035 void
   1036 mips_emul_sw(uint32_t inst, struct trapframe *tf, uint32_t cause)
   1037 {
   1038 	intptr_t	vaddr;
   1039 	int16_t		offset;
   1040 
   1041 	offset = inst & 0xFFFF;
   1042 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
   1043 
   1044 	/* segment and alignment check */
   1045 	if (vaddr < 0 || (vaddr & 3)) {
   1046 		send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
   1047 		return;
   1048 	}
   1049 
   1050 	if (ustore_32((void *)vaddr, tf->tf_regs[(inst>>16)&0x1F]) != 0) {
   1051 		send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
   1052 		return;
   1053 	}
   1054 
   1055 	update_pc(tf, cause);
   1056 }
   1057 
   1058 void
   1059 mips_emul_swl(uint32_t inst, struct trapframe *tf, uint32_t cause)
   1060 {
   1061 	intptr_t	vaddr;
   1062 	uint32_t	a, x, shift;
   1063 	int16_t		offset;
   1064 
   1065 	offset = inst & 0xFFFF;
   1066 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
   1067 
   1068 	/* segment check */
   1069 	if (vaddr < 0) {
   1070 		send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
   1071 		return;
   1072 	}
   1073 
   1074 	if (copyin((void *)(vaddr & ~3), &a, 4) != 0) {
   1075 		send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
   1076 		return;
   1077 	}
   1078 
   1079 	x = tf->tf_regs[(inst>>16)&0x1F];
   1080 
   1081 	shift = (3 - (vaddr & 3)) * 8;
   1082 	x >>= shift;
   1083 	a &= ~(0xFFFFFFFFUL >> shift);
   1084 	a |= x;
   1085 
   1086 	if (ustore_32((void *)vaddr, a) != 0) {
   1087 		send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
   1088 		return;
   1089 	}
   1090 
   1091 	update_pc(tf, cause);
   1092 }
   1093 
   1094 void
   1095 mips_emul_swr(uint32_t inst, struct trapframe *tf, uint32_t cause)
   1096 {
   1097 	intptr_t	vaddr;
   1098 	uint32_t	a, x, shift;
   1099 	int16_t		offset;
   1100 
   1101 	offset = inst & 0xFFFF;
   1102 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
   1103 
   1104 	/* segment check */
   1105 	if (vaddr < 0) {
   1106 		send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
   1107 		return;
   1108 	}
   1109 
   1110 	if (copyin((void *)(vaddr & ~3), &a, 4) != 0) {
   1111 		send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
   1112 		return;
   1113 	}
   1114 
   1115 	x = tf->tf_regs[(inst>>16)&0x1F];
   1116 
   1117 	shift = (vaddr & 3) * 8;
   1118 	x <<= shift;
   1119 	a &= ~(0xFFFFFFFFUL << shift);
   1120 	a |= x;
   1121 
   1122 	if (ustore_32((void *)vaddr, a) != 0) {
   1123 		send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
   1124 		return;
   1125 	}
   1126 
   1127 	update_pc(tf, cause);
   1128 }
   1129 
   1130 #if defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64)
   1131 void
   1132 mips_emul_sd(uint32_t inst, struct trapframe *tf, uint32_t cause)
   1133 {
   1134 	intptr_t	vaddr;
   1135 	int16_t		offset;
   1136 
   1137 	offset = inst & 0xFFFF;
   1138 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
   1139 
   1140 	/* segment and alignment check */
   1141 	if (vaddr < 0 || vaddr & 0x7) {
   1142 		send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
   1143 		return;
   1144 	}
   1145 
   1146 	if (copyout((void *)vaddr, &tf->tf_regs[(inst>>16)&0x1F], 8) < 0) {
   1147 		send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
   1148 		return;
   1149 	}
   1150 
   1151 	update_pc(tf, cause);
   1152 }
   1153 
   1154 void
   1155 mips_emul_sdl(uint32_t inst, struct trapframe *tf, uint32_t cause)
   1156 {
   1157 	intptr_t	vaddr;
   1158 	uint64_t	a, x;
   1159 	uint32_t	shift;
   1160 	int16_t		offset;
   1161 
   1162 	offset = inst & 0xFFFF;
   1163 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
   1164 
   1165 	/* segment check */
   1166 	if (vaddr < 0) {
   1167 		send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
   1168 		return;
   1169 	}
   1170 
   1171 	if (copyin((void *)(vaddr & ~0x7), &a, 8) != 0) {
   1172 		send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
   1173 		return;
   1174 	}
   1175 
   1176 	x = tf->tf_regs[(inst>>16)&0x1F];
   1177 
   1178 	shift = (7 - (vaddr & 7)) * 8;
   1179 	x >>= shift;
   1180 	a &= ~(~(uint64_t)0U >> shift);
   1181 	a |= x;
   1182 
   1183 	if (copyout((void *)(vaddr & ~0x7), &a, 8) != 0) {
   1184 		send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
   1185 		return;
   1186 	}
   1187 
   1188 	update_pc(tf, cause);
   1189 }
   1190 
   1191 void
   1192 mips_emul_sdr(uint32_t inst, struct trapframe *tf, uint32_t cause)
   1193 {
   1194 	intptr_t	vaddr;
   1195 	uint64_t	a, x;
   1196 	uint32_t	shift;
   1197 	int16_t		offset;
   1198 
   1199 	offset = inst & 0xFFFF;
   1200 	vaddr = tf->tf_regs[(inst>>21)&0x1F] + offset;
   1201 
   1202 	/* segment check */
   1203 	if (vaddr < 0) {
   1204 		send_sigsegv(vaddr, T_ADDR_ERR_ST, tf, cause);
   1205 		return;
   1206 	}
   1207 
   1208 	if (copyin((void *)(vaddr & ~0x7), &a, 8) != 0) {
   1209 		send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
   1210 		return;
   1211 	}
   1212 
   1213 	x = tf->tf_regs[(inst>>16)&0x1F];
   1214 
   1215 	shift = (vaddr & 7) * 8;
   1216 	x <<= shift;
   1217 	a &= ~(~(uint64_t)0U << shift);
   1218 	a |= x;
   1219 
   1220 	if (copyout((void *)(vaddr & ~0x7), &a, 8) != 0) {
   1221 		send_sigsegv(vaddr, T_TLB_ST_MISS, tf, cause);
   1222 		return;
   1223 	}
   1224 
   1225 	update_pc(tf, cause);
   1226 }
   1227 #endif /* defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64) */
   1228 #endif /* defined(FPEMUL) */
   1229