--- nono/fpe/fpu_emulate.c 2026/04/29 17:04:28 1.1.1.1 +++ nono/fpe/fpu_emulate.c 2026/04/29 17:05:23 1.1.1.3 @@ -1,4 +1,4 @@ -/* $NetBSD: fpu_emulate.c,v 1.38 2013/10/25 21:32:45 martin Exp $ */ +/* $NetBSD: fpu_emulate.c,v 1.40 2019/12/27 07:41:23 msaitoh Exp $ */ /* * Copyright (c) 1995 Gordon W. Ross @@ -79,8 +79,8 @@ fpu_emulate(struct frame *frame, struct { static struct instruction insn; static struct fpemu fe; - int word, optype, sig; - + int optype, sig; + unsigned short sval; /* initialize insn.is_datasize to tell it is *not* initialized */ insn.is_datasize = -1; @@ -116,32 +116,30 @@ fpu_emulate(struct frame *frame, struct frame->f_pc = insn.is_pc; } - word = fusword((void *)(insn.is_pc)); - if (word < 0) { + if (ufetch_short((void *)(insn.is_pc), &sval)) { DPRINTF(("%s: fault reading opcode\n", __func__)); fpe_abort(frame, ksi, SIGSEGV, SEGV_ACCERR); } - if ((word & 0xf000) != 0xf000) { + if ((sval & 0xf000) != 0xf000) { DPRINTF(("%s: not coproc. insn.: opcode=0x%x\n", __func__, word)); fpe_abort(frame, ksi, SIGILL, ILL_ILLOPC); } - if ((word & 0x0E00) != 0x0200) { + if ((sval & 0x0E00) != 0x0200) { DPRINTF(("%s: bad coproc. id: opcode=0x%x\n", __func__, word)); fpe_abort(frame, ksi, SIGILL, ILL_ILLOPC); } - insn.is_opcode = word; - optype = (word & 0x01C0); + insn.is_opcode = sval; + optype = (sval & 0x01C0); - word = fusword((void *)(insn.is_pc + 2)); - if (word < 0) { + if (ufetch_short((void *)(insn.is_pc + 2), &sval)) { DPRINTF(("%s: fault reading word1\n", __func__)); fpe_abort(frame, ksi, SIGSEGV, SEGV_ACCERR); } - insn.is_word1 = word; + insn.is_word1 = sval; /* all FPU instructions are at least 4-byte long */ insn.is_advance = 4; @@ -154,21 +152,21 @@ fpu_emulate(struct frame *frame, struct */ if (optype == 0x0000) { /* type=0: generic */ - if ((word & 0xc000) == 0xc000) { + if ((sval & 0xc000) == 0xc000) { DPRINTF(("%s: fmovm FPr\n", __func__)); sig = fpu_emul_fmovm(&fe, &insn); - } else if ((word & 0xc000) == 0x8000) { + } else if ((sval & 0xc000) == 0x8000) { DPRINTF(("%s: fmovm FPcr\n", __func__)); sig = fpu_emul_fmovmcr(&fe, &insn); - } else if ((word & 0xe000) == 0x6000) { + } else if ((sval & 0xe000) == 0x6000) { /* fstore = fmove FPn,mem */ DPRINTF(("%s: fmove to mem\n", __func__)); sig = fpu_emul_fstore(&fe, &insn); - } else if ((word & 0xfc00) == 0x5c00) { + } else if ((sval & 0xfc00) == 0x5c00) { /* fmovecr */ DPRINTF(("%s: fmovecr\n", __func__)); sig = fpu_emul_fmovecr(&fe, &insn); - } else if ((word & 0xa07f) == 0x26) { + } else if ((sval & 0xa07f) == 0x26) { /* fscale */ DPRINTF(("%s: fscale\n", __func__)); sig = fpu_emul_fscale(&fe, &insn); @@ -507,73 +505,6 @@ fpu_emul_fmovm(struct fpemu *fe, struct } #endif /* !XM6i_FPE */ -struct fpn * -fpu_cmp(struct fpemu *fe) -{ - struct fpn *x = &fe->fe_f1, *y = &fe->fe_f2; - - /* take care of special cases */ - if (x->fp_class < 0) { - /* if x is a SNAN, result is x */ - return x; - } else if (y->fp_class < 0) { - /* if y is a SNAN, result is y */ - return y; - } else if (x->fp_class == FPC_INF) { - if (y->fp_class == FPC_INF) { - /* both infinities */ - if (x->fp_sign == y->fp_sign) { - /* return a signed zero */ - x->fp_class = FPC_ZERO; - } else { - /* return a faked number w/x's sign */ - x->fp_class = FPC_NUM; - x->fp_exp = 16383; - x->fp_mant[0] = FP_1; - } - } else { - /* y is a number */ - /* return a forged number w/x's sign */ - x->fp_class = FPC_NUM; - x->fp_exp = 16383; - x->fp_mant[0] = FP_1; - } - } else if (y->fp_class == FPC_INF) { - /* x is a Num but y is an Inf */ - /* return a forged number w/y's sign inverted */ - x->fp_class = FPC_NUM; - x->fp_sign = !y->fp_sign; - x->fp_exp = 16383; - x->fp_mant[0] = FP_1; - } else if (x->fp_class == FPC_ZERO && y->fp_class == FPC_ZERO) { - /* use x's sign */ - } else if (x->fp_sign == y->fp_sign && - x->fp_exp == y->fp_exp && - x->fp_mant[0] == y->fp_mant[0] && - x->fp_mant[1] == y->fp_mant[1] && - x->fp_mant[2] == y->fp_mant[2]) { - /* x and y are the same, return zero (with sign) */ - x->fp_class = FPC_ZERO; - } else { - /* - * x and y are both numbers, - * or pair of a number and a zero - */ - y->fp_sign = !y->fp_sign; - x = fpu_add(fe); /* (x - y) */ - /* - * FCMP does not set Inf bit in CC, so return a forged number - * (value doesn't matter) if Inf is the result of fsub. - */ - if (x->fp_class == FPC_INF) { - x->fp_class = FPC_NUM; - x->fp_exp = 16383; - x->fp_mant[0] = FP_1; - } - } - return x; -} - #if defined(XM6i_FPE) struct fpn * fpu_sglmul(struct fpemu *fe) @@ -653,7 +584,7 @@ fpu_sgldiv(struct fpemu *fe) #if !defined(XM6i_FPE) /* - * arithmetic oprations + * arithmetic operations */ static int fpu_emul_arith(struct fpemu *fe, struct instruction *insn) @@ -1109,6 +1040,7 @@ fpu_emul_type1(struct fpemu *fe, struct { struct frame *frame = fe->fe_frame; int advance, sig, branch, displ; + unsigned short sval; branch = test_cc(fe, insn->is_word1); fe->fe_fpframe->fpf_fpsr = fe->fe_fpsr; @@ -1126,13 +1058,14 @@ fpu_emul_type1(struct fpemu *fe, struct uint16_t count = frame->f_regs[insn->is_opcode & 7]; if (count-- != 0) { - displ = fusword((void *)(insn->is_pc + - insn->is_advance)); - if (displ < 0) { + if (ufetch_short((void *)(insn->is_pc + + insn->is_advance), + &sval)) { DPRINTF(("%s: fault reading " "displacement\n", __func__)); return SIGSEGV; } + displ = sval; /* sign-extend the displacement */ displ &= 0xffff; if (displ & 0x8000) { @@ -1211,6 +1144,7 @@ fpu_emul_brcc(struct fpemu *fe, struct i { int displ, word2; int sig; + unsigned short sval; /* * Get branch displacement. @@ -1219,11 +1153,12 @@ fpu_emul_brcc(struct fpemu *fe, struct i displ = insn->is_word1; if (insn->is_opcode & 0x40) { - word2 = fusword((void *)(insn->is_pc + insn->is_advance)); - if (word2 < 0) { + if (ufetch_short((void *)(insn->is_pc + insn->is_advance), + &sval)) { DPRINTF(("%s: fault reading word2\n", __func__)); return SIGSEGV; } + word2 = sval; displ <<= 16; displ |= word2; insn->is_advance += 2;