summaryrefslogtreecommitdiff
path: root/usr/src/uts/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/sparc')
-rw-r--r--usr/src/uts/sparc/fpu/fpu_simulator.c554
-rw-r--r--usr/src/uts/sparc/os/driver_aliases7
-rw-r--r--usr/src/uts/sparc/os/name_to_major7
-rw-r--r--usr/src/uts/sparc/sys/Makefile8
-rw-r--r--usr/src/uts/sparc/sys/cpu.h11
-rw-r--r--usr/src/uts/sparc/sys/fm/cpu/SPARC64-VI.h118
-rw-r--r--usr/src/uts/sparc/sys/fpu/fpu_simulator.h35
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 {