Module Name: src Committed By: thorpej Date: Tue Jul 20 01:56:06 UTC 2021
Modified Files: src/sys/arch/alpha/alpha: trap.c Log Message: Emulate the CIX extension instructions (CTPOP, CTTZ, CTLZ). To generate a diff of this commit: cvs rdiff -u -r1.136 -r1.137 src/sys/arch/alpha/alpha/trap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/alpha/alpha/trap.c diff -u src/sys/arch/alpha/alpha/trap.c:1.136 src/sys/arch/alpha/alpha/trap.c:1.137 --- src/sys/arch/alpha/alpha/trap.c:1.136 Mon Jul 19 22:21:36 2021 +++ src/sys/arch/alpha/alpha/trap.c Tue Jul 20 01:56:06 2021 @@ -1,7 +1,7 @@ -/* $NetBSD: trap.c,v 1.136 2021/07/19 22:21:36 thorpej Exp $ */ +/* $NetBSD: trap.c,v 1.137 2021/07/20 01:56:06 thorpej Exp $ */ /*- - * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc. + * Copyright (c) 2000, 2001, 2021 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -95,7 +95,7 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.136 2021/07/19 22:21:36 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.137 2021/07/20 01:56:06 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -106,6 +106,7 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.1 #include <sys/kmem.h> #include <sys/cpu.h> #include <sys/atomic.h> +#include <sys/bitops.h> #include <uvm/uvm_extern.h> @@ -980,6 +981,17 @@ EVCNT_ATTACH_STATIC(emul_bwx_stw); EVCNT_ATTACH_STATIC(emul_bwx_sextb); EVCNT_ATTACH_STATIC(emul_bwx_sextw); +static struct evcnt emul_cix_ctpop = + EVCNT_INITIALIZER(EVCNT_TYPE_TRAP, NULL, "emul cix", "ctpop"); +static struct evcnt emul_cix_ctlz = + EVCNT_INITIALIZER(EVCNT_TYPE_TRAP, NULL, "emul cix", "ctlz"); +static struct evcnt emul_cix_cttz = + EVCNT_INITIALIZER(EVCNT_TYPE_TRAP, NULL, "emul cix", "cttz"); + +EVCNT_ATTACH_STATIC(emul_cix_ctpop); +EVCNT_ATTACH_STATIC(emul_cix_ctlz); +EVCNT_ATTACH_STATIC(emul_cix_cttz); + #define EMUL_COUNT(ev) atomic_inc_64(&(ev).ev_count) /* @@ -1129,6 +1141,60 @@ handle_opdec(struct lwp *l, u_long *ucod *regptr = w; break; } + if (inst.operate_reg_format.function == op_ctpop && + inst.operate_reg_format.zero == 0 && + inst.operate_reg_format.sbz == 0 && + inst.operate_reg_format.ra == 31) { + unsigned long val; + unsigned int res; + + EMUL_COUNT(emul_cix_ctpop); + regptr = irp(l, inst.operate_reg_format.rb); + val = (regptr != NULL) ? *regptr : 0; + res = popcount64(val); + regptr = irp(l, inst.operate_reg_format.rc); + if (regptr != NULL) { + *regptr = res; + } + break; + } + if (inst.operate_reg_format.function == op_ctlz && + inst.operate_reg_format.zero == 0 && + inst.operate_reg_format.sbz == 0 && + inst.operate_reg_format.ra == 31) { + unsigned long val; + unsigned int res; + + EMUL_COUNT(emul_cix_ctlz); + regptr = irp(l, inst.operate_reg_format.rb); + val = (regptr != NULL) ? *regptr : 0; + res = fls64(val); + res = (res == 0) ? 64 : 64 - res; + regptr = irp(l, inst.operate_reg_format.rc); + if (regptr != NULL) { + *regptr = res; + } + break; + } + if (inst.operate_reg_format.function == op_cttz && + inst.operate_reg_format.zero == 0 && + inst.operate_reg_format.sbz == 0 && + inst.operate_reg_format.ra == 31) { + unsigned long val; + unsigned int res; + + EMUL_COUNT(emul_cix_cttz); + regptr = irp(l, inst.operate_reg_format.rb); + val = (regptr != NULL) ? *regptr : 0; + res = ffs64(val); + res = (res == 0) ? 64 : res - 1; + regptr = irp(l, inst.operate_reg_format.rc); + if (regptr != NULL) { + *regptr = res; + } + break; + } + goto sigill; default: