diff options
Diffstat (limited to 'usr/src/uts/sparc')
-rw-r--r-- | usr/src/uts/sparc/fpu/fpu_simulator.c | 554 | ||||
-rw-r--r-- | usr/src/uts/sparc/os/driver_aliases | 7 | ||||
-rw-r--r-- | usr/src/uts/sparc/os/name_to_major | 7 | ||||
-rw-r--r-- | usr/src/uts/sparc/sys/Makefile | 8 | ||||
-rw-r--r-- | usr/src/uts/sparc/sys/cpu.h | 11 | ||||
-rw-r--r-- | usr/src/uts/sparc/sys/fm/cpu/SPARC64-VI.h | 118 | ||||
-rw-r--r-- | usr/src/uts/sparc/sys/fpu/fpu_simulator.h | 35 |
7 files changed, 493 insertions, 247 deletions
diff --git a/usr/src/uts/sparc/fpu/fpu_simulator.c b/usr/src/uts/sparc/fpu/fpu_simulator.c index a29c45f0da..0705a1023b 100644 --- a/usr/src/uts/sparc/fpu/fpu_simulator.c +++ b/usr/src/uts/sparc/fpu/fpu_simulator.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -107,6 +106,15 @@ struct fpuinfo_kstat fpuinfo = { { "fpu_sim_fqtoi", KSTAT_DATA_UINT64}, { "fpu_sim_fmovcc", KSTAT_DATA_UINT64}, { "fpu_sim_fmovr", KSTAT_DATA_UINT64}, + { "fpu_sim_fmadds", KSTAT_DATA_UINT64}, + { "fpu_sim_fmaddd", KSTAT_DATA_UINT64}, + { "fpu_sim_fmsubs", KSTAT_DATA_UINT64}, + { "fpu_sim_fmsubd", KSTAT_DATA_UINT64}, + { "fpu_sim_fnmadds", KSTAT_DATA_UINT64}, + { "fpu_sim_fnmaddd", KSTAT_DATA_UINT64}, + { "fpu_sim_fnmsubs", KSTAT_DATA_UINT64}, + { "fpu_sim_fnmsubd", KSTAT_DATA_UINT64}, + { "fpu_sim_invalid", KSTAT_DATA_UINT64}, }; struct visinfo_kstat visinfo = { @@ -182,241 +190,315 @@ _fp_fpu_simulator( */ pfpsd->fp_direction = GSR_IM(gsr) ? GSR_IRND(gsr) : fsr.rnd; pfpsd->fp_precision = fsr.rnp; - nfcc = nrd & 0x3; - if (inst.op3 == 0x35) { /* fpop2 */ - fsr.cexc = 0; - *pfsr = fsr; - if ((inst.opcode & 0xf) == 0) { - if ((fp_notp) && (inst.prec == 0)) - return (ftt_unimplemented); - FPUINFO_KSTAT(fpu_sim_fmovcc); - return (fmovcc(pfpsd, inst, pfsr)); /* fmovcc */ - } else if ((inst.opcode & 0x7) == 1) { - if ((fp_notp) && (inst.prec == 0)) - return (ftt_unimplemented); - FPUINFO_KSTAT(fpu_sim_fmovr); - return (fmovr(pfpsd, inst)); /* fmovr */ - } - } - /* ibit not valid for fpop1 instructions */ - if ((fp_notp) && (inst.ibit != 0)) - return (ftt_unimplemented); - if ((fp_notp) && (inst.prec == 0)) { /* fxto[sdq], fito[sdq] */ - if ((inst.opcode != flltos) && - (inst.opcode != flltod) && - (inst.opcode != flltox) && - (inst.opcode != fitos) && - (inst.opcode != fitod) && - (inst.opcode != fitox)) { - return (ftt_unimplemented); - } - } - switch (inst.opcode) { - case fmovs: /* also covers fmovd, fmovq */ - if (inst.prec < 2) { /* fmovs */ - _fp_unpack_word(pfpsd, &usr, nrs2); - _fp_pack_word(pfpsd, &usr, nrd); - FPUINFO_KSTAT(fpu_sim_fmovs); - } else { /* fmovd */ - _fp_unpack_extword(pfpsd, &lusr, nrs2); - _fp_pack_extword(pfpsd, &lusr, nrd); - if (inst.prec > 2) { /* fmovq */ - _fp_unpack_extword(pfpsd, &lusr, nrs2+2); - _fp_pack_extword(pfpsd, &lusr, nrd+2); - FPUINFO_KSTAT(fpu_sim_fmovq); - } else { - FPUINFO_KSTAT(fpu_sim_fmovd); + + if (inst.op3 == 0x37) { /* IMPDEP2B FMA-fused opcode */ + fp_fma_inst_type *fma_inst; + uint32_t nrs3; + unpacked us3; + unpacked ust; + fma_inst = (fp_fma_inst_type *) &inst; + nrs2 = fma_inst->rs2; + nrs3 = fma_inst->rs3; + switch (fma_inst->var) { + case fmadd: + _fp_unpack(pfpsd, &us1, nrs1, fma_inst->sz); + _fp_unpack(pfpsd, &us2, nrs2, fma_inst->sz); + _fp_mul(pfpsd, &us1, &us2, &ust); + if ((pfpsd->fp_current_exceptions & fsr.tem) == 0) { + _fp_unpack(pfpsd, &us3, nrs3, fma_inst->sz); + _fp_add(pfpsd, &ust, &us3, &ud); + _fp_pack(pfpsd, &ud, nrd, fma_inst->sz); } - } - break; - case fabss: /* also covers fabsd, fabsq */ - if (inst.prec < 2) { /* fabss */ - _fp_unpack_word(pfpsd, &usr, nrs2); - usr &= 0x7fffffff; - _fp_pack_word(pfpsd, &usr, nrd); - FPUINFO_KSTAT(fpu_sim_fabss); - } else { /* fabsd */ - _fp_unpack_extword(pfpsd, &lusr, nrs2); - lusr &= 0x7fffffffffffffff; - _fp_pack_extword(pfpsd, &lusr, nrd); - if (inst.prec > 2) { /* fabsq */ - _fp_unpack_extword(pfpsd, &lusr, nrs2+2); - _fp_pack_extword(pfpsd, &lusr, nrd+2); - FPUINFO_KSTAT(fpu_sim_fabsq); - } else { - FPUINFO_KSTAT(fpu_sim_fabsd); + FPUINFO_KSTAT_PREC(fma_inst->sz, fpu_sim_fmadds, + fpu_sim_fmaddd, fpu_sim_invalid); + break; + case fmsub: + _fp_unpack(pfpsd, &us1, nrs1, fma_inst->sz); + _fp_unpack(pfpsd, &us2, nrs2, fma_inst->sz); + _fp_mul(pfpsd, &us1, &us2, &ust); + if ((pfpsd->fp_current_exceptions & fsr.tem) == 0) { + _fp_unpack(pfpsd, &us3, nrs3, fma_inst->sz); + _fp_sub(pfpsd, &ust, &us3, &ud); + _fp_pack(pfpsd, &ud, nrd, fma_inst->sz); + } + FPUINFO_KSTAT_PREC(fma_inst->sz, fpu_sim_fmsubs, + fpu_sim_fmsubd, fpu_sim_invalid); + break; + case fnmadd: + _fp_unpack(pfpsd, &us1, nrs1, fma_inst->sz); + _fp_unpack(pfpsd, &us2, nrs2, fma_inst->sz); + _fp_mul(pfpsd, &us1, &us2, &ust); + if ((pfpsd->fp_current_exceptions & fsr.tem) == 0) { + if (ust.fpclass == fp_quiet || + ust.fpclass == fp_signaling) { + _fp_pack(pfpsd, &ust, nrd, fma_inst->sz); + } else { + _fp_unpack(pfpsd, &us3, nrs3, fma_inst->sz); + _fp_add(pfpsd, &ust, &us3, &ud); + ud.sign ^= 1; + _fp_pack(pfpsd, &ud, nrd, fma_inst->sz); + } + } + FPUINFO_KSTAT_PREC(fma_inst->sz, fpu_sim_fnmadds, + fpu_sim_fnmaddd, fpu_sim_invalid); + break; + case fnmsub: + _fp_unpack(pfpsd, &us1, nrs1, fma_inst->sz); + _fp_unpack(pfpsd, &us2, nrs2, fma_inst->sz); + _fp_mul(pfpsd, &us1, &us2, &ust); + if ((pfpsd->fp_current_exceptions & fsr.tem) == 0) { + if (ust.fpclass == fp_quiet || + ust.fpclass == fp_signaling) { + _fp_pack(pfpsd, &ust, nrd, fma_inst->sz); + } else { + _fp_unpack(pfpsd, &us3, nrs3, fma_inst->sz); + _fp_sub(pfpsd, &ust, &us3, &ud); + ud.sign ^= 1; + _fp_pack(pfpsd, &ud, nrd, fma_inst->sz); + } } + FPUINFO_KSTAT_PREC(fma_inst->sz, fpu_sim_fnmsubs, + fpu_sim_fnmsubd, fpu_sim_invalid); } - break; - case fnegs: /* also covers fnegd, fnegq */ - if (inst.prec < 2) { /* fnegs */ - _fp_unpack_word(pfpsd, &usr, nrs2); - usr ^= 0x80000000; - _fp_pack_word(pfpsd, &usr, nrd); - FPUINFO_KSTAT(fpu_sim_fnegs); - } else { /* fnegd */ - _fp_unpack_extword(pfpsd, &lusr, nrs2); - lusr ^= 0x8000000000000000; - _fp_pack_extword(pfpsd, &lusr, nrd); - if (inst.prec > 2) { /* fnegq */ - _fp_unpack_extword(pfpsd, &lusr, nrs2+2); - lusr ^= 0x0000000000000000; - _fp_pack_extword(pfpsd, &lusr, nrd+2); - FPUINFO_KSTAT(fpu_sim_fnegq); - } else { - FPUINFO_KSTAT(fpu_sim_fnegd); + } else { + nfcc = nrd & 0x3; + if (inst.op3 == 0x35) { /* fpop2 */ + fsr.cexc = 0; + *pfsr = fsr; + if ((inst.opcode & 0xf) == 0) { + if ((fp_notp) && (inst.prec == 0)) + return (ftt_unimplemented); + FPUINFO_KSTAT(fpu_sim_fmovcc); + return (fmovcc(pfpsd, inst, pfsr)); /* fmovcc */ + } else if ((inst.opcode & 0x7) == 1) { + if ((fp_notp) && (inst.prec == 0)) + return (ftt_unimplemented); + FPUINFO_KSTAT(fpu_sim_fmovr); + return (fmovr(pfpsd, inst)); /* fmovr */ } } - break; - case fadd: - _fp_unpack(pfpsd, &us1, nrs1, inst.prec); - _fp_unpack(pfpsd, &us2, nrs2, inst.prec); - _fp_add(pfpsd, &us1, &us2, &ud); - _fp_pack(pfpsd, &ud, nrd, inst.prec); - FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fadds, - fpu_sim_faddd, fpu_sim_faddq); - break; - case fsub: - _fp_unpack(pfpsd, &us1, nrs1, inst.prec); - _fp_unpack(pfpsd, &us2, nrs2, inst.prec); - _fp_sub(pfpsd, &us1, &us2, &ud); - _fp_pack(pfpsd, &ud, nrd, inst.prec); - FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fsubs, - fpu_sim_fsubd, fpu_sim_fsubq); - break; - case fmul: - _fp_unpack(pfpsd, &us1, nrs1, inst.prec); - _fp_unpack(pfpsd, &us2, nrs2, inst.prec); - _fp_mul(pfpsd, &us1, &us2, &ud); - _fp_pack(pfpsd, &ud, nrd, inst.prec); - FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fmuls, - fpu_sim_fmuld, fpu_sim_fmulq); - break; - case fsmuld: - if ((fp_notp) && (inst.prec != 1)) - return (ftt_unimplemented); - _fp_unpack(pfpsd, &us1, nrs1, inst.prec); - _fp_unpack(pfpsd, &us2, nrs2, inst.prec); - _fp_mul(pfpsd, &us1, &us2, &ud); - _fp_pack(pfpsd, &ud, nrd, (enum fp_op_type) ((int)inst.prec+1)); - FPUINFO_KSTAT(fpu_sim_fsmuld); - break; - case fdmulx: - if ((fp_notp) && (inst.prec != 2)) + /* ibit not valid for fpop1 instructions */ + if ((fp_notp) && (inst.ibit != 0)) return (ftt_unimplemented); - _fp_unpack(pfpsd, &us1, nrs1, inst.prec); - _fp_unpack(pfpsd, &us2, nrs2, inst.prec); - _fp_mul(pfpsd, &us1, &us2, &ud); - _fp_pack(pfpsd, &ud, nrd, (enum fp_op_type) ((int)inst.prec+1)); - FPUINFO_KSTAT(fpu_sim_fdmulx); - break; - case fdiv: - _fp_unpack(pfpsd, &us1, nrs1, inst.prec); - _fp_unpack(pfpsd, &us2, nrs2, inst.prec); - _fp_div(pfpsd, &us1, &us2, &ud); - _fp_pack(pfpsd, &ud, nrd, inst.prec); - FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fdivs, - fpu_sim_fdivd, fpu_sim_fdivq); - break; - case fcmp: - _fp_unpack(pfpsd, &us1, nrs1, inst.prec); - _fp_unpack(pfpsd, &us2, nrs2, inst.prec); - cc = _fp_compare(pfpsd, &us1, &us2, 0); - if (!(pfpsd->fp_current_exceptions & pfpsd->fp_fsrtem)) - switch (nfcc) { - case fcc_0: - fsr.fcc0 = cc; - break; - case fcc_1: - fsr.fcc1 = cc; - break; - case fcc_2: - fsr.fcc2 = cc; - break; - case fcc_3: - fsr.fcc3 = cc; - break; + if ((fp_notp) && (inst.prec == 0)) { /* fxto[sdq], fito[sdq] */ + if ((inst.opcode != flltos) && + (inst.opcode != flltod) && + (inst.opcode != flltox) && + (inst.opcode != fitos) && + (inst.opcode != fitod) && + (inst.opcode != fitox)) { + return (ftt_unimplemented); + } + } + switch (inst.opcode) { + case fmovs: /* also covers fmovd, fmovq */ + if (inst.prec < 2) { /* fmovs */ + _fp_unpack_word(pfpsd, &usr, nrs2); + _fp_pack_word(pfpsd, &usr, nrd); + FPUINFO_KSTAT(fpu_sim_fmovs); + } else { /* fmovd */ + _fp_unpack_extword(pfpsd, &lusr, nrs2); + _fp_pack_extword(pfpsd, &lusr, nrd); + if (inst.prec > 2) { /* fmovq */ + _fp_unpack_extword(pfpsd, &lusr, nrs2+2); + _fp_pack_extword(pfpsd, &lusr, nrd+2); + FPUINFO_KSTAT(fpu_sim_fmovq); + } else { + FPUINFO_KSTAT(fpu_sim_fmovd); + } } - FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fcmps, - fpu_sim_fcmpd, fpu_sim_fcmpq); - break; - case fcmpe: - _fp_unpack(pfpsd, &us1, nrs1, inst.prec); - _fp_unpack(pfpsd, &us2, nrs2, inst.prec); - cc = _fp_compare(pfpsd, &us1, &us2, 1); - if (!(pfpsd->fp_current_exceptions & pfpsd->fp_fsrtem)) - switch (nfcc) { - case fcc_0: - fsr.fcc0 = cc; - break; - case fcc_1: - fsr.fcc1 = cc; - break; - case fcc_2: - fsr.fcc2 = cc; - break; - case fcc_3: - fsr.fcc3 = cc; - break; + break; + case fabss: /* also covers fabsd, fabsq */ + if (inst.prec < 2) { /* fabss */ + _fp_unpack_word(pfpsd, &usr, nrs2); + usr &= 0x7fffffff; + _fp_pack_word(pfpsd, &usr, nrd); + FPUINFO_KSTAT(fpu_sim_fabss); + } else { /* fabsd */ + _fp_unpack_extword(pfpsd, &lusr, nrs2); + lusr &= 0x7fffffffffffffff; + _fp_pack_extword(pfpsd, &lusr, nrd); + if (inst.prec > 2) { /* fabsq */ + _fp_unpack_extword(pfpsd, &lusr, nrs2+2); + _fp_pack_extword(pfpsd, &lusr, nrd+2); + FPUINFO_KSTAT(fpu_sim_fabsq); + } else { + FPUINFO_KSTAT(fpu_sim_fabsd); + } } - FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fcmpes, - fpu_sim_fcmped, fpu_sim_fcmpeq); - break; - case fsqrt: - _fp_unpack(pfpsd, &us1, nrs2, inst.prec); - _fp_sqrt(pfpsd, &us1, &ud); - _fp_pack(pfpsd, &ud, nrd, inst.prec); - FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fsqrts, - fpu_sim_fsqrtd, fpu_sim_fsqrtq); - break; - case ftoi: - _fp_unpack(pfpsd, &us1, nrs2, inst.prec); - pfpsd->fp_direction = fp_tozero; - /* Force rounding toward zero. */ - _fp_pack(pfpsd, &us1, nrd, fp_op_int32); - FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fstoi, - fpu_sim_fdtoi, fpu_sim_fqtoi); - break; - case ftoll: - _fp_unpack(pfpsd, &us1, nrs2, inst.prec); - pfpsd->fp_direction = fp_tozero; - /* Force rounding toward zero. */ - _fp_pack(pfpsd, &us1, nrd, fp_op_int64); - FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fstox, - fpu_sim_fdtox, fpu_sim_fqtox); - break; - case flltos: - _fp_unpack(pfpsd, &us1, nrs2, fp_op_int64); - _fp_pack(pfpsd, &us1, nrd, fp_op_single); - FPUINFO_KSTAT(fpu_sim_fxtos); - break; - case flltod: - _fp_unpack(pfpsd, &us1, nrs2, fp_op_int64); - _fp_pack(pfpsd, &us1, nrd, fp_op_double); - FPUINFO_KSTAT(fpu_sim_fxtod); - break; - case flltox: - _fp_unpack(pfpsd, &us1, nrs2, fp_op_int64); - _fp_pack(pfpsd, &us1, nrd, fp_op_extended); - FPUINFO_KSTAT(fpu_sim_fxtoq); - break; - case fitos: - _fp_unpack(pfpsd, &us1, nrs2, inst.prec); - _fp_pack(pfpsd, &us1, nrd, fp_op_single); - FPUINFO_KSTAT(fpu_sim_fitos); - break; - case fitod: - _fp_unpack(pfpsd, &us1, nrs2, inst.prec); - _fp_pack(pfpsd, &us1, nrd, fp_op_double); - FPUINFO_KSTAT(fpu_sim_fitod); - break; - case fitox: - _fp_unpack(pfpsd, &us1, nrs2, inst.prec); - _fp_pack(pfpsd, &us1, nrd, fp_op_extended); - FPUINFO_KSTAT(fpu_sim_fitoq); - break; - default: - return (ftt_unimplemented); + break; + case fnegs: /* also covers fnegd, fnegq */ + if (inst.prec < 2) { /* fnegs */ + _fp_unpack_word(pfpsd, &usr, nrs2); + usr ^= 0x80000000; + _fp_pack_word(pfpsd, &usr, nrd); + FPUINFO_KSTAT(fpu_sim_fnegs); + } else { /* fnegd */ + _fp_unpack_extword(pfpsd, &lusr, nrs2); + lusr ^= 0x8000000000000000; + _fp_pack_extword(pfpsd, &lusr, nrd); + if (inst.prec > 2) { /* fnegq */ + _fp_unpack_extword(pfpsd, &lusr, nrs2+2); + lusr ^= 0x0000000000000000; + _fp_pack_extword(pfpsd, &lusr, nrd+2); + FPUINFO_KSTAT(fpu_sim_fnegq); + } else { + FPUINFO_KSTAT(fpu_sim_fnegd); + } + } + break; + case fadd: + _fp_unpack(pfpsd, &us1, nrs1, inst.prec); + _fp_unpack(pfpsd, &us2, nrs2, inst.prec); + _fp_add(pfpsd, &us1, &us2, &ud); + _fp_pack(pfpsd, &ud, nrd, inst.prec); + FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fadds, + fpu_sim_faddd, fpu_sim_faddq); + break; + case fsub: + _fp_unpack(pfpsd, &us1, nrs1, inst.prec); + _fp_unpack(pfpsd, &us2, nrs2, inst.prec); + _fp_sub(pfpsd, &us1, &us2, &ud); + _fp_pack(pfpsd, &ud, nrd, inst.prec); + FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fsubs, + fpu_sim_fsubd, fpu_sim_fsubq); + break; + case fmul: + _fp_unpack(pfpsd, &us1, nrs1, inst.prec); + _fp_unpack(pfpsd, &us2, nrs2, inst.prec); + _fp_mul(pfpsd, &us1, &us2, &ud); + _fp_pack(pfpsd, &ud, nrd, inst.prec); + FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fmuls, + fpu_sim_fmuld, fpu_sim_fmulq); + break; + case fsmuld: + if ((fp_notp) && (inst.prec != 1)) + return (ftt_unimplemented); + _fp_unpack(pfpsd, &us1, nrs1, inst.prec); + _fp_unpack(pfpsd, &us2, nrs2, inst.prec); + _fp_mul(pfpsd, &us1, &us2, &ud); + _fp_pack(pfpsd, &ud, nrd, + (enum fp_op_type) ((int)inst.prec+1)); + FPUINFO_KSTAT(fpu_sim_fsmuld); + break; + case fdmulx: + if ((fp_notp) && (inst.prec != 2)) + return (ftt_unimplemented); + _fp_unpack(pfpsd, &us1, nrs1, inst.prec); + _fp_unpack(pfpsd, &us2, nrs2, inst.prec); + _fp_mul(pfpsd, &us1, &us2, &ud); + _fp_pack(pfpsd, &ud, nrd, + (enum fp_op_type) ((int)inst.prec+1)); + FPUINFO_KSTAT(fpu_sim_fdmulx); + break; + case fdiv: + _fp_unpack(pfpsd, &us1, nrs1, inst.prec); + _fp_unpack(pfpsd, &us2, nrs2, inst.prec); + _fp_div(pfpsd, &us1, &us2, &ud); + _fp_pack(pfpsd, &ud, nrd, inst.prec); + FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fdivs, + fpu_sim_fdivd, fpu_sim_fdivq); + break; + case fcmp: + _fp_unpack(pfpsd, &us1, nrs1, inst.prec); + _fp_unpack(pfpsd, &us2, nrs2, inst.prec); + cc = _fp_compare(pfpsd, &us1, &us2, 0); + if (!(pfpsd->fp_current_exceptions & pfpsd->fp_fsrtem)) + switch (nfcc) { + case fcc_0: + fsr.fcc0 = cc; + break; + case fcc_1: + fsr.fcc1 = cc; + break; + case fcc_2: + fsr.fcc2 = cc; + break; + case fcc_3: + fsr.fcc3 = cc; + break; + } + FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fcmps, + fpu_sim_fcmpd, fpu_sim_fcmpq); + break; + case fcmpe: + _fp_unpack(pfpsd, &us1, nrs1, inst.prec); + _fp_unpack(pfpsd, &us2, nrs2, inst.prec); + cc = _fp_compare(pfpsd, &us1, &us2, 1); + if (!(pfpsd->fp_current_exceptions & pfpsd->fp_fsrtem)) + switch (nfcc) { + case fcc_0: + fsr.fcc0 = cc; + break; + case fcc_1: + fsr.fcc1 = cc; + break; + case fcc_2: + fsr.fcc2 = cc; + break; + case fcc_3: + fsr.fcc3 = cc; + break; + } + FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fcmpes, + fpu_sim_fcmped, fpu_sim_fcmpeq); + break; + case fsqrt: + _fp_unpack(pfpsd, &us1, nrs2, inst.prec); + _fp_sqrt(pfpsd, &us1, &ud); + _fp_pack(pfpsd, &ud, nrd, inst.prec); + FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fsqrts, + fpu_sim_fsqrtd, fpu_sim_fsqrtq); + break; + case ftoi: + _fp_unpack(pfpsd, &us1, nrs2, inst.prec); + pfpsd->fp_direction = fp_tozero; + /* Force rounding toward zero. */ + _fp_pack(pfpsd, &us1, nrd, fp_op_int32); + FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fstoi, + fpu_sim_fdtoi, fpu_sim_fqtoi); + break; + case ftoll: + _fp_unpack(pfpsd, &us1, nrs2, inst.prec); + pfpsd->fp_direction = fp_tozero; + /* Force rounding toward zero. */ + _fp_pack(pfpsd, &us1, nrd, fp_op_int64); + FPUINFO_KSTAT_PREC(inst.prec, fpu_sim_fstox, + fpu_sim_fdtox, fpu_sim_fqtox); + break; + case flltos: + _fp_unpack(pfpsd, &us1, nrs2, fp_op_int64); + _fp_pack(pfpsd, &us1, nrd, fp_op_single); + FPUINFO_KSTAT(fpu_sim_fxtos); + break; + case flltod: + _fp_unpack(pfpsd, &us1, nrs2, fp_op_int64); + _fp_pack(pfpsd, &us1, nrd, fp_op_double); + FPUINFO_KSTAT(fpu_sim_fxtod); + break; + case flltox: + _fp_unpack(pfpsd, &us1, nrs2, fp_op_int64); + _fp_pack(pfpsd, &us1, nrd, fp_op_extended); + FPUINFO_KSTAT(fpu_sim_fxtoq); + break; + case fitos: + _fp_unpack(pfpsd, &us1, nrs2, inst.prec); + _fp_pack(pfpsd, &us1, nrd, fp_op_single); + FPUINFO_KSTAT(fpu_sim_fitos); + break; + case fitod: + _fp_unpack(pfpsd, &us1, nrs2, inst.prec); + _fp_pack(pfpsd, &us1, nrd, fp_op_double); + FPUINFO_KSTAT(fpu_sim_fitod); + break; + case fitox: + _fp_unpack(pfpsd, &us1, nrs2, inst.prec); + _fp_pack(pfpsd, &us1, nrd, fp_op_extended); + FPUINFO_KSTAT(fpu_sim_fitoq); + break; + default: + return (ftt_unimplemented); + } } fsr.cexc = pfpsd->fp_current_exceptions; if (pfpsd->fp_current_exceptions) { /* Exception(s) occurred. */ @@ -450,6 +532,7 @@ _fp_fpu_simulator( return (ftt_none); } + /* * fpu_vis_sim simulates fpu and vis instructions; * It can work with both real and pcb image registers. @@ -495,7 +578,8 @@ fpu_vis_sim( pregs, (ulong_t *)pregs->r_sp, pfp); return (ftt); } else if ((fp.inst.hibits == 2) && - ((fp.inst.op3 == 0x34) || (fp.inst.op3 == 0x35))) { + ((fp.inst.op3 == 0x34) || (fp.inst.op3 == 0x35) || + (fp.inst.op3 == 0x37))) { ftt = _fp_fpu_simulator(pfpsd, fp.inst, pfsr, gsr); if (ftt == ftt_none || ftt == ftt_ieee) { pregs->r_pc = pregs->r_npc; @@ -573,7 +657,8 @@ fp_emulator( return (ftt); if ((fp.inst.hibits == 2) && - ((fp.inst.op3 == 0x34) || (fp.inst.op3 == 0x35))) { + ((fp.inst.op3 == 0x34) || (fp.inst.op3 == 0x35) || + (fp.inst.op3 == 0x37))) { ftt = _fp_fpu_simulator(pfpsd, fp.inst, (fsr_type *)&tfsr, gsr); /* Do not retry emulated instruction. */ pregs->r_pc = pregs->r_npc; @@ -612,7 +697,8 @@ again: if (ftt != ftt_none) return (ftt); if ((fp.inst.hibits == 2) && /* fpops */ - ((fp.inst.op3 == 0x34) || (fp.inst.op3 == 0x35))) { + ((fp.inst.op3 == 0x34) || (fp.inst.op3 == 0x35) || + (fp.inst.op3 == 0x37))) { ftt = _fp_fpu_simulator(pfpsd, fp.inst, (fsr_type *)&tfsr, gsr); /* Do not retry emulated instruction. */ pfpu->fpu_fsr = tfsr; diff --git a/usr/src/uts/sparc/os/driver_aliases b/usr/src/uts/sparc/os/driver_aliases index db3ba0352c..787f3d32f0 100644 --- a/usr/src/uts/sparc/os/driver_aliases +++ b/usr/src/uts/sparc/os/driver_aliases @@ -144,6 +144,7 @@ ibd "ib.ipib" px "SUNW,sun4v-pci" px "pci108e,80f0" px "pciex108e,80f0" +px "pciex108e,80f8" px_pci "pci1033,124" px_pci "pci1033,125" px_pci "pci8086,340" @@ -161,3 +162,9 @@ epic "SUNW,ebus-pic18lf65j10-env" i8042 "8042" mouse8042 "pnpPNP,f03" kb8042 "pnpPNP,303" +pcicmu "pci10cf,138f" +pcicmu "pci10cf,1390" +oplpanel "FJSV,panel" +oplmsu "FJSV,oplmsu" +mc-opl "FJSV,oplmc" +scfd "FJSV,scfc" diff --git a/usr/src/uts/sparc/os/name_to_major b/usr/src/uts/sparc/os/name_to_major index d38eb494a4..81708db46f 100644 --- a/usr/src/uts/sparc/os/name_to_major +++ b/usr/src/uts/sparc/os/name_to_major @@ -207,3 +207,10 @@ mouse8042 256 kssl 257 epic 258 adm1026 259 +pcicmu 260 +oplpanel 261 +oplmsu 262 +scfd 263 +mc-opl 264 +dm2s 265 +oplkmdrv 266 diff --git a/usr/src/uts/sparc/sys/Makefile b/usr/src/uts/sparc/sys/Makefile index 72c122f969..b75af1c382 100644 --- a/usr/src/uts/sparc/sys/Makefile +++ b/usr/src/uts/sparc/sys/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -68,7 +67,8 @@ FPUHDRS= \ FMCPUHDRS= \ UltraSPARC-II.h \ UltraSPARC-III.h \ - UltraSPARC-T1.h + UltraSPARC-T1.h \ + SPARC64-VI.h ROOTDIR= $(ROOT)/usr/include/sys ROOTDIRS= \ diff --git a/usr/src/uts/sparc/sys/cpu.h b/usr/src/uts/sparc/sys/cpu.h index be90896939..6f0fbc919d 100644 --- a/usr/src/uts/sparc/sys/cpu.h +++ b/usr/src/uts/sparc/sys/cpu.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -69,7 +68,9 @@ extern int vac; /* * Use to insert cpu-dependent instructions into spin loops */ -#define SMT_PAUSE() /* none */ +#pragma weak cpu_smt_pause +extern void cpu_smt_pause(); +#define SMT_PAUSE() { if (&cpu_smt_pause) cpu_smt_pause(); } #endif /* defined(_KERNEL) && !defined(_ASM) */ diff --git a/usr/src/uts/sparc/sys/fm/cpu/SPARC64-VI.h b/usr/src/uts/sparc/sys/fm/cpu/SPARC64-VI.h new file mode 100644 index 0000000000..c1de31063d --- /dev/null +++ b/usr/src/uts/sparc/sys/fm/cpu/SPARC64-VI.h @@ -0,0 +1,118 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_FM_SPARC64_VI_H +#define _SYS_FM_SPARC64_VI_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ereport class subcategories for SPARC64-VI */ +#define FM_EREPORT_CPU_SPARC64_VI "SPARC64-VI" +#define FM_EREPORT_CPU_UNSUPPORTED "unsupported" + +/* + * Ereport payload definitions. + */ +#define FM_EREPORT_PAYLOAD_NAME_SFSR "sfsr" +#define FM_EREPORT_PAYLOAD_NAME_SFAR "sfar" +#define FM_EREPORT_PAYLOAD_NAME_UGESR "ugesr" +#define FM_EREPORT_PAYLOAD_NAME_PC "pc" +#define FM_EREPORT_PAYLOAD_NAME_TL "tl" +#define FM_EREPORT_PAYLOAD_NAME_TT "tt" +#define FM_EREPORT_PAYLOAD_NAME_PRIV "privileged" +#define FM_EREPORT_PAYLOAD_NAME_RESOURCE "resource" +#define FM_EREPORT_PAYLOAD_NAME_FLT_STATUS "flt-status" + +#define FM_EREPORT_PAYLOAD_FLAG_SFSR 0x00000001 +#define FM_EREPORT_PAYLOAD_FLAG_SFAR 0x00000002 +#define FM_EREPORT_PAYLOAD_FLAG_UGESR 0x00000004 +#define FM_EREPORT_PAYLOAD_FLAG_PC 0x00000008 +#define FM_EREPORT_PAYLOAD_FLAG_TL 0x00000010 +#define FM_EREPORT_PAYLOAD_FLAG_TT 0x00000020 +#define FM_EREPORT_PAYLOAD_FLAG_PRIV 0x00000040 +#define FM_EREPORT_PAYLOAD_FLAG_RESOURCE 0x00000080 +#define FM_EREPORT_PAYLOAD_FLAG_FLT_STATUS 0x00000100 + +#define FM_EREPORT_PAYLOAD_FLAGS_TRAP \ + (FM_EREPORT_PAYLOAD_FLAG_TL | \ + FM_EREPORT_PAYLOAD_FLAG_TT) + +#define FM_EREPORT_PAYLOAD_SYNC (FM_EREPORT_PAYLOAD_FLAG_SFSR | \ + FM_EREPORT_PAYLOAD_FLAG_SFAR | \ + FM_EREPORT_PAYLOAD_FLAG_PC | \ + FM_EREPORT_PAYLOAD_FLAGS_TRAP | \ + FM_EREPORT_PAYLOAD_FLAG_PRIV | \ + FM_EREPORT_PAYLOAD_FLAG_FLT_STATUS | \ + FM_EREPORT_PAYLOAD_FLAG_RESOURCE) + +#define FM_EREPORT_PAYLOAD_URGENT (FM_EREPORT_PAYLOAD_FLAG_UGESR | \ + FM_EREPORT_PAYLOAD_FLAG_PC | \ + FM_EREPORT_PAYLOAD_FLAGS_TRAP | \ + FM_EREPORT_PAYLOAD_FLAG_PRIV) + +/* + * FM_EREPORT_PAYLOAD_SYNC + */ + +#define FM_EREPORT_CPU_UE_MEM "ue-mem" +#define FM_EREPORT_CPU_UE_CHANNEL "ue-channel" +#define FM_EREPORT_CPU_UE_CPU "ue-cpu" +#define FM_EREPORT_CPU_UE_PATH "ue-path" +#define FM_EREPORT_CPU_BERR "berr" +#define FM_EREPORT_CPU_BTO "bto" +#define FM_EREPORT_CPU_MTLB "mtlb" +#define FM_EREPORT_CPU_TLBP "tlbp" +#define FM_EREPORT_CPU_INV_SFSR "inv-sfsr" + +/* + * FM_EREPORT_PAYLOAD_URGENT + */ + +#define FM_EREPORT_CPU_CRE "cre" +#define FM_EREPORT_CPU_TSBCTX "tsb-ctx" +#define FM_EREPORT_CPU_TSBP "tsbp" +#define FM_EREPORT_CPU_PSTATE "pstate" +#define FM_EREPORT_CPU_TSTATE "tstate" +#define FM_EREPORT_CPU_IUG_F "iug-f" +#define FM_EREPORT_CPU_IUG_R "iug-r" +#define FM_EREPORT_CPU_SDC "sdc" +#define FM_EREPORT_CPU_WDT "wdt" +#define FM_EREPORT_CPU_DTLB "dtlb" +#define FM_EREPORT_CPU_ITLB "itlb" +#define FM_EREPORT_CPU_CORE "core-err" +#define FM_EREPORT_CPU_DAE "dae" +#define FM_EREPORT_CPU_IAE "iae" +#define FM_EREPORT_CPU_UGE "uge" +#define FM_EREPORT_CPU_INV_URG "inv-urg" + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_FM_SPARC64_VI_H */ diff --git a/usr/src/uts/sparc/sys/fpu/fpu_simulator.h b/usr/src/uts/sparc/sys/fpu/fpu_simulator.h index 70b1bb54b7..3b46025fcf 100644 --- a/usr/src/uts/sparc/sys/fpu/fpu_simulator.h +++ b/usr/src/uts/sparc/sys/fpu/fpu_simulator.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -221,6 +220,25 @@ typedef /* FPU instruction. */ uint32_t rs2 : 5; /* Second operand. */ } fp_inst_type; +enum fp_op_fma_var { /* IMPDEP2B FMA-fused instr. variations */ + fmadd = 0, + fmsub = 1, + fnmsub = 2, + fnmadd = 3 +}; + +typedef /* IMPDEP2B FPU FMA-fused instruction. */ + struct { + uint32_t hibits : 2; /* Top two bits. */ + uint32_t rd : 5; /* Destination. */ + uint32_t op3 : 6; /* Main op code. */ + uint32_t rs1 : 5; /* First operand. */ + uint32_t rs3 : 5; /* Third operand */ + uint32_t /* enum fp_op_fma_var */ var : 2; /* Instr. variation */ + uint32_t sz : 2; /* Size */ + uint32_t rs2 : 5; /* Second operand. */ +} fp_fma_inst_type; + typedef /* Integer condition code. */ struct { uint32_t : 28; /* the unused part */ @@ -305,6 +323,15 @@ struct fpuinfo_kstat { struct kstat_named fpu_sim_fqtoi; struct kstat_named fpu_sim_fmovcc; struct kstat_named fpu_sim_fmovr; + struct kstat_named fpu_sim_fmadds; + struct kstat_named fpu_sim_fmaddd; + struct kstat_named fpu_sim_fmsubs; + struct kstat_named fpu_sim_fmsubd; + struct kstat_named fpu_sim_fnmadds; + struct kstat_named fpu_sim_fnmaddd; + struct kstat_named fpu_sim_fnmsubs; + struct kstat_named fpu_sim_fnmsubd; + struct kstat_named fpu_sim_invalid; }; struct visinfo_kstat { |