diff --git a/sys/arch/powerpc/fpu/fpu_emu.c b/sys/arch/powerpc/fpu/fpu_emu.c index 4bdeda2e25b7..4314e8da9f0e 100644 --- a/sys/arch/powerpc/fpu/fpu_emu.c +++ b/sys/arch/powerpc/fpu/fpu_emu.c @@ -1,4 +1,4 @@ -/* $NetBSD: fpu_emu.c,v 1.3 2001/07/22 11:29:44 wiz Exp $ */ +/* $NetBSD: fpu_emu.c,v 1.4 2002/11/24 17:34:06 thorpej Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -87,6 +87,7 @@ #include #include #include +#include /* for evcnt */ #include #include @@ -95,6 +96,45 @@ #include #include +#define FPU_EMU_EVCNT_DECL(name) \ +static struct evcnt fpu_emu_ev_##name = \ + EVCNT_INITIALIZER(EVCNT_TYPE_TRAP, NULL, "fpemu", #name); \ +EVCNT_ATTACH_STATIC(fpu_emu_ev_##name) + +#define FPU_EMU_EVCNT_INCR(name) \ + fpu_emu_ev_##name##.ev_count++ + +FPU_EMU_EVCNT_DECL(stfiwx); +FPU_EMU_EVCNT_DECL(fpstore); +FPU_EMU_EVCNT_DECL(fpload); +FPU_EMU_EVCNT_DECL(fcmpu); +FPU_EMU_EVCNT_DECL(frsp); +FPU_EMU_EVCNT_DECL(fctiw); +FPU_EMU_EVCNT_DECL(fcmpo); +FPU_EMU_EVCNT_DECL(mtfsb1); +FPU_EMU_EVCNT_DECL(fnegabs); +FPU_EMU_EVCNT_DECL(mcrfs); +FPU_EMU_EVCNT_DECL(mtfsb0); +FPU_EMU_EVCNT_DECL(fmr); +FPU_EMU_EVCNT_DECL(mtfsfi); +FPU_EMU_EVCNT_DECL(fnabs); +FPU_EMU_EVCNT_DECL(fabs); +FPU_EMU_EVCNT_DECL(mffs); +FPU_EMU_EVCNT_DECL(mtfsf); +FPU_EMU_EVCNT_DECL(fctid); +FPU_EMU_EVCNT_DECL(fcfid); +FPU_EMU_EVCNT_DECL(fdiv); +FPU_EMU_EVCNT_DECL(fsub); +FPU_EMU_EVCNT_DECL(fadd); +FPU_EMU_EVCNT_DECL(fsqrt); +FPU_EMU_EVCNT_DECL(fsel); +FPU_EMU_EVCNT_DECL(fpres); +FPU_EMU_EVCNT_DECL(fmul); +FPU_EMU_EVCNT_DECL(frsqrte); +FPU_EMU_EVCNT_DECL(fmulsub); +FPU_EMU_EVCNT_DECL(fmuladd); +FPU_EMU_EVCNT_DECL(fnmsub); +FPU_EMU_EVCNT_DECL(fnmadd); /* FPSR exception masks */ #define FPSR_EX_MSK (FPSCR_VX|FPSCR_OX|FPSCR_UX|FPSCR_ZX| \ @@ -280,6 +320,8 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) if (instr.i_any.i_opcd == OPC_integer_31) { if (instr.i_x.i_xo == OPC31_STFIWX) { + FPU_EMU_EVCNT_INCR(stfiwx); + /* Store as integer */ ra = instr.i_x.i_ra; rb = instr.i_x.i_rb; @@ -342,6 +384,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) if (store) { /* Store */ + FPU_EMU_EVCNT_INCR(fpstore); if (type != FTYPE_DBL) { DPRINTF(FPE_INSN, ("fpu_execute: Store SNG at %p\n", @@ -359,6 +402,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) } } else { /* Load */ + FPU_EMU_EVCNT_INCR(fpload); DPRINTF(FPE_INSN, ("fpu_execute: Load from %p\n", (void *)addr)); if (copyin((const void *)addr, &fs->fpreg[rt], size)) @@ -393,6 +437,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) /* One of the special opcodes.... */ switch (instr.i_x.i_xo) { case OPC63_FCMPU: + FPU_EMU_EVCNT_INCR(fcmpu); DPRINTF(FPE_INSN, ("fpu_execute: FCMPU\n")); rt >>= 2; fpu_explode(fe, &fe->fe_f1, type, ra); @@ -414,6 +459,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) * but values in registers are always * stored in double precision format. */ + FPU_EMU_EVCNT_INCR(frsp); DPRINTF(FPE_INSN, ("fpu_execute: FRSP\n")); fpu_explode(fe, fp = &fe->fe_f1, FTYPE_DBL, rb); fpu_implode(fe, fp, FTYPE_SNG, @@ -423,11 +469,13 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) break; case OPC63_FCTIW: case OPC63_FCTIWZ: + FPU_EMU_EVCNT_INCR(fctiw); DPRINTF(FPE_INSN, ("fpu_execute: FCTIW\n")); fpu_explode(fe, fp = &fe->fe_f1, type, rb); type = FTYPE_INT; break; case OPC63_FCMPO: + FPU_EMU_EVCNT_INCR(fcmpo); DPRINTF(FPE_INSN, ("fpu_execute: FCMPO\n")); rt >>= 2; fpu_explode(fe, &fe->fe_f1, type, ra); @@ -440,11 +488,13 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) setcr = 1; break; case OPC63_MTFSB1: + FPU_EMU_EVCNT_INCR(mtfsb1); DPRINTF(FPE_INSN, ("fpu_execute: MTFSB1\n")); fe->fe_fpscr |= (~(FPSCR_VX|FPSR_EX) & (1<<(31-rt))); break; case OPC63_FNEG: + FPU_EMU_EVCNT_INCR(fnegabs); DPRINTF(FPE_INSN, ("fpu_execute: FNEGABS\n")); memcpy(&fs->fpreg[rt], &fs->fpreg[rb], sizeof(double)); @@ -452,6 +502,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) *a ^= (1 << 31); break; case OPC63_MCRFS: + FPU_EMU_EVCNT_INCR(mcrfs); DPRINTF(FPE_INSN, ("fpu_execute: MCRFS\n")); cond = 0; rt &= 0x1c; @@ -467,16 +518,19 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) tf->cr |= (mask << (28 - rt)); break; case OPC63_MTFSB0: + FPU_EMU_EVCNT_INCR(mtfsb0); DPRINTF(FPE_INSN, ("fpu_execute: MTFSB0\n")); fe->fe_fpscr &= ((FPSCR_VX|FPSR_EX) & ~(1<<(31-rt))); break; case OPC63_FMR: + FPU_EMU_EVCNT_INCR(fmr); DPRINTF(FPE_INSN, ("fpu_execute: FMR\n")); memcpy(&fs->fpreg[rt], &fs->fpreg[rb], sizeof(double)); break; case OPC63_MTFSFI: + FPU_EMU_EVCNT_INCR(mtfsfi); DPRINTF(FPE_INSN, ("fpu_execute: MTFSFI\n")); rb >>= 1; rt &= 0x1c; /* Already left-shifted 4 */ @@ -487,6 +541,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) /* XXX weird stuff about OX, FX, FEX, and VX should be handled */ break; case OPC63_FNABS: + FPU_EMU_EVCNT_INCR(fnabs); DPRINTF(FPE_INSN, ("fpu_execute: FABS\n")); memcpy(&fs->fpreg[rt], &fs->fpreg[rb], sizeof(double)); @@ -494,6 +549,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) *a |= (1 << 31); break; case OPC63_FABS: + FPU_EMU_EVCNT_INCR(fabs); DPRINTF(FPE_INSN, ("fpu_execute: FABS\n")); memcpy(&fs->fpreg[rt], &fs->fpreg[rb], sizeof(double)); @@ -501,11 +557,13 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) *a &= ~(1 << 31); break; case OPC63_MFFS: + FPU_EMU_EVCNT_INCR(mffs); DPRINTF(FPE_INSN, ("fpu_execute: MFFS\n")); memcpy(&fs->fpreg[rt], &fs->fpscr, sizeof(fs->fpscr)); break; case OPC63_MTFSF: + FPU_EMU_EVCNT_INCR(mtfsf); DPRINTF(FPE_INSN, ("fpu_execute: MTFSF\n")); if ((rt = instr.i_xfl.i_flm) == -1) mask = -1; @@ -524,11 +582,13 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) break; case OPC63_FCTID: case OPC63_FCTIDZ: + FPU_EMU_EVCNT_INCR(fctid); DPRINTF(FPE_INSN, ("fpu_execute: FCTID\n")); fpu_explode(fe, fp = &fe->fe_f1, type, rb); type = FTYPE_LNG; break; case OPC63_FCFID: + FPU_EMU_EVCNT_INCR(fcfid); DPRINTF(FPE_INSN, ("fpu_execute: FCFID\n")); type = FTYPE_LNG; fpu_explode(fe, fp = &fe->fe_f1, type, rb); @@ -550,29 +610,34 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) type = FTYPE_DBL; switch ((unsigned int)instr.i_a.i_xo) { case OPC59_FDIVS: + FPU_EMU_EVCNT_INCR(fdiv); DPRINTF(FPE_INSN, ("fpu_execute: FDIV\n")); fpu_explode(fe, &fe->fe_f1, type, ra); fpu_explode(fe, &fe->fe_f2, type, rb); fp = fpu_div(fe); break; case OPC59_FSUBS: + FPU_EMU_EVCNT_INCR(fsub); DPRINTF(FPE_INSN, ("fpu_execute: FSUB\n")); fpu_explode(fe, &fe->fe_f1, type, ra); fpu_explode(fe, &fe->fe_f2, type, rb); fp = fpu_sub(fe); break; case OPC59_FADDS: + FPU_EMU_EVCNT_INCR(fadd); DPRINTF(FPE_INSN, ("fpu_execute: FADD\n")); fpu_explode(fe, &fe->fe_f1, type, ra); fpu_explode(fe, &fe->fe_f2, type, rb); fp = fpu_add(fe); break; case OPC59_FSQRTS: + FPU_EMU_EVCNT_INCR(fsqrt); DPRINTF(FPE_INSN, ("fpu_execute: FSQRT\n")); fpu_explode(fe, &fe->fe_f1, type, rb); fp = fpu_sqrt(fe); break; case OPC63M_FSEL: + FPU_EMU_EVCNT_INCR(fsel); DPRINTF(FPE_INSN, ("fpu_execute: FSEL\n")); a = (int *)&fe->fe_fpstate->fpreg[ra]; if ((*a & 0x80000000) && (*a & 0x7fffffff)) @@ -583,6 +648,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) sizeof(double)); break; case OPC59_FRES: + FPU_EMU_EVCNT_INCR(fpres); DPRINTF(FPE_INSN, ("fpu_execute: FPRES\n")); fpu_explode(fe, &fe->fe_f1, type, rb); fp = fpu_sqrt(fe); @@ -592,6 +658,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) fpu_div(fe); break; case OPC59_FMULS: + FPU_EMU_EVCNT_INCR(fmul); DPRINTF(FPE_INSN, ("fpu_execute: FMUL\n")); fpu_explode(fe, &fe->fe_f1, type, ra); fpu_explode(fe, &fe->fe_f2, type, rc); @@ -599,6 +666,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) break; case OPC63M_FRSQRTE: /* Reciprocal sqrt() estimate */ + FPU_EMU_EVCNT_INCR(frsqrte); DPRINTF(FPE_INSN, ("fpu_execute: FRSQRTE\n")); fpu_explode(fe, &fe->fe_f1, type, rb); fe->fe_f2 = *fp; @@ -608,6 +676,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) fpu_div(fe); break; case OPC59_FMSUBS: + FPU_EMU_EVCNT_INCR(fmulsub); DPRINTF(FPE_INSN, ("fpu_execute: FMULSUB\n")); fpu_explode(fe, &fe->fe_f1, type, ra); fpu_explode(fe, &fe->fe_f2, type, rc); @@ -617,6 +686,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) fp = fpu_sub(fe); break; case OPC59_FMADDS: + FPU_EMU_EVCNT_INCR(fmuladd); DPRINTF(FPE_INSN, ("fpu_execute: FMULADD\n")); fpu_explode(fe, &fe->fe_f1, type, ra); fpu_explode(fe, &fe->fe_f2, type, rc); @@ -626,6 +696,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) fp = fpu_add(fe); break; case OPC59_FNMSUBS: + FPU_EMU_EVCNT_INCR(fnmsub); DPRINTF(FPE_INSN, ("fpu_execute: FNMSUB\n")); fpu_explode(fe, &fe->fe_f1, type, ra); fpu_explode(fe, &fe->fe_f2, type, rc); @@ -637,6 +708,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn) fp->fp_sign ^= 1; break; case OPC59_FNMADDS: + FPU_EMU_EVCNT_INCR(fnmadd); DPRINTF(FPE_INSN, ("fpu_execute: FNMADD\n")); fpu_explode(fe, &fe->fe_f1, type, ra); fpu_explode(fe, &fe->fe_f2, type, rc);