Files
Run-Sun3-SunOS-4.1.1/tme-0.8_up/ic/sparc/sparc-fpu-auto.c
Amberelle Mason ac30ff9032 Initial import
Initial import of SunOS 4.1.1 and TME 0.8
2023-05-01 12:16:40 -04:00

900 lines
37 KiB
C

/* automatically generated by sparc-fpu-auto.sh, do not edit! */
_TME_RCSID("$Id: sparc-fpu-auto.sh,v 1.6 2009/11/08 16:27:12 fredette Exp $");
/* this sets the floating-point condition codes after a
single-precision operation: */
static void inline
_tme_sparc_fpu_fcc_single(struct tme_sparc *ic, const struct tme_float *dst, int trap_on_nan)
{
tme_uint32_t fcc;
unsigned int cc;
/* set fcc: */
fcc = (tme_float_is_nan(dst, (TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))
? TME_SPARC_FSR_FCC_UN
: tme_float_is_zero(dst, (TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))
? TME_SPARC_FSR_FCC_EQ
: tme_float_is_negative(dst, (TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))
? TME_SPARC_FSR_FCC_LT
: TME_SPARC_FSR_FCC_GT);
/* if this is an FCMPE and this is a NaN, we always cause an invalid exception: */
if (trap_on_nan && fcc == TME_SPARC_FSR_FCC_UN) {
_tme_sparc_fpu_exception_ieee754(&ic->tme_sparc_fpu_ieee754_ctl, TME_FLOAT_EXCEPTION_INVALID);
}
/* set the floating-point condition codes: */
if (TME_SPARC_VERSION(ic) >= 9) {
cc = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x3 << 25));
if (cc != 0) {
fcc = TME_FIELD_MASK_EXTRACTU(fcc, TME_SPARC_FSR_FCC);
ic->tme_sparc_fpu_xfsr
= ((ic->tme_sparc_fpu_xfsr
& ~ (tme_uint32_t) (0x3 << (2 * (cc - 1))))
| (fcc << (2 * (cc - 1))));
return;
}
}
ic->tme_sparc_fpu_fsr = (ic->tme_sparc_fpu_fsr & ~TME_SPARC_FSR_FCC) | fcc;
}
/* if the most significant bit of the NaN fraction is zero,
this is a signaling NaN: */
#define _TME_SPARC_FPU_IS_SNAN_SINGLE(a) (((*(a)) & ((0x007f0000 | (0x007f0000 >> 1)) ^ (0x007f0000 >> 1))) != 0)
static tme_int8_t
_tme_sparc_fpu_is_snan_single(tme_uint32_t *value)
{
return (_TME_SPARC_FPU_IS_SNAN_SINGLE(value));
}
/* single-precision NaN propagation: */
static void
_tme_sparc_fpu_nan_from_nans_single(struct tme_ieee754_ctl *ctl,
const tme_uint32_t *a,
const tme_uint32_t *b,
tme_uint32_t *z)
{
struct tme_sparc *ic;
int a_is_snan;
int b_is_snan;
/* recover our data structure : */
ic = ctl->tme_ieee754_ctl_private;
/* see if any of the NaNs are signaling NaNs: */
a_is_snan = _TME_SPARC_FPU_IS_SNAN_SINGLE(a);
b_is_snan = _TME_SPARC_FPU_IS_SNAN_SINGLE(b);
/* if either operand is a signaling NaN: */
if (a_is_snan || b_is_snan) {
/* signal the signaling NaN: */
_tme_sparc_fpu_exception_ieee754(ctl, TME_FLOAT_EXCEPTION_INVALID);
}
/* if and only if a (corresponding to f[rs1]) is a signaling NaN, do
we return a. at all other times we return b (corresponding to f[rs2]): */
if (a_is_snan) {
b = a;
}
/* return the NaN, but make sure it's nonsignaling: */
*z = *b;
(*(z)) |= ((0x007f0000 | (0x007f0000 >> 1)) ^ (0x007f0000 >> 1));
}
/* this sets the floating-point condition codes after a
double-precision operation: */
static void inline
_tme_sparc_fpu_fcc_double(struct tme_sparc *ic, const struct tme_float *dst, int trap_on_nan)
{
tme_uint32_t fcc;
unsigned int cc;
/* set fcc: */
fcc = (tme_float_is_nan(dst, (TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))
? TME_SPARC_FSR_FCC_UN
: tme_float_is_zero(dst, (TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))
? TME_SPARC_FSR_FCC_EQ
: tme_float_is_negative(dst, (TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))
? TME_SPARC_FSR_FCC_LT
: TME_SPARC_FSR_FCC_GT);
/* if this is an FCMPE and this is a NaN, we always cause an invalid exception: */
if (trap_on_nan && fcc == TME_SPARC_FSR_FCC_UN) {
_tme_sparc_fpu_exception_ieee754(&ic->tme_sparc_fpu_ieee754_ctl, TME_FLOAT_EXCEPTION_INVALID);
}
/* set the floating-point condition codes: */
if (TME_SPARC_VERSION(ic) >= 9) {
cc = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x3 << 25));
if (cc != 0) {
fcc = TME_FIELD_MASK_EXTRACTU(fcc, TME_SPARC_FSR_FCC);
ic->tme_sparc_fpu_xfsr
= ((ic->tme_sparc_fpu_xfsr
& ~ (tme_uint32_t) (0x3 << (2 * (cc - 1))))
| (fcc << (2 * (cc - 1))));
return;
}
}
ic->tme_sparc_fpu_fsr = (ic->tme_sparc_fpu_fsr & ~TME_SPARC_FSR_FCC) | fcc;
}
/* if the most significant bit of the NaN fraction is zero,
this is a signaling NaN: */
#define _TME_SPARC_FPU_IS_SNAN_DOUBLE(a) (((*(a)).tme_value64_uint32_hi & ((0x000f0000 | (0x000f0000 >> 1)) ^ (0x000f0000 >> 1))) != 0)
static tme_int8_t
_tme_sparc_fpu_is_snan_double(union tme_value64 *value)
{
return (_TME_SPARC_FPU_IS_SNAN_DOUBLE(value));
}
/* double-precision NaN propagation: */
static void
_tme_sparc_fpu_nan_from_nans_double(struct tme_ieee754_ctl *ctl,
const union tme_value64 *a,
const union tme_value64 *b,
union tme_value64 *z)
{
struct tme_sparc *ic;
int a_is_snan;
int b_is_snan;
/* recover our data structure : */
ic = ctl->tme_ieee754_ctl_private;
/* see if any of the NaNs are signaling NaNs: */
a_is_snan = _TME_SPARC_FPU_IS_SNAN_DOUBLE(a);
b_is_snan = _TME_SPARC_FPU_IS_SNAN_DOUBLE(b);
/* if either operand is a signaling NaN: */
if (a_is_snan || b_is_snan) {
/* signal the signaling NaN: */
_tme_sparc_fpu_exception_ieee754(ctl, TME_FLOAT_EXCEPTION_INVALID);
}
/* if and only if a (corresponding to f[rs1]) is a signaling NaN, do
we return a. at all other times we return b (corresponding to f[rs2]): */
if (a_is_snan) {
b = a;
}
/* return the NaN, but make sure it's nonsignaling: */
*z = *b;
(*(z)).tme_value64_uint32_hi |= ((0x000f0000 | (0x000f0000 >> 1)) ^ (0x000f0000 >> 1));
}
/* this sets the floating-point condition codes after a
quad-precision operation: */
static void inline
_tme_sparc_fpu_fcc_quad(struct tme_sparc *ic, const struct tme_float *dst, int trap_on_nan)
{
tme_uint32_t fcc;
unsigned int cc;
/* set fcc: */
fcc = (tme_float_is_nan(dst, (TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))
? TME_SPARC_FSR_FCC_UN
: tme_float_is_zero(dst, (TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))
? TME_SPARC_FSR_FCC_EQ
: tme_float_is_negative(dst, (TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))
? TME_SPARC_FSR_FCC_LT
: TME_SPARC_FSR_FCC_GT);
/* if this is an FCMPE and this is a NaN, we always cause an invalid exception: */
if (trap_on_nan && fcc == TME_SPARC_FSR_FCC_UN) {
_tme_sparc_fpu_exception_ieee754(&ic->tme_sparc_fpu_ieee754_ctl, TME_FLOAT_EXCEPTION_INVALID);
}
/* set the floating-point condition codes: */
if (TME_SPARC_VERSION(ic) >= 9) {
cc = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x3 << 25));
if (cc != 0) {
fcc = TME_FIELD_MASK_EXTRACTU(fcc, TME_SPARC_FSR_FCC);
ic->tme_sparc_fpu_xfsr
= ((ic->tme_sparc_fpu_xfsr
& ~ (tme_uint32_t) (0x3 << (2 * (cc - 1))))
| (fcc << (2 * (cc - 1))));
return;
}
}
ic->tme_sparc_fpu_fsr = (ic->tme_sparc_fpu_fsr & ~TME_SPARC_FSR_FCC) | fcc;
}
/* if the most significant bit of the NaN fraction is zero,
this is a signaling NaN: */
#define _TME_SPARC_FPU_IS_SNAN_QUAD(a) (((*(a)).tme_float_ieee754_quad_hi.tme_value64_uint32_hi & ((0x0000ffff | (0x0000ffff >> 1)) ^ (0x0000ffff >> 1))) != 0)
static tme_int8_t
_tme_sparc_fpu_is_snan_quad(struct tme_float_ieee754_quad *value)
{
return (_TME_SPARC_FPU_IS_SNAN_QUAD(value));
}
/* quad-precision NaN propagation: */
static void
_tme_sparc_fpu_nan_from_nans_quad(struct tme_ieee754_ctl *ctl,
const struct tme_float_ieee754_quad *a,
const struct tme_float_ieee754_quad *b,
struct tme_float_ieee754_quad *z)
{
struct tme_sparc *ic;
int a_is_snan;
int b_is_snan;
/* recover our data structure : */
ic = ctl->tme_ieee754_ctl_private;
/* see if any of the NaNs are signaling NaNs: */
a_is_snan = _TME_SPARC_FPU_IS_SNAN_QUAD(a);
b_is_snan = _TME_SPARC_FPU_IS_SNAN_QUAD(b);
/* if either operand is a signaling NaN: */
if (a_is_snan || b_is_snan) {
/* signal the signaling NaN: */
_tme_sparc_fpu_exception_ieee754(ctl, TME_FLOAT_EXCEPTION_INVALID);
}
/* if and only if a (corresponding to f[rs1]) is a signaling NaN, do
we return a. at all other times we return b (corresponding to f[rs2]): */
if (a_is_snan) {
b = a;
}
/* return the NaN, but make sure it's nonsignaling: */
*z = *b;
(*(z)).tme_float_ieee754_quad_hi.tme_value64_uint32_hi |= ((0x0000ffff | (0x0000ffff >> 1)) ^ (0x0000ffff >> 1));
}
#define _TME_SPARC_FPU_UNIMPL tme_sparc_fpu_exception(ic, TME_SPARC_FSR_FTT_unimplemented_FPop)
#define _TME_SPARC_FPU_UNIMPL_IF(flags) do { if ((ic->tme_sparc_fpu_flags & (flags)) != 0) { _TME_SPARC_FPU_UNIMPL; } } while (/* CONSTCOND */ 0)
void
tme_sparc_fpu_fpop1(struct tme_sparc *ic)
{
tme_uint8_t rounding_mode;
unsigned int opf;
unsigned int fpreg_rd_number_encoded;
unsigned int fpreg_rd_number;
const struct tme_float *fpreg_rs1;
const struct tme_float *fpreg_rs2;
struct tme_float fpreg_rs1_buffer;
struct tme_float fpreg_rs2_buffer;
struct tme_float fpreg_rd;
unsigned int fpreg_rd_format;
/* set the rounding mode: */
switch (ic->tme_sparc_fpu_fsr & TME_SPARC_FSR_RND) {
default: assert(FALSE);
case TME_SPARC_FSR_RND_RN: rounding_mode = TME_FLOAT_ROUND_NEAREST_EVEN; break;
case TME_SPARC_FSR_RND_RZ: rounding_mode = TME_FLOAT_ROUND_TO_ZERO; break;
case TME_SPARC_FSR_RND_RM: rounding_mode = TME_FLOAT_ROUND_DOWN; break;
case TME_SPARC_FSR_RND_RP: rounding_mode = TME_FLOAT_ROUND_UP; break;
}
ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = rounding_mode;
/* decode the rd and opf fields: */
fpreg_rd_number_encoded = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
opf = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x1ff << 5));
/* silence uninitialized variable warnings: */
fpreg_rd_number = 0;
#ifdef _TME_SPARC_RECODE_VERIFY
/* clear the rd buffer: */
memset(&fpreg_rd, 0, sizeof(fpreg_rd));
#endif /* _TME_SPARC_RECODE_VERIFY */
/* dispatch on the opf field: */
switch (opf) {
#define _TME_SPARC_FPU_FORMAT_RS1(format) fpreg_rs1 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS1, (format))
#define _TME_SPARC_FPU_FORMAT_RS2(format) fpreg_rs2 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS2, (format))
#define _TME_SPARC_FPU_FORMAT_RD(format) do { fpreg_rd_format = (format) | TME_IEEE754_FPREG_FORMAT_BUILTIN; fpreg_rd_number = tme_sparc_fpu_fpreg_decode(ic, fpreg_rd_number_encoded, fpreg_rd_format); } while (/* CONSTCOND */ 0)
case 1: /* 000000001 FMOVs: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_BEGIN;
fpreg_rd = *fpreg_rs2;
break;
case 2: /* 000000010 FMOVd: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_BEGIN;
fpreg_rd = *fpreg_rs2;
break;
case 5: /* 000000101 FNEGs: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_BEGIN;
fpreg_rd = *fpreg_rs2;
fpreg_rd.tme_float_value_ieee754_single ^= 0x80000000;
break;
case 6: /* 000000110 FNEGd: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_BEGIN;
fpreg_rd = *fpreg_rs2;
fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint32_hi ^= 0x80000000;
break;
case 9: /* 000001001 FABSs: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_BEGIN;
fpreg_rd = *fpreg_rs2;
fpreg_rd.tme_float_value_ieee754_single &= ~0x80000000;
break;
case 10: /* 000001010 FABSd: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_BEGIN;
fpreg_rd = *fpreg_rs2;
fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint32_hi &= ~0x80000000;
break;
case 41: /* 000101001 FSQRTs: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FSQRT);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_sqrt,
fpreg_rs2, &fpreg_rd);
break;
case 42: /* 000101010 FSQRTd: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FSQRT);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_sqrt,
fpreg_rs2, &fpreg_rd);
break;
case 43: /* 000101011 FSQRTq: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FSQRT | TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_sqrt,
fpreg_rs2, &fpreg_rd);
break;
case 65: /* 001000001 FADDs: */
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_add,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
break;
case 66: /* 001000010 FADDd: */
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_add,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
break;
case 67: /* 001000011 FADDq: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_add,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
break;
case 69: /* 001000101 FSUBs: */
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_sub,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
break;
case 70: /* 001000110 FSUBd: */
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_sub,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
break;
case 71: /* 001000111 FSUBq: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_sub,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
break;
case 73: /* 001001001 FMULs: */
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_mul,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
break;
case 74: /* 001001010 FMULd: */
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_mul,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
break;
case 75: /* 001001011 FMULq: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_mul,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
break;
case 77: /* 001001101 FDIVs: */
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_div,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
break;
case 78: /* 001001110 FDIVd: */
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_div,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
break;
case 79: /* 001001111 FDIVq: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_div,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
break;
case 105: /* 001101001 FsMULd: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FMUL_WIDER);
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_single,
fpreg_rs1, &fpreg_rs1_buffer);
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_single,
fpreg_rs2, &fpreg_rs2_buffer);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_mul,
&fpreg_rs1_buffer, &fpreg_rs2_buffer, &fpreg_rd);
break;
case 110: /* 001101110 FdMULq: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FMUL_WIDER | TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_double,
fpreg_rs1, &fpreg_rs1_buffer);
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_double,
fpreg_rs2, &fpreg_rs2_buffer);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_mul,
&fpreg_rs1_buffer, &fpreg_rs2_buffer, &fpreg_rd);
break;
case 129: /* 010000001 FsTOx: */
#ifdef TME_HAVE_INT64_T
if (__tme_predict_true(TME_SPARC_VERSION(ic) >= 9)) {
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_BEGIN;
fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_to_int64,
fpreg_rs2, &fpreg_rd.tme_float_value_ieee754_double.tme_value64_int);
break;
}
#endif /* TME_HAVE_INT64_T */
_TME_SPARC_FPU_UNIMPL;
fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
break;
case 130: /* 010000010 FdTOx: */
#ifdef TME_HAVE_INT64_T
if (__tme_predict_true(TME_SPARC_VERSION(ic) >= 9)) {
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_BEGIN;
fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_to_int64,
fpreg_rs2, &fpreg_rd.tme_float_value_ieee754_double.tme_value64_int);
break;
}
#endif /* TME_HAVE_INT64_T */
_TME_SPARC_FPU_UNIMPL;
fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
break;
case 131: /* 010000011 FqTOx: */
#ifdef TME_HAVE_INT64_T
if (__tme_predict_true(TME_SPARC_VERSION(ic) >= 9)) {
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_BEGIN;
fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_to_int64,
fpreg_rs2, &fpreg_rd.tme_float_value_ieee754_double.tme_value64_int);
break;
}
#endif /* TME_HAVE_INT64_T */
_TME_SPARC_FPU_UNIMPL;
fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
break;
case 132: /* 010000100 FxTOs: */
#ifdef TME_HAVE_INT64_T
if (__tme_predict_true(TME_SPARC_VERSION(ic) >= 9)) {
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_BEGIN;
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_from_int64,
fpreg_rs2->tme_float_value_ieee754_double.tme_value64_int, &fpreg_rd);
break;
}
#endif /* TME_HAVE_INT64_T */
_TME_SPARC_FPU_UNIMPL;
fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
break;
case 136: /* 010001000 FxTOd: */
#ifdef TME_HAVE_INT64_T
if (__tme_predict_true(TME_SPARC_VERSION(ic) >= 9)) {
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_BEGIN;
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_int64,
fpreg_rs2->tme_float_value_ieee754_double.tme_value64_int, &fpreg_rd);
break;
}
#endif /* TME_HAVE_INT64_T */
_TME_SPARC_FPU_UNIMPL;
fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
break;
case 140: /* 010001100 FxTOq: */
#ifdef TME_HAVE_INT64_T
if (__tme_predict_true(TME_SPARC_VERSION(ic) >= 9)) {
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
_TME_SPARC_FPU_BEGIN;
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_int64,
fpreg_rs2->tme_float_value_ieee754_double.tme_value64_int, &fpreg_rd);
break;
}
#endif /* TME_HAVE_INT64_T */
_TME_SPARC_FPU_UNIMPL;
fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
break;
case 196: /* 011000100 FiTOs: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_BEGIN;
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_from_int32,
fpreg_rs2->tme_float_value_ieee754_single, &fpreg_rd);
break;
case 198: /* 011000110 FdTOs: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_from_double,
fpreg_rs2, &fpreg_rd);
break;
case 199: /* 011000111 FqTOs: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_from_quad,
fpreg_rs2, &fpreg_rd);
break;
case 200: /* 011001000 FiTOd: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_BEGIN;
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_int32,
fpreg_rs2->tme_float_value_ieee754_single, &fpreg_rd);
break;
case 201: /* 011001001 FsTOd: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_single,
fpreg_rs2, &fpreg_rd);
break;
case 203: /* 011001011 FqTOd: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_quad,
fpreg_rs2, &fpreg_rd);
break;
case 204: /* 011001100 FiTOq: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
_TME_SPARC_FPU_BEGIN;
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_int32,
fpreg_rs2->tme_float_value_ieee754_single, &fpreg_rd);
break;
case 205: /* 011001101 FsTOq: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_single,
fpreg_rs2, &fpreg_rd);
break;
case 206: /* 011001110 FdTOq: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_double,
fpreg_rs2, &fpreg_rd);
break;
case 209: /* 011010001 FsTOi: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_BEGIN;
fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_to_int32,
fpreg_rs2, (tme_int32_t *) &fpreg_rd.tme_float_value_ieee754_single);
break;
case 210: /* 011010010 FdTOi: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_BEGIN;
fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_to_int32,
fpreg_rs2, (tme_int32_t *) &fpreg_rd.tme_float_value_ieee754_single);
break;
case 211: /* 011010011 FqTOi: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_BEGIN;
fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
_TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_to_int32,
fpreg_rs2, (tme_int32_t *) &fpreg_rd.tme_float_value_ieee754_single);
break;
default:
_TME_SPARC_FPU_UNIMPL;
fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
break;
#undef _TME_SPARC_FPU_FORMAT_RS1
#undef _TME_SPARC_FPU_FORMAT_RS2
#undef _TME_SPARC_FPU_FORMAT_RD
}
/* store any destination: */
if (fpreg_rd_format != TME_IEEE754_FPREG_FORMAT_NULL) {
tme_sparc_fpu_fpreg_format(ic, fpreg_rd_number, fpreg_rd_format);
ic->tme_sparc_fpu_fpregs[fpreg_rd_number] = fpreg_rd;
TME_SPARC_FPU_DIRTY(ic, fpreg_rd_number);
}
}
void
tme_sparc_fpu_fpop2(struct tme_sparc *ic)
{
tme_uint8_t rounding_mode;
unsigned int opf;
unsigned int fpreg_rd_number_encoded;
unsigned int fpreg_rd_number;
const struct tme_float *fpreg_rs1;
const struct tme_float *fpreg_rs2;
unsigned int cc;
tme_uint32_t conds_mask;
unsigned int cc_i;
tme_uint32_t cond;
struct tme_float fpreg_rd;
unsigned int fpreg_rd_format;
/* set the rounding mode: */
switch (ic->tme_sparc_fpu_fsr & TME_SPARC_FSR_RND) {
default: assert(FALSE);
case TME_SPARC_FSR_RND_RN: rounding_mode = TME_FLOAT_ROUND_NEAREST_EVEN; break;
case TME_SPARC_FSR_RND_RZ: rounding_mode = TME_FLOAT_ROUND_TO_ZERO; break;
case TME_SPARC_FSR_RND_RM: rounding_mode = TME_FLOAT_ROUND_DOWN; break;
case TME_SPARC_FSR_RND_RP: rounding_mode = TME_FLOAT_ROUND_UP; break;
}
ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = rounding_mode;
/* decode the rd and opf fields: */
fpreg_rd_number_encoded = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
opf = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x1ff << 5));
/* silence uninitialized variable warnings: */
fpreg_rd_number = 0;
#ifdef _TME_SPARC_RECODE_VERIFY
/* clear the rd buffer: */
memset(&fpreg_rd, 0, sizeof(fpreg_rd));
#endif /* _TME_SPARC_RECODE_VERIFY */
/* if this is an FMOVcc: */
if (((opf - 1) & 0x3f) < 3) {
/* if opf bit eight is set, this uses integer condition codes: */
if (opf & TME_BIT(8)) {
/* if opf bit six is set, this is unimplemented: */
if (__tme_predict_false(opf & TME_BIT(6))) {
_TME_SPARC_FPU_UNIMPL;
}
/* get %icc or %xcc, depending on opf bit seven: */
cc = ic->tme_sparc64_ireg_ccr;
if (opf & TME_BIT(7)) {
cc /= (TME_SPARC64_CCR_XCC / TME_SPARC64_CCR_ICC);
}
cc = TME_FIELD_MASK_EXTRACTU(cc, TME_SPARC64_CCR_ICC);
/* get the conditions mask: */
conds_mask = _tme_sparc_conds_icc[cc];
}
/* otherwise, this uses floating-point condition codes: */
else {
/* get the right %fcc: */
cc_i = TME_FIELD_MASK_EXTRACTU(opf, (0x3 << 6));
if (cc_i == 0) {
cc = TME_FIELD_MASK_EXTRACTU(ic->tme_sparc_fpu_fsr, TME_SPARC_FSR_FCC);
}
else {
cc = (ic->tme_sparc_fpu_xfsr >> (2 * (cc_i - 1))) & 0x3;
}
/* get the conditions mask: */
conds_mask = _tme_sparc_conds_fcc[cc];
}
/* add the not-conditions to the conditions mask: */
conds_mask += ((~conds_mask) << 8);
/* get the cond field: */
cond = TME_BIT(TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0xf << 14)));
/* if the condition is not true: */
if (!(conds_mask & cond)) {
/* return now: */
/* NB that this may expose us to guests, since we do not check
that the floating-point register numbers are valid: */
return;
}
/* clear bits six, seven, and eight in opf: */
opf &= 0x3f;
}
/* dispatch on the opf field: */
switch (opf) {
#define _TME_SPARC_FPU_FORMAT_RS1(format) fpreg_rs1 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS1, (format))
#define _TME_SPARC_FPU_FORMAT_RS2(format) fpreg_rs2 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS2, (format))
#define _TME_SPARC_FPU_FORMAT_RD(format) do { fpreg_rd_format = (format) | TME_IEEE754_FPREG_FORMAT_BUILTIN; fpreg_rd_number = tme_sparc_fpu_fpreg_decode(ic, fpreg_rd_number_encoded, fpreg_rd_format); } while (/* CONSTCOND */ 0)
case 1: /* 000000001 FMOVscc: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
_TME_SPARC_FPU_BEGIN;
fpreg_rd = *fpreg_rs2;
break;
case 2: /* 000000010 FMOVdcc: */
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
_TME_SPARC_FPU_BEGIN;
fpreg_rd = *fpreg_rs2;
break;
case 81: /* 001010001 FCMPs: */
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_sub,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
_tme_sparc_fpu_fcc_single(ic, &fpreg_rd, FALSE);
fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
break;
case 82: /* 001010010 FCMPd: */
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_sub,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
_tme_sparc_fpu_fcc_double(ic, &fpreg_rd, FALSE);
fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
break;
case 83: /* 001010011 FCMPq: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_sub,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
_tme_sparc_fpu_fcc_quad(ic, &fpreg_rd, FALSE);
fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
break;
case 85: /* 001010101 FCMPEs: */
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_sub,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
_tme_sparc_fpu_fcc_single(ic, &fpreg_rd, TRUE);
fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
break;
case 86: /* 001010110 FCMPEd: */
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_sub,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
_tme_sparc_fpu_fcc_double(ic, &fpreg_rd, TRUE);
fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
break;
case 87: /* 001010111 FCMPEq: */
_TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
_TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
_TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_sub,
fpreg_rs1, fpreg_rs2, &fpreg_rd);
_tme_sparc_fpu_fcc_quad(ic, &fpreg_rd, TRUE);
fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
break;
default:
_TME_SPARC_FPU_UNIMPL;
fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
break;
#undef _TME_SPARC_FPU_FORMAT_RS1
#undef _TME_SPARC_FPU_FORMAT_RS2
#undef _TME_SPARC_FPU_FORMAT_RD
}
/* store any destination: */
if (fpreg_rd_format != TME_IEEE754_FPREG_FORMAT_NULL) {
tme_sparc_fpu_fpreg_format(ic, fpreg_rd_number, fpreg_rd_format);
ic->tme_sparc_fpu_fpregs[fpreg_rd_number] = fpreg_rd;
TME_SPARC_FPU_DIRTY(ic, fpreg_rd_number);
}
}