[BACK]Return to emul.c CVS log [TXT][DIR] Up to [local] / sys / arch / sparc64 / sparc64

Annotation of sys/arch/sparc64/sparc64/emul.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: emul.c,v 1.12 2003/11/03 07:01:33 david Exp $ */
                      2: /*     $NetBSD: emul.c,v 1.8 2001/06/29 23:58:40 eeh Exp $     */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1997, 2001 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Christos Zoulas.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *        This product includes software developed by the NetBSD
                     22:  *        Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
                     39:
                     40: #include <sys/param.h>
                     41: #include <sys/systm.h>
                     42: #include <sys/proc.h>
                     43: #include <sys/signalvar.h>
                     44: #include <sys/malloc.h>
                     45: #include <machine/reg.h>
                     46: #include <machine/instr.h>
                     47: #include <machine/cpu.h>
                     48: #include <machine/psl.h>
                     49: #include <sparc64/sparc64/cpuvar.h>
                     50: #include <uvm/uvm_extern.h>
                     51:
                     52: #ifdef DEBUG_EMUL
                     53: # define DPRINTF(a) printf a
                     54: #else
                     55: # define DPRINTF(a)
                     56: #endif
                     57:
                     58: #define GPR(tf, i)     ((int32_t *)(u_long)&tf->tf_global)[i]
                     59: #define IPR(tf, i)     ((int32_t *)(u_long)tf->tf_out[6])[i - 16]
                     60: #define FPR(p, i)      ((int32_t) p->p_md.md_fpstate->fs_regs[i])
                     61:
                     62: static __inline int readgpreg(struct trapframe64 *, int, void *);
                     63: static __inline int readfpreg(struct proc *, int, void *);
                     64: static __inline int writegpreg(struct trapframe64 *, int, const void *);
                     65: static __inline int writefpreg(struct proc *, int, const void *);
                     66: static __inline int decodeaddr(struct trapframe64 *, union instr *, void *);
                     67: static int muldiv(struct trapframe64 *, union instr *, int32_t *, int32_t *,
                     68:     int32_t *);
                     69: void swap_quad(int64_t *);
                     70:
                     71: #define        REGNAME(i)      "goli"[i >> 3], i & 7
                     72:
                     73:
                     74: static __inline int
                     75: readgpreg(tf, i, val)
                     76:        struct trapframe64 *tf;
                     77:        int i;
                     78:        void *val;
                     79: {
                     80:        int error = 0;
                     81:        if (i == 0)
                     82:                *(int32_t *) val = 0;
                     83:        else if (i < 16)
                     84:                *(int32_t *) val = GPR(tf, i);
                     85:        else
                     86:                error = copyin(&IPR(tf, i), val, sizeof(int32_t));
                     87:
                     88:        return error;
                     89: }
                     90:
                     91:
                     92: static __inline int
                     93: writegpreg(tf, i, val)
                     94:        struct trapframe64 *tf;
                     95:        int i;
                     96:        const void *val;
                     97: {
                     98:        int error = 0;
                     99:
                    100:        if (i == 0)
                    101:                return error;
                    102:        else if (i < 16)
                    103:                GPR(tf, i) = *(int32_t *) val;
                    104:        else
                    105:                /* XXX: Fix copyout prototype */
                    106:                error = copyout((caddr_t) val, &IPR(tf, i), sizeof(int32_t));
                    107:
                    108:        return error;
                    109: }
                    110:
                    111:
                    112: static __inline int
                    113: readfpreg(p, i, val)
                    114:        struct proc *p;
                    115:        int i;
                    116:        void *val;
                    117: {
                    118:        *(int32_t *) val = FPR(p, i);
                    119:        return 0;
                    120: }
                    121:
                    122:
                    123: static __inline int
                    124: writefpreg(p, i, val)
                    125:        struct proc *p;
                    126:        int i;
                    127:        const void *val;
                    128: {
                    129:        FPR(p, i) = *(const int32_t *) val;
                    130:        return 0;
                    131: }
                    132:
                    133: static __inline int
                    134: decodeaddr(tf, code, val)
                    135:        struct trapframe64 *tf;
                    136:        union instr *code;
                    137:        void *val;
                    138: {
                    139:        if (code->i_simm13.i_i)
                    140:                *((int32_t *) val) = code->i_simm13.i_simm13;
                    141:        else {
                    142:                int error;
                    143:
                    144:                if (code->i_asi.i_asi)
                    145:                        return EINVAL;
                    146:                if ((error = readgpreg(tf, code->i_asi.i_rs2, val)) != 0)
                    147:                        return error;
                    148:        }
                    149:        return 0;
                    150: }
                    151:
                    152:
                    153: static int
                    154: muldiv(tf, code, rd, rs1, rs2)
                    155:        struct trapframe64 *tf;
                    156:        union instr *code;
                    157:        int32_t *rd, *rs1, *rs2;
                    158: {
                    159:        /*
                    160:         * We check for {S,U}{MUL,DIV}{,cc}
                    161:         *
                    162:         * [c = condition code, s = sign]
                    163:         * Mul = 0c101s
                    164:         * Div = 0c111s
                    165:         */
                    166:        union {
                    167:                struct {
                    168:                        unsigned unused:26;     /* padding */
                    169:                        unsigned zero:1;        /* zero by opcode */
                    170:                        unsigned cc:1;          /* one to send condition code */
                    171:                        unsigned one1:1;        /* one by opcode */
                    172:                        unsigned div:1;         /* one if divide */
                    173:                        unsigned one2:1;        /* one by opcode */
                    174:                        unsigned sgn:1;         /* sign bit */
                    175:                } bits;
                    176:                int num;
                    177:        } op;
                    178:
                    179:        op.num = code->i_op3.i_op3;
                    180:
                    181: #ifdef DEBUG_EMUL
                    182:        printf("muldiv 0x%x: %c%s%s %c%d, %c%d, ", code->i_int,
                    183:            "us"[op.bits.sgn], op.bits.div ? "div" : "mul",
                    184:            op.bits.cc ? "cc" : "", REGNAME(code->i_op3.i_rd),
                    185:            REGNAME(code->i_op3.i_rs1));
                    186:        if (code->i_loadstore.i_i)
                    187:                printf("0x%x\n", *rs2);
                    188:        else
                    189:                printf("%c%d\n", REGNAME(code->i_asi.i_rs2));
                    190: #endif
                    191:
                    192:        if (op.bits.div) {
                    193:                if (*rs2 == 0) {
                    194:                        /*
                    195:                         * XXX: to be 100% correct here, on sunos we need to
                    196:                         *      ignore the error and return *rd = *rs1.
                    197:                         *      It should be easy to fix by passing struct
                    198:                         *      proc in here.
                    199:                         */
                    200:                        DPRINTF(("muldiv: avoid zerodivide\n"));
                    201:                        return EINVAL;
                    202:                }
                    203:                *rd = *rs1 / *rs2;
                    204:                DPRINTF(("muldiv: %d / %d = %d\n", *rs1, *rs2, *rd));
                    205:        }
                    206:        else {
                    207:                *rd = *rs1 * *rs2;
                    208:                DPRINTF(("muldiv: %d * %d = %d\n", *rs1, *rs2, *rd));
                    209:        }
                    210:
                    211:        if (op.bits.cc) {
                    212:                /* Set condition codes */
                    213:                tf->tf_tstate &= ~(TSTATE_CCR);
                    214:
                    215:                if (*rd == 0)
                    216:                        tf->tf_tstate |= (u_int64_t)(ICC_Z|XCC_Z) << TSTATE_CCR_SHIFT;
                    217:                else {
                    218:                        if (op.bits.sgn && *rd < 0)
                    219:                                tf->tf_tstate |= (u_int64_t)(ICC_N|XCC_N) << TSTATE_CCR_SHIFT;
                    220:                        if (op.bits.div) {
                    221:                                if (*rd * *rs2 != *rs1)
                    222:                                        tf->tf_tstate |= (u_int64_t)(ICC_V|XCC_V) << TSTATE_CCR_SHIFT;
                    223:                        }
                    224:                        else {
                    225:                                if (*rd / *rs2 != *rs1)
                    226:                                        tf->tf_tstate |= (u_int64_t)(ICC_V|XCC_V) << TSTATE_CCR_SHIFT;
                    227:                        }
                    228:                }
                    229:        }
                    230:
                    231:        return 0;
                    232: }
                    233:
                    234: /*
                    235:  * Code to handle alignment faults on the sparc. This is enabled by sending
                    236:  * a fixalign trap. Such code is generated by compiling with cc -misalign
                    237:  * on SunOS, but we don't have such a feature yet on our gcc.
                    238:  */
                    239:
                    240: int
                    241: fixalign(p, tf)
                    242:        struct proc *p;
                    243:        struct trapframe64 *tf;
                    244: {
                    245:        static u_char sizedef[] = { 0x4, 0xff, 0x2, 0x8 };
                    246:
                    247:        /*
                    248:         * This is particular to load and store instructions
                    249:         */
                    250:        union {
                    251:                struct {
                    252:                        unsigned unused:26;     /* 26 padding */
                    253:                        unsigned fl:1;          /* 1 bit float flag */
                    254:                        unsigned op:1;          /* 1 bit opcode */
                    255:                        unsigned sgn:1;         /* 1 bit sign */
                    256:                        unsigned st:1;          /* 1 bit load/store */
                    257:                        unsigned sz:2;          /* 2 bit size register */
                    258:                } bits;
                    259:                int num;
                    260:        } op;
                    261:
                    262:        union {
                    263:                double  d;
                    264:                int32_t i[2];
                    265:                int16_t s[4];
                    266:                int8_t  c[8];
                    267:        } data;
                    268:
                    269:        union instr code;
                    270:        size_t size;
                    271:        int64_t rs1, rs2;
                    272:        int error;
                    273:
                    274:        /* fetch and check the instruction that caused the fault */
                    275:        error = copyin((caddr_t)(u_long)tf->tf_pc, &code.i_int, sizeof(code.i_int));
                    276:        if (error != 0) {
                    277:                DPRINTF(("fixalign: Bad instruction fetch\n"));
                    278:                return EINVAL;
                    279:        }
                    280:
                    281:        /* Only support format 3 */
                    282:        if (code.i_any.i_op != 3) {
                    283:                DPRINTF(("fixalign: Not a load or store\n"));
                    284:                return EINVAL;
                    285:        }
                    286:
                    287:        op.num = code.i_loadstore.i_op3;
                    288:
                    289:        /* Check operand size */
                    290:        if ((size = sizedef[op.bits.sz]) == 0xff) {
                    291:                DPRINTF(("fixalign: Bad operand size\n"));
                    292:                return EINVAL;
                    293:        }
                    294:
                    295:        write_user_windows();
                    296:
                    297:        if ((error = readgpreg(tf, code.i_op3.i_rs1, &rs1)) != 0) {
                    298:                DPRINTF(("fixalign: read rs1 %d\n", error));
                    299:                return error;
                    300:        }
                    301:
                    302:        if ((error = decodeaddr(tf, &code, &rs2)) != 0) {
                    303:                DPRINTF(("fixalign: decode addr %d\n", error));
                    304:                return error;
                    305:        }
                    306:
                    307:
                    308:        rs1 += rs2;
                    309:
                    310: #ifdef DEBUG_EMUL
                    311:        printf("memalign 0x%x: %s%c%c %c%d, %c%d, ", code.i_int,
                    312:            op.bits.st ? "st" : "ld", "us"[op.bits.sgn],
                    313:            "w*hd"[op.bits.sz], op.bits.fl ? 'f' : REGNAME(code.i_op3.i_rd),
                    314:            REGNAME(code.i_op3.i_rs1));
                    315:        if (code.i_loadstore.i_i)
                    316:                printf("0x%llx\n", (unsigned long long)rs2);
                    317:        else
                    318:                printf("%c%d\n", REGNAME(code.i_asi.i_rs2));
                    319: #endif
                    320: #ifdef DIAGNOSTIC
                    321:        if (op.bits.fl && p != fpproc)
                    322:                panic("fp align without being the FP owning process");
                    323: #endif
                    324:
                    325:        if (op.bits.st) {
                    326:                if (op.bits.fl) {
                    327:                        if (p == fpproc) {
                    328:                                savefpstate(p->p_md.md_fpstate);
                    329:                                fpproc = NULL;
                    330:                        }
                    331:
                    332:                        error = readfpreg(p, code.i_op3.i_rd, &data.i[0]);
                    333:                        if (error)
                    334:                                return error;
                    335:                        if (size == 8) {
                    336:                                error = readfpreg(p, code.i_op3.i_rd + 1,
                    337:                                    &data.i[1]);
                    338:                                if (error)
                    339:                                        return error;
                    340:                        }
                    341:                }
                    342:                else {
                    343:                        error = readgpreg(tf, code.i_op3.i_rd, &data.i[0]);
                    344:                        if (error)
                    345:                                return error;
                    346:                        if (size == 8) {
                    347:                                error = readgpreg(tf, code.i_op3.i_rd + 1,
                    348:                                    &data.i[1]);
                    349:                                if (error)
                    350:                                        return error;
                    351:                        }
                    352:                }
                    353:
                    354:                if (size == 2)
                    355:                        return copyout(&data.s[1], (caddr_t)(u_long)rs1, size);
                    356:                else
                    357:                        return copyout(&data.d, (caddr_t)(u_long)rs1, size);
                    358:        }
                    359:        else { /* load */
                    360:                if (size == 2) {
                    361:                        error = copyin((caddr_t)(u_long)rs1, &data.s[1], size);
                    362:                        if (error)
                    363:                                return error;
                    364:
                    365:                        /* Sign extend if necessary */
                    366:                        if (op.bits.sgn && (data.s[1] & 0x8000) != 0)
                    367:                                data.s[0] = ~0;
                    368:                        else
                    369:                                data.s[0] = 0;
                    370:                }
                    371:                else
                    372:                        error = copyin((caddr_t)(u_long)rs1, &data.d, size);
                    373:
                    374:                if (error)
                    375:                        return error;
                    376:
                    377:                if (op.bits.fl) {
                    378:                        error = writefpreg(p, code.i_op3.i_rd, &data.i[0]);
                    379:                        if (error)
                    380:                                return error;
                    381:                        if (size == 8) {
                    382:                                error = writefpreg(p, code.i_op3.i_rd + 1,
                    383:                                    &data.i[1]);
                    384:                                if (error)
                    385:                                        return error;
                    386:                        }
                    387:                        loadfpstate(p->p_md.md_fpstate);
                    388:                        fpproc = p;
                    389:                }
                    390:                else {
                    391:                        error = writegpreg(tf, code.i_op3.i_rd, &data.i[0]);
                    392:                        if (error)
                    393:                                return error;
                    394:                        if (size == 8)
                    395:                                error = writegpreg(tf, code.i_op3.i_rd + 1,
                    396:                                    &data.i[1]);
                    397:                }
                    398:        }
                    399:        return error;
                    400: }
                    401:
                    402: /*
                    403:  * Emulate unimplemented instructions on earlier sparc chips.
                    404:  */
                    405: int
                    406: emulinstr(pc, tf)
                    407:        vaddr_t pc;
                    408:        struct trapframe64 *tf;
                    409: {
                    410:        union instr code;
                    411:        int32_t rs1, rs2, rd;
                    412:        int error;
                    413:
                    414:        /* fetch and check the instruction that caused the fault */
                    415:        error = copyin((caddr_t) pc, &code.i_int, sizeof(code.i_int));
                    416:        if (error != 0) {
                    417:                DPRINTF(("emulinstr: Bad instruction fetch\n"));
                    418:                return (SIGILL);
                    419:        }
                    420:
                    421:        /* Only support format 2 */
                    422:        if (code.i_any.i_op != 2) {
                    423:                DPRINTF(("emulinstr: Not a format 2 instruction\n"));
                    424:                return (SIGILL);
                    425:        }
                    426:
                    427:        write_user_windows();
                    428:
                    429:        if ((error = readgpreg(tf, code.i_op3.i_rs1, &rs1)) != 0) {
                    430:                DPRINTF(("emulinstr: read rs1 %d\n", error));
                    431:                return (SIGILL);
                    432:        }
                    433:
                    434:        if ((error = decodeaddr(tf, &code, &rs2)) != 0) {
                    435:                DPRINTF(("emulinstr: decode addr %d\n", error));
                    436:                return (SIGILL);
                    437:        }
                    438:
                    439:        switch (code.i_op3.i_op3) {
                    440:        case IOP3_FLUSH:
                    441: /*             cpuinfo.cache_flush((caddr_t)(rs1 + rs2), 4); XXX */
                    442:                return (0);
                    443:
                    444:        default:
                    445:                if ((code.i_op3.i_op3 & 0x2a) != 0xa) {
                    446:                        DPRINTF(("emulinstr: Unsupported op3 0x%x\n",
                    447:                            code.i_op3.i_op3));
                    448:                        return (SIGILL);
                    449:                }
                    450:                else if ((error = muldiv(tf, &code, &rd, &rs1, &rs2)) != 0)
                    451:                        return (SIGFPE);
                    452:        }
                    453:
                    454:        if ((error = writegpreg(tf, code.i_op3.i_rd, &rd)) != 0) {
                    455:                DPRINTF(("muldiv: write rd %d\n", error));
                    456:                return (SIGILL);
                    457:        }
                    458:
                    459:        return (0);
                    460: }
                    461:
                    462: #define        SIGN_EXT13(v)   (((int64_t)(v) << 51) >> 51)
                    463:
                    464: void
                    465: swap_quad(int64_t *p)
                    466: {
                    467:        int64_t t;
                    468:
                    469:        t = htole64(p[0]);
                    470:        p[0] = htole64(p[1]);
                    471:        p[1] = t;
                    472: }
                    473:
                    474: /*
                    475:  * emulate STQF, STQFA, LDQF, and LDQFA
                    476:  */
                    477: int
                    478: emul_qf(int32_t insv, struct proc *p, union sigval sv, struct trapframe *tf)
                    479: {
                    480:        extern struct fpstate64 initfpstate;
                    481:        struct fpstate64 *fs = p->p_md.md_fpstate;
                    482:        int64_t addr, buf[2];
                    483:        union instr ins;
                    484:        int freg, isload, err;
                    485:        u_int8_t asi;
                    486:
                    487:        ins.i_int = insv;
                    488:        freg = ins.i_op3.i_rd & ~1;
                    489:        freg |= (ins.i_op3.i_rd & 1) << 5;
                    490:
                    491:        if (ins.i_op3.i_op3 == IOP3_LDQF || ins.i_op3.i_op3 == IOP3_LDQFA)
                    492:                isload = 1;
                    493:        else
                    494:                isload = 0;
                    495:
                    496:        if (ins.i_op3.i_op3 == IOP3_STQF || ins.i_op3.i_op3 == IOP3_LDQF)
                    497:                asi = ASI_PRIMARY;
                    498:        else if (ins.i_loadstore.i_i)
                    499:                asi = (tf->tf_tstate & TSTATE_ASI) >> TSTATE_ASI_SHIFT;
                    500:        else
                    501:                asi = ins.i_asi.i_asi;
                    502:
                    503:        addr = tf->tf_global[ins.i_asi.i_rs1];
                    504:        if (ins.i_loadstore.i_i)
                    505:                addr += SIGN_EXT13(ins.i_simm13.i_simm13);
                    506:        else
                    507:                addr += tf->tf_global[ins.i_asi.i_rs2];
                    508:
                    509:        if (asi < ASI_PRIMARY) {
                    510:                /* privileged asi */
                    511:                trapsignal(p, SIGILL, 0, ILL_PRVOPC, sv);
                    512:                return (0);
                    513:        }
                    514:        if (asi > ASI_SECONDARY_NOFAULT_LITTLE ||
                    515:            (asi > ASI_SECONDARY_NOFAULT && asi < ASI_PRIMARY_LITTLE)) {
                    516:                /* architecturally undefined user ASI's */
                    517:                goto segv;
                    518:        }
                    519:
                    520:        if ((freg & 3) != 0) {
                    521:                /* only valid for %fN where N % 4 = 0 */
                    522:                trapsignal(p, SIGILL, 0, ILL_ILLOPN, sv);
                    523:                return (0);
                    524:        }
                    525:
                    526:        if ((p->p_md.md_flags & MDP_FIXALIGN) == 0 && (addr & 3) != 0) {
                    527:                /*
                    528:                 * If process doesn't want us to fix alignment and the
                    529:                 * request isn't aligned, kill it.
                    530:                 */
                    531:                trapsignal(p, SIGBUS, 0, BUS_ADRALN, sv);
                    532:                return (0);
                    533:        }
                    534:
                    535:        fs = p->p_md.md_fpstate;
                    536:        if (fs == NULL) {
                    537:                /* don't currently have an fpu context, get one */
                    538:                fs = malloc(sizeof(*fs), M_SUBPROC, M_WAITOK);
                    539:                *fs = initfpstate;
                    540:                fs->fs_qsize = 0;
                    541:                p->p_md.md_fpstate = fs;
                    542:        }
                    543:        if (fpproc != p) {
                    544:                /* make this process the current holder of the fpu */
                    545:                if (fpproc != NULL)
                    546:                        savefpstate(fpproc->p_md.md_fpstate);
                    547:                fpproc = p;
                    548:        }
                    549:        tf->tf_tstate |= TSTATE_PEF;
                    550:
                    551:        /* Ok, try to do the actual operation (finally) */
                    552:        if (isload) {
                    553:                err = copyin((caddr_t)addr, buf, sizeof(buf));
                    554:                if (err != 0 && (asi & 2) == 0)
                    555:                        goto segv;
                    556:                if (err == 0) {
                    557:                        savefpstate(fs);
                    558:                        if (asi & 8)
                    559:                                swap_quad(buf);
                    560:                        bcopy(buf, &fs->fs_regs[freg], sizeof(buf));
                    561:                        loadfpstate(fs);
                    562:                }
                    563:        } else {
                    564:                bcopy(&fs->fs_regs[freg], buf, sizeof(buf));
                    565:                if (asi & 8)
                    566:                        swap_quad(buf);
                    567:                if (copyout(buf, (caddr_t)addr, sizeof(buf)) && (asi & 2) == 0)
                    568:                        goto segv;
                    569:        }
                    570:
                    571:        return (1);
                    572:
                    573: segv:
                    574:        trapsignal(p, SIGSEGV, isload ? VM_PROT_READ : VM_PROT_WRITE,
                    575:            SEGV_MAPERR, sv);
                    576:        return (0);
                    577: }
                    578:
                    579: int
                    580: emul_popc(int32_t insv, struct proc *p, union sigval sv, struct trapframe *tf)
                    581: {
                    582:        u_int64_t val, ret = 0;
                    583:        union instr ins;
                    584:
                    585:        ins.i_int = insv;
                    586:        if (ins.i_simm13.i_i == 0)
                    587:                val = tf->tf_global[ins.i_asi.i_rs2];
                    588:        else
                    589:                val = SIGN_EXT13(ins.i_simm13.i_simm13);
                    590:
                    591:        for (; val != 0; val >>= 1)
                    592:                ret += val & 1;
                    593:
                    594:        tf->tf_global[ins.i_asi.i_rd] = ret;
                    595:        return (1);
                    596: }

CVSweb