Annotation of tme/ic/sparc/sparc-fpu-auto.c, revision 1.1.1.2

1.1       root        1: /* automatically generated by sparc-fpu-auto.sh, do not edit! */
1.1.1.2 ! root        2: _TME_RCSID("$Id: sparc-fpu-auto.sh,v 1.6 2009/11/08 16:27:12 fredette Exp $");
1.1       root        3: 
                      4: /* this sets the floating-point condition codes after a
                      5:    single-precision operation: */
                      6: static void inline
                      7: _tme_sparc_fpu_fcc_single(struct tme_sparc *ic, const struct tme_float *dst, int trap_on_nan)
                      8: {
                      9:   tme_uint32_t fcc;
1.1.1.2 ! root       10:   unsigned int cc;
1.1       root       11: 
                     12:   /* set fcc: */
                     13:   fcc = (tme_float_is_nan(dst, (TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))
                     14:          ? TME_SPARC_FSR_FCC_UN
                     15:         : tme_float_is_zero(dst, (TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))
                     16:         ? TME_SPARC_FSR_FCC_EQ
                     17:         : tme_float_is_negative(dst, (TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))
                     18:         ? TME_SPARC_FSR_FCC_LT
                     19:         : TME_SPARC_FSR_FCC_GT);
                     20: 
                     21:   /* if this is an FCMPE and this is a NaN, we always cause an invalid exception: */
                     22:   if (trap_on_nan && fcc == TME_SPARC_FSR_FCC_UN) {
                     23:     _tme_sparc_fpu_exception_ieee754(&ic->tme_sparc_fpu_ieee754_ctl, TME_FLOAT_EXCEPTION_INVALID);
                     24:   }
                     25: 
                     26:   /* set the floating-point condition codes: */
1.1.1.2 ! root       27:   if (TME_SPARC_VERSION(ic) >= 9) {
        !            28:     cc = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x3 << 25));
        !            29:     if (cc != 0) {
        !            30:       fcc = TME_FIELD_MASK_EXTRACTU(fcc, TME_SPARC_FSR_FCC);
        !            31:       ic->tme_sparc_fpu_xfsr
        !            32:        = ((ic->tme_sparc_fpu_xfsr
        !            33:            & ~ (tme_uint32_t) (0x3 << (2 * (cc - 1))))
        !            34:           | (fcc << (2 * (cc - 1))));
        !            35:       return;
        !            36:     }
        !            37:   }
1.1       root       38:   ic->tme_sparc_fpu_fsr = (ic->tme_sparc_fpu_fsr & ~TME_SPARC_FSR_FCC) | fcc;
                     39: }
                     40: 
                     41: /* if the most significant bit of the NaN fraction is zero,
                     42:    this is a signaling NaN: */
                     43: #define _TME_SPARC_FPU_IS_SNAN_SINGLE(a) (((*(a)) & ((0x007f0000 | (0x007f0000 >> 1)) ^ (0x007f0000 >> 1))) != 0)
                     44: static tme_int8_t
                     45: _tme_sparc_fpu_is_snan_single(tme_uint32_t *value)
                     46: {
                     47:   return (_TME_SPARC_FPU_IS_SNAN_SINGLE(value));
                     48: }
                     49: 
                     50: /* single-precision NaN propagation: */
                     51: static void
                     52: _tme_sparc_fpu_nan_from_nans_single(struct tme_ieee754_ctl *ctl, 
                     53:                                     const tme_uint32_t *a,
                     54:                                     const tme_uint32_t *b,
                     55:                                     tme_uint32_t *z)
                     56: {
                     57:   struct tme_sparc *ic;
                     58:   int a_is_snan;
                     59:   int b_is_snan;
                     60: 
                     61:   /* recover our data structure : */
                     62:   ic = ctl->tme_ieee754_ctl_private;    
                     63: 
                     64:   /* see if any of the NaNs are signaling NaNs: */
                     65:   a_is_snan = _TME_SPARC_FPU_IS_SNAN_SINGLE(a);
                     66:   b_is_snan = _TME_SPARC_FPU_IS_SNAN_SINGLE(b);
                     67: 
                     68:   /* if either operand is a signaling NaN: */
                     69:   if (a_is_snan || b_is_snan) {
                     70: 
                     71:     /* signal the signaling NaN: */
                     72:     _tme_sparc_fpu_exception_ieee754(ctl, TME_FLOAT_EXCEPTION_INVALID);
                     73:   }
                     74: 
                     75:   /* if and only if a (corresponding to f[rs1]) is a signaling NaN, do 
                     76:      we return a. at all other times we return b (corresponding to f[rs2]): */
                     77:   if (a_is_snan) {
                     78:     b = a;
                     79:   }
                     80: 
                     81:   /* return the NaN, but make sure it's nonsignaling: */
                     82:   *z = *b;
                     83:   (*(z)) |= ((0x007f0000 | (0x007f0000 >> 1)) ^ (0x007f0000 >> 1));
                     84: }
                     85: 
                     86: 
                     87: /* this sets the floating-point condition codes after a
                     88:    double-precision operation: */
                     89: static void inline
                     90: _tme_sparc_fpu_fcc_double(struct tme_sparc *ic, const struct tme_float *dst, int trap_on_nan)
                     91: {
                     92:   tme_uint32_t fcc;
1.1.1.2 ! root       93:   unsigned int cc;
1.1       root       94: 
                     95:   /* set fcc: */
                     96:   fcc = (tme_float_is_nan(dst, (TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))
                     97:          ? TME_SPARC_FSR_FCC_UN
                     98:         : tme_float_is_zero(dst, (TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))
                     99:         ? TME_SPARC_FSR_FCC_EQ
                    100:         : tme_float_is_negative(dst, (TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))
                    101:         ? TME_SPARC_FSR_FCC_LT
                    102:         : TME_SPARC_FSR_FCC_GT);
                    103: 
                    104:   /* if this is an FCMPE and this is a NaN, we always cause an invalid exception: */
                    105:   if (trap_on_nan && fcc == TME_SPARC_FSR_FCC_UN) {
                    106:     _tme_sparc_fpu_exception_ieee754(&ic->tme_sparc_fpu_ieee754_ctl, TME_FLOAT_EXCEPTION_INVALID);
                    107:   }
                    108: 
                    109:   /* set the floating-point condition codes: */
1.1.1.2 ! root      110:   if (TME_SPARC_VERSION(ic) >= 9) {
        !           111:     cc = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x3 << 25));
        !           112:     if (cc != 0) {
        !           113:       fcc = TME_FIELD_MASK_EXTRACTU(fcc, TME_SPARC_FSR_FCC);
        !           114:       ic->tme_sparc_fpu_xfsr
        !           115:        = ((ic->tme_sparc_fpu_xfsr
        !           116:            & ~ (tme_uint32_t) (0x3 << (2 * (cc - 1))))
        !           117:           | (fcc << (2 * (cc - 1))));
        !           118:       return;
        !           119:     }
        !           120:   }
1.1       root      121:   ic->tme_sparc_fpu_fsr = (ic->tme_sparc_fpu_fsr & ~TME_SPARC_FSR_FCC) | fcc;
                    122: }
                    123: 
                    124: /* if the most significant bit of the NaN fraction is zero,
                    125:    this is a signaling NaN: */
                    126: #define _TME_SPARC_FPU_IS_SNAN_DOUBLE(a) (((*(a)).tme_value64_uint32_hi & ((0x000f0000 | (0x000f0000 >> 1)) ^ (0x000f0000 >> 1))) != 0)
                    127: static tme_int8_t
                    128: _tme_sparc_fpu_is_snan_double(union tme_value64 *value)
                    129: {
                    130:   return (_TME_SPARC_FPU_IS_SNAN_DOUBLE(value));
                    131: }
                    132: 
                    133: /* double-precision NaN propagation: */
                    134: static void
                    135: _tme_sparc_fpu_nan_from_nans_double(struct tme_ieee754_ctl *ctl, 
                    136:                                     const union tme_value64 *a,
                    137:                                     const union tme_value64 *b,
                    138:                                     union tme_value64 *z)
                    139: {
                    140:   struct tme_sparc *ic;
                    141:   int a_is_snan;
                    142:   int b_is_snan;
                    143: 
                    144:   /* recover our data structure : */
                    145:   ic = ctl->tme_ieee754_ctl_private;    
                    146: 
                    147:   /* see if any of the NaNs are signaling NaNs: */
                    148:   a_is_snan = _TME_SPARC_FPU_IS_SNAN_DOUBLE(a);
                    149:   b_is_snan = _TME_SPARC_FPU_IS_SNAN_DOUBLE(b);
                    150: 
                    151:   /* if either operand is a signaling NaN: */
                    152:   if (a_is_snan || b_is_snan) {
                    153: 
                    154:     /* signal the signaling NaN: */
                    155:     _tme_sparc_fpu_exception_ieee754(ctl, TME_FLOAT_EXCEPTION_INVALID);
                    156:   }
                    157: 
                    158:   /* if and only if a (corresponding to f[rs1]) is a signaling NaN, do 
                    159:      we return a. at all other times we return b (corresponding to f[rs2]): */
                    160:   if (a_is_snan) {
                    161:     b = a;
                    162:   }
                    163: 
                    164:   /* return the NaN, but make sure it's nonsignaling: */
                    165:   *z = *b;
                    166:   (*(z)).tme_value64_uint32_hi |= ((0x000f0000 | (0x000f0000 >> 1)) ^ (0x000f0000 >> 1));
                    167: }
                    168: 
                    169: 
                    170: /* this sets the floating-point condition codes after a
                    171:    quad-precision operation: */
                    172: static void inline
                    173: _tme_sparc_fpu_fcc_quad(struct tme_sparc *ic, const struct tme_float *dst, int trap_on_nan)
                    174: {
                    175:   tme_uint32_t fcc;
1.1.1.2 ! root      176:   unsigned int cc;
1.1       root      177: 
                    178:   /* set fcc: */
                    179:   fcc = (tme_float_is_nan(dst, (TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))
                    180:          ? TME_SPARC_FSR_FCC_UN
                    181:         : tme_float_is_zero(dst, (TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))
                    182:         ? TME_SPARC_FSR_FCC_EQ
                    183:         : tme_float_is_negative(dst, (TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))
                    184:         ? TME_SPARC_FSR_FCC_LT
                    185:         : TME_SPARC_FSR_FCC_GT);
                    186: 
                    187:   /* if this is an FCMPE and this is a NaN, we always cause an invalid exception: */
                    188:   if (trap_on_nan && fcc == TME_SPARC_FSR_FCC_UN) {
                    189:     _tme_sparc_fpu_exception_ieee754(&ic->tme_sparc_fpu_ieee754_ctl, TME_FLOAT_EXCEPTION_INVALID);
                    190:   }
                    191: 
                    192:   /* set the floating-point condition codes: */
1.1.1.2 ! root      193:   if (TME_SPARC_VERSION(ic) >= 9) {
        !           194:     cc = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x3 << 25));
        !           195:     if (cc != 0) {
        !           196:       fcc = TME_FIELD_MASK_EXTRACTU(fcc, TME_SPARC_FSR_FCC);
        !           197:       ic->tme_sparc_fpu_xfsr
        !           198:        = ((ic->tme_sparc_fpu_xfsr
        !           199:            & ~ (tme_uint32_t) (0x3 << (2 * (cc - 1))))
        !           200:           | (fcc << (2 * (cc - 1))));
        !           201:       return;
        !           202:     }
        !           203:   }
1.1       root      204:   ic->tme_sparc_fpu_fsr = (ic->tme_sparc_fpu_fsr & ~TME_SPARC_FSR_FCC) | fcc;
                    205: }
                    206: 
                    207: /* if the most significant bit of the NaN fraction is zero,
                    208:    this is a signaling NaN: */
                    209: #define _TME_SPARC_FPU_IS_SNAN_QUAD(a) (((*(a)).tme_float_ieee754_quad_hi.tme_value64_uint32_hi & ((0x0000ffff | (0x0000ffff >> 1)) ^ (0x0000ffff >> 1))) != 0)
                    210: static tme_int8_t
                    211: _tme_sparc_fpu_is_snan_quad(struct tme_float_ieee754_quad *value)
                    212: {
                    213:   return (_TME_SPARC_FPU_IS_SNAN_QUAD(value));
                    214: }
                    215: 
                    216: /* quad-precision NaN propagation: */
                    217: static void
                    218: _tme_sparc_fpu_nan_from_nans_quad(struct tme_ieee754_ctl *ctl, 
                    219:                                     const struct tme_float_ieee754_quad *a,
                    220:                                     const struct tme_float_ieee754_quad *b,
                    221:                                     struct tme_float_ieee754_quad *z)
                    222: {
                    223:   struct tme_sparc *ic;
                    224:   int a_is_snan;
                    225:   int b_is_snan;
                    226: 
                    227:   /* recover our data structure : */
                    228:   ic = ctl->tme_ieee754_ctl_private;    
                    229: 
                    230:   /* see if any of the NaNs are signaling NaNs: */
                    231:   a_is_snan = _TME_SPARC_FPU_IS_SNAN_QUAD(a);
                    232:   b_is_snan = _TME_SPARC_FPU_IS_SNAN_QUAD(b);
                    233: 
                    234:   /* if either operand is a signaling NaN: */
                    235:   if (a_is_snan || b_is_snan) {
                    236: 
                    237:     /* signal the signaling NaN: */
                    238:     _tme_sparc_fpu_exception_ieee754(ctl, TME_FLOAT_EXCEPTION_INVALID);
                    239:   }
                    240: 
                    241:   /* if and only if a (corresponding to f[rs1]) is a signaling NaN, do 
                    242:      we return a. at all other times we return b (corresponding to f[rs2]): */
                    243:   if (a_is_snan) {
                    244:     b = a;
                    245:   }
                    246: 
                    247:   /* return the NaN, but make sure it's nonsignaling: */
                    248:   *z = *b;
                    249:   (*(z)).tme_float_ieee754_quad_hi.tme_value64_uint32_hi |= ((0x0000ffff | (0x0000ffff >> 1)) ^ (0x0000ffff >> 1));
                    250: }
                    251: 
                    252: #define _TME_SPARC_FPU_UNIMPL tme_sparc_fpu_exception(ic, TME_SPARC_FSR_FTT_unimplemented_FPop)
                    253: #define _TME_SPARC_FPU_UNIMPL_IF(flags) do { if ((ic->tme_sparc_fpu_flags & (flags)) != 0) { _TME_SPARC_FPU_UNIMPL; } } while (/* CONSTCOND */ 0)
                    254: 
                    255: void
                    256: tme_sparc_fpu_fpop1(struct tme_sparc *ic)
                    257: {
                    258:   tme_uint8_t rounding_mode;
                    259:   unsigned int opf;
1.1.1.2 ! root      260:   unsigned int fpreg_rd_number_encoded;
1.1       root      261:   unsigned int fpreg_rd_number;
                    262:   const struct tme_float *fpreg_rs1;
                    263:   const struct tme_float *fpreg_rs2;
                    264:   struct tme_float fpreg_rs1_buffer;
                    265:   struct tme_float fpreg_rs2_buffer;
                    266:   struct tme_float fpreg_rd;
                    267:   unsigned int fpreg_rd_format;
                    268: 
                    269:   /* set the rounding mode: */
                    270:   switch (ic->tme_sparc_fpu_fsr & TME_SPARC_FSR_RND) {
                    271:   default: assert(FALSE);
                    272:   case TME_SPARC_FSR_RND_RN: rounding_mode = TME_FLOAT_ROUND_NEAREST_EVEN; break;
                    273:   case TME_SPARC_FSR_RND_RZ: rounding_mode = TME_FLOAT_ROUND_TO_ZERO; break;
                    274:   case TME_SPARC_FSR_RND_RM: rounding_mode = TME_FLOAT_ROUND_DOWN; break;
                    275:   case TME_SPARC_FSR_RND_RP: rounding_mode = TME_FLOAT_ROUND_UP; break;
                    276:   }
                    277:   ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = rounding_mode;
                    278: 
                    279:   /* decode the rd and opf fields: */
1.1.1.2 ! root      280:   fpreg_rd_number_encoded = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
1.1       root      281:   opf = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x1ff << 5));
                    282: 
1.1.1.2 ! root      283:   /* silence uninitialized variable warnings: */
        !           284:   fpreg_rd_number = 0;
        !           285: 
        !           286: #ifdef _TME_SPARC_RECODE_VERIFY
        !           287:   /* clear the rd buffer: */
        !           288:   memset(&fpreg_rd, 0, sizeof(fpreg_rd));
        !           289: #endif /* _TME_SPARC_RECODE_VERIFY */
        !           290: 
1.1       root      291:   /* dispatch on the opf field: */
                    292:   switch (opf) {
                    293: #define _TME_SPARC_FPU_FORMAT_RS1(format) fpreg_rs1 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS1, (format))
                    294: #define _TME_SPARC_FPU_FORMAT_RS2(format) fpreg_rs2 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS2, (format))
1.1.1.2 ! root      295: #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)
1.1       root      296: 
                    297:   case 1:  /* 000000001 FMOVs: */
                    298:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    299:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    300:     _TME_SPARC_FPU_BEGIN;
                    301:     fpreg_rd = *fpreg_rs2;
                    302:     break;
                    303: 
1.1.1.2 ! root      304:   case 2:  /* 000000010 FMOVd: */
        !           305:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
        !           306:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !           307:     _TME_SPARC_FPU_BEGIN;
        !           308:     fpreg_rd = *fpreg_rs2;
        !           309:     break;
        !           310: 
1.1       root      311:   case 5:  /* 000000101 FNEGs: */
                    312:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    313:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    314:     _TME_SPARC_FPU_BEGIN;
                    315:     fpreg_rd = *fpreg_rs2;
                    316:     fpreg_rd.tme_float_value_ieee754_single ^= 0x80000000;
                    317:     break;
                    318: 
1.1.1.2 ! root      319:   case 6:  /* 000000110 FNEGd: */
        !           320:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !           321:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !           322:     _TME_SPARC_FPU_BEGIN;
        !           323:     fpreg_rd = *fpreg_rs2;
        !           324:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint32_hi ^= 0x80000000;
        !           325:     break;
        !           326: 
1.1       root      327:   case 9:  /* 000001001 FABSs: */
                    328:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    329:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    330:     _TME_SPARC_FPU_BEGIN;
                    331:     fpreg_rd = *fpreg_rs2;
                    332:     fpreg_rd.tme_float_value_ieee754_single &= ~0x80000000;
                    333:     break;
                    334: 
1.1.1.2 ! root      335:   case 10:  /* 000001010 FABSd: */
        !           336:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !           337:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !           338:     _TME_SPARC_FPU_BEGIN;
        !           339:     fpreg_rd = *fpreg_rs2;
        !           340:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint32_hi &= ~0x80000000;
        !           341:     break;
        !           342: 
1.1       root      343:   case 41:  /* 000101001 FSQRTs: */
                    344:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FSQRT);
                    345:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    346:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    347:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_sqrt,
                    348:                               fpreg_rs2, &fpreg_rd);
                    349:     break;
                    350: 
                    351:   case 42:  /* 000101010 FSQRTd: */
                    352:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FSQRT);
                    353:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    354:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    355:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_sqrt,
                    356:                               fpreg_rs2, &fpreg_rd);
                    357:     break;
                    358: 
                    359:   case 43:  /* 000101011 FSQRTq: */
                    360:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FSQRT | TME_SPARC_FPU_FLAG_NO_QUAD);
                    361:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    362:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
                    363:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_sqrt,
                    364:                               fpreg_rs2, &fpreg_rd);
                    365:     break;
                    366: 
                    367:   case 65:  /* 001000001 FADDs: */
                    368:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    369:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    370:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    371:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_add,
                    372:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    373:     break;
                    374: 
                    375:   case 66:  /* 001000010 FADDd: */
                    376:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    377:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    378:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    379:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_add,
                    380:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    381:     break;
                    382: 
                    383:   case 67:  /* 001000011 FADDq: */
                    384:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
                    385:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    386:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    387:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
                    388:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_add,
                    389:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    390:     break;
                    391: 
                    392:   case 69:  /* 001000101 FSUBs: */
                    393:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    394:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    395:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    396:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_sub,
                    397:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    398:     break;
                    399: 
                    400:   case 70:  /* 001000110 FSUBd: */
                    401:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    402:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    403:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    404:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_sub,
                    405:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    406:     break;
                    407: 
                    408:   case 71:  /* 001000111 FSUBq: */
                    409:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
                    410:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    411:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    412:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
                    413:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_sub,
                    414:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    415:     break;
                    416: 
                    417:   case 73:  /* 001001001 FMULs: */
                    418:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    419:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    420:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    421:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_mul,
                    422:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    423:     break;
                    424: 
                    425:   case 74:  /* 001001010 FMULd: */
                    426:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    427:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    428:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    429:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_mul,
                    430:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    431:     break;
                    432: 
                    433:   case 75:  /* 001001011 FMULq: */
                    434:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
                    435:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    436:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    437:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
                    438:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_mul,
                    439:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    440:     break;
                    441: 
                    442:   case 77:  /* 001001101 FDIVs: */
                    443:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    444:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    445:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    446:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_div,
                    447:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    448:     break;
                    449: 
                    450:   case 78:  /* 001001110 FDIVd: */
                    451:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    452:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    453:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    454:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_div,
                    455:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    456:     break;
                    457: 
                    458:   case 79:  /* 001001111 FDIVq: */
                    459:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
                    460:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    461:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    462:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
                    463:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_div,
                    464:                               fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    465:     break;
                    466: 
                    467:   case 105:  /* 001101001 FsMULd: */
                    468:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FMUL_WIDER);
                    469:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    470:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    471:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    472:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_single,
                    473:                               fpreg_rs1, &fpreg_rs1_buffer);
                    474:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_single,
                    475:                               fpreg_rs2, &fpreg_rs2_buffer);
1.1.1.2 ! root      476:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_mul,
1.1       root      477:                              &fpreg_rs1_buffer, &fpreg_rs2_buffer, &fpreg_rd);
                    478:     break;
                    479: 
                    480:   case 110:  /* 001101110 FdMULq: */
                    481:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FMUL_WIDER | TME_SPARC_FPU_FLAG_NO_QUAD);
                    482:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    483:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    484:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
                    485:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_double,
                    486:                               fpreg_rs1, &fpreg_rs1_buffer);
                    487:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_double,
                    488:                               fpreg_rs2, &fpreg_rs2_buffer);
                    489:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_mul,
                    490:                              &fpreg_rs1_buffer, &fpreg_rs2_buffer, &fpreg_rd);
                    491:     break;
                    492: 
1.1.1.2 ! root      493:   case 129:  /* 010000001 FsTOx: */
        !           494: #ifdef TME_HAVE_INT64_T
        !           495:     if (__tme_predict_true(TME_SPARC_VERSION(ic) >= 9)) {
        !           496:       _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
        !           497:       _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !           498:       _TME_SPARC_FPU_BEGIN;
        !           499:       fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
        !           500:       ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
        !           501:       _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_to_int64,
        !           502:                                 fpreg_rs2, &fpreg_rd.tme_float_value_ieee754_double.tme_value64_int);
        !           503:       break;
        !           504:     }
        !           505: #endif /* TME_HAVE_INT64_T */
        !           506:     _TME_SPARC_FPU_UNIMPL;
        !           507:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
        !           508:     break;
        !           509: 
        !           510:   case 130:  /* 010000010 FdTOx: */
        !           511: #ifdef TME_HAVE_INT64_T
        !           512:     if (__tme_predict_true(TME_SPARC_VERSION(ic) >= 9)) {
        !           513:       _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
        !           514:       _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !           515:       _TME_SPARC_FPU_BEGIN;
        !           516:       fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
        !           517:       ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
        !           518:       _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_to_int64,
        !           519:                                 fpreg_rs2, &fpreg_rd.tme_float_value_ieee754_double.tme_value64_int);
        !           520:       break;
        !           521:     }
        !           522: #endif /* TME_HAVE_INT64_T */
        !           523:     _TME_SPARC_FPU_UNIMPL;
        !           524:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
        !           525:     break;
        !           526: 
        !           527:   case 131:  /* 010000011 FqTOx: */
        !           528: #ifdef TME_HAVE_INT64_T
        !           529:     if (__tme_predict_true(TME_SPARC_VERSION(ic) >= 9)) {
        !           530:       _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
        !           531:       _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
        !           532:       _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !           533:       _TME_SPARC_FPU_BEGIN;
        !           534:       fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
        !           535:       ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
        !           536:       _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_to_int64,
        !           537:                                 fpreg_rs2, &fpreg_rd.tme_float_value_ieee754_double.tme_value64_int);
        !           538:       break;
        !           539:     }
        !           540: #endif /* TME_HAVE_INT64_T */
        !           541:     _TME_SPARC_FPU_UNIMPL;
        !           542:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
        !           543:     break;
        !           544: 
        !           545:   case 132:  /* 010000100 FxTOs: */
        !           546: #ifdef TME_HAVE_INT64_T
        !           547:     if (__tme_predict_true(TME_SPARC_VERSION(ic) >= 9)) {
        !           548:       _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !           549:       _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
        !           550:       _TME_SPARC_FPU_BEGIN;
        !           551:       _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_from_int64,
        !           552:                                 fpreg_rs2->tme_float_value_ieee754_double.tme_value64_int, &fpreg_rd);
        !           553:       break;
        !           554:     }
        !           555: #endif /* TME_HAVE_INT64_T */
        !           556:     _TME_SPARC_FPU_UNIMPL;
        !           557:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
        !           558:     break;
        !           559: 
        !           560:   case 136:  /* 010001000 FxTOd: */
        !           561: #ifdef TME_HAVE_INT64_T
        !           562:     if (__tme_predict_true(TME_SPARC_VERSION(ic) >= 9)) {
        !           563:       _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !           564:       _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !           565:       _TME_SPARC_FPU_BEGIN;
        !           566:       _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_int64,
        !           567:                                 fpreg_rs2->tme_float_value_ieee754_double.tme_value64_int, &fpreg_rd);
        !           568:       break;
        !           569:     }
        !           570: #endif /* TME_HAVE_INT64_T */
        !           571:     _TME_SPARC_FPU_UNIMPL;
        !           572:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
        !           573:     break;
        !           574: 
        !           575:   case 140:  /* 010001100 FxTOq: */
        !           576: #ifdef TME_HAVE_INT64_T
        !           577:     if (__tme_predict_true(TME_SPARC_VERSION(ic) >= 9)) {
        !           578:       _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
        !           579:       _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !           580:       _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
        !           581:       _TME_SPARC_FPU_BEGIN;
        !           582:       _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_int64,
        !           583:                                 fpreg_rs2->tme_float_value_ieee754_double.tme_value64_int, &fpreg_rd);
        !           584:       break;
        !           585:     }
        !           586: #endif /* TME_HAVE_INT64_T */
        !           587:     _TME_SPARC_FPU_UNIMPL;
        !           588:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
        !           589:     break;
        !           590: 
1.1       root      591:   case 196:  /* 011000100 FiTOs: */
                    592:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    593:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    594:     _TME_SPARC_FPU_BEGIN;
                    595:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_from_int32,
                    596:                               fpreg_rs2->tme_float_value_ieee754_single, &fpreg_rd);
                    597:     break;
                    598: 
                    599:   case 198:  /* 011000110 FdTOs: */
                    600:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    601:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    602:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_from_double,
                    603:                               fpreg_rs2, &fpreg_rd);
                    604:     break;
                    605: 
                    606:   case 199:  /* 011000111 FqTOs: */
                    607:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
                    608:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    609:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    610:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_from_quad,
                    611:                               fpreg_rs2, &fpreg_rd);
                    612:     break;
                    613: 
                    614:   case 200:  /* 011001000 FiTOd: */
                    615:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    616:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    617:     _TME_SPARC_FPU_BEGIN;
                    618:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_int32,
                    619:                               fpreg_rs2->tme_float_value_ieee754_single, &fpreg_rd);
                    620:     break;
                    621: 
                    622:   case 201:  /* 011001001 FsTOd: */
                    623:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    624:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    625:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_single,
                    626:                               fpreg_rs2, &fpreg_rd);
                    627:     break;
                    628: 
                    629:   case 203:  /* 011001011 FqTOd: */
                    630:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
                    631:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    632:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    633:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_quad,
                    634:                               fpreg_rs2, &fpreg_rd);
                    635:     break;
                    636: 
                    637:   case 204:  /* 011001100 FiTOq: */
                    638:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
                    639:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    640:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
                    641:     _TME_SPARC_FPU_BEGIN;
                    642:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_int32,
                    643:                               fpreg_rs2->tme_float_value_ieee754_single, &fpreg_rd);
                    644:     break;
                    645: 
                    646:   case 205:  /* 011001101 FsTOq: */
                    647:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
                    648:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    649:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
                    650:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_single,
                    651:                               fpreg_rs2, &fpreg_rd);
                    652:     break;
                    653: 
                    654:   case 206:  /* 011001110 FdTOq: */
                    655:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    656:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
                    657:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_double,
                    658:                               fpreg_rs2, &fpreg_rd);
                    659:     break;
                    660: 
                    661:   case 209:  /* 011010001 FsTOi: */
                    662:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    663:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    664:     _TME_SPARC_FPU_BEGIN;
                    665:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    666:     ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
                    667:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_to_int32,
                    668:                               fpreg_rs2, (tme_int32_t *) &fpreg_rd.tme_float_value_ieee754_single);
                    669:     break;
                    670: 
                    671:   case 210:  /* 011010010 FdTOi: */
                    672:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    673:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    674:     _TME_SPARC_FPU_BEGIN;
                    675:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    676:     ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
                    677:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_to_int32,
                    678:                               fpreg_rs2, (tme_int32_t *) &fpreg_rd.tme_float_value_ieee754_single);
                    679:     break;
                    680: 
                    681:   case 211:  /* 011010011 FqTOi: */
                    682:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
                    683:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    684:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    685:     _TME_SPARC_FPU_BEGIN;
                    686:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    687:     ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
                    688:     _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_to_int32,
                    689:                               fpreg_rs2, (tme_int32_t *) &fpreg_rd.tme_float_value_ieee754_single);
                    690:     break;
                    691: 
1.1.1.2 ! root      692:   default:
        !           693:     _TME_SPARC_FPU_UNIMPL;
        !           694:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
        !           695:     break;
1.1       root      696: 
                    697: #undef _TME_SPARC_FPU_FORMAT_RS1
                    698: #undef _TME_SPARC_FPU_FORMAT_RS2
                    699: #undef _TME_SPARC_FPU_FORMAT_RD
                    700:   }
                    701: 
                    702:   /* store any destination: */
                    703:   if (fpreg_rd_format != TME_IEEE754_FPREG_FORMAT_NULL) {
                    704:     tme_sparc_fpu_fpreg_format(ic, fpreg_rd_number, fpreg_rd_format);
                    705:     ic->tme_sparc_fpu_fpregs[fpreg_rd_number] = fpreg_rd;
1.1.1.2 ! root      706:     TME_SPARC_FPU_DIRTY(ic, fpreg_rd_number);
1.1       root      707:   }
                    708: 
                    709: }
                    710: 
                    711: void
                    712: tme_sparc_fpu_fpop2(struct tme_sparc *ic)
                    713: {
                    714:   tme_uint8_t rounding_mode;
                    715:   unsigned int opf;
1.1.1.2 ! root      716:   unsigned int fpreg_rd_number_encoded;
1.1       root      717:   unsigned int fpreg_rd_number;
                    718:   const struct tme_float *fpreg_rs1;
                    719:   const struct tme_float *fpreg_rs2;
1.1.1.2 ! root      720:   unsigned int cc;
        !           721:   tme_uint32_t conds_mask;
        !           722:   unsigned int cc_i;
        !           723:   tme_uint32_t cond;
1.1       root      724:   struct tme_float fpreg_rd;
                    725:   unsigned int fpreg_rd_format;
                    726: 
                    727:   /* set the rounding mode: */
                    728:   switch (ic->tme_sparc_fpu_fsr & TME_SPARC_FSR_RND) {
                    729:   default: assert(FALSE);
                    730:   case TME_SPARC_FSR_RND_RN: rounding_mode = TME_FLOAT_ROUND_NEAREST_EVEN; break;
                    731:   case TME_SPARC_FSR_RND_RZ: rounding_mode = TME_FLOAT_ROUND_TO_ZERO; break;
                    732:   case TME_SPARC_FSR_RND_RM: rounding_mode = TME_FLOAT_ROUND_DOWN; break;
                    733:   case TME_SPARC_FSR_RND_RP: rounding_mode = TME_FLOAT_ROUND_UP; break;
                    734:   }
                    735:   ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = rounding_mode;
                    736: 
                    737:   /* decode the rd and opf fields: */
1.1.1.2 ! root      738:   fpreg_rd_number_encoded = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
1.1       root      739:   opf = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x1ff << 5));
                    740: 
1.1.1.2 ! root      741:   /* silence uninitialized variable warnings: */
        !           742:   fpreg_rd_number = 0;
        !           743: 
        !           744: #ifdef _TME_SPARC_RECODE_VERIFY
        !           745:   /* clear the rd buffer: */
        !           746:   memset(&fpreg_rd, 0, sizeof(fpreg_rd));
        !           747: #endif /* _TME_SPARC_RECODE_VERIFY */
        !           748: 
        !           749:   /* if this is an FMOVcc: */
        !           750:   if (((opf - 1) & 0x3f) < 3) {
        !           751: 
        !           752:     /* if opf bit eight is set, this uses integer condition codes: */
        !           753:     if (opf & TME_BIT(8)) {
        !           754: 
        !           755:       /* if opf bit six is set, this is unimplemented: */
        !           756:       if (__tme_predict_false(opf & TME_BIT(6))) {
        !           757:         _TME_SPARC_FPU_UNIMPL;
        !           758:       }
        !           759: 
        !           760:       /* get %icc or %xcc, depending on opf bit seven: */
        !           761:       cc = ic->tme_sparc64_ireg_ccr;
        !           762:       if (opf & TME_BIT(7)) {
        !           763:         cc /= (TME_SPARC64_CCR_XCC / TME_SPARC64_CCR_ICC);
        !           764:       }
        !           765:       cc = TME_FIELD_MASK_EXTRACTU(cc, TME_SPARC64_CCR_ICC);
        !           766: 
        !           767:       /* get the conditions mask: */
        !           768:       conds_mask = _tme_sparc_conds_icc[cc];
        !           769:     }
        !           770: 
        !           771:     /* otherwise, this uses floating-point condition codes: */
        !           772:     else {
        !           773: 
        !           774:       /* get the right %fcc: */
        !           775:       cc_i = TME_FIELD_MASK_EXTRACTU(opf, (0x3 << 6));
        !           776:       if (cc_i == 0) {
        !           777:         cc = TME_FIELD_MASK_EXTRACTU(ic->tme_sparc_fpu_fsr, TME_SPARC_FSR_FCC);
        !           778:       }
        !           779:       else {
        !           780:         cc = (ic->tme_sparc_fpu_xfsr >> (2 * (cc_i - 1))) & 0x3;
        !           781:       }
        !           782: 
        !           783:       /* get the conditions mask: */
        !           784:       conds_mask = _tme_sparc_conds_fcc[cc];
        !           785:     }
        !           786: 
        !           787:     /* add the not-conditions to the conditions mask: */
        !           788:     conds_mask += ((~conds_mask) << 8);
        !           789: 
        !           790:     /* get the cond field: */
        !           791:     cond = TME_BIT(TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0xf << 14)));
        !           792: 
        !           793:     /* if the condition is not true: */
        !           794:     if (!(conds_mask & cond)) {
        !           795: 
        !           796:       /* return now: */
        !           797:       /* NB that this may expose us to guests, since we do not check
        !           798:          that the floating-point register numbers are valid: */
        !           799:       return;
        !           800:     }
        !           801: 
        !           802:     /* clear bits six, seven, and eight in opf: */
        !           803:     opf &= 0x3f;
        !           804:   }
        !           805: 
1.1       root      806:   /* dispatch on the opf field: */
                    807:   switch (opf) {
                    808: #define _TME_SPARC_FPU_FORMAT_RS1(format) fpreg_rs1 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS1, (format))
                    809: #define _TME_SPARC_FPU_FORMAT_RS2(format) fpreg_rs2 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS2, (format))
1.1.1.2 ! root      810: #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)
        !           811: 
        !           812:   case 1:  /* 000000001 FMOVscc: */
        !           813:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
        !           814:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
        !           815:     _TME_SPARC_FPU_BEGIN;
        !           816:     fpreg_rd = *fpreg_rs2;
        !           817:     break;
        !           818: 
        !           819:   case 2:  /* 000000010 FMOVdcc: */
        !           820:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
        !           821:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !           822:     _TME_SPARC_FPU_BEGIN;
        !           823:     fpreg_rd = *fpreg_rs2;
        !           824:     break;
1.1       root      825: 
                    826:   case 81:  /* 001010001 FCMPs: */
                    827:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    828:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    829:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_sub,
                    830:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    831:     _tme_sparc_fpu_fcc_single(ic, &fpreg_rd, FALSE);
                    832:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                    833:     break;
                    834: 
                    835:   case 82:  /* 001010010 FCMPd: */
                    836:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    837:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    838:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_sub,
                    839:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    840:     _tme_sparc_fpu_fcc_double(ic, &fpreg_rd, FALSE);
                    841:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                    842:     break;
                    843: 
                    844:   case 83:  /* 001010011 FCMPq: */
                    845:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
                    846:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    847:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    848:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_sub,
                    849:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    850:     _tme_sparc_fpu_fcc_quad(ic, &fpreg_rd, FALSE);
                    851:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                    852:     break;
                    853: 
                    854:   case 85:  /* 001010101 FCMPEs: */
                    855:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    856:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    857:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_sub,
                    858:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    859:     _tme_sparc_fpu_fcc_single(ic, &fpreg_rd, TRUE);
                    860:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                    861:     break;
                    862: 
                    863:   case 86:  /* 001010110 FCMPEd: */
                    864:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    865:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    866:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_sub,
                    867:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    868:     _tme_sparc_fpu_fcc_double(ic, &fpreg_rd, TRUE);
                    869:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                    870:     break;
                    871: 
                    872:   case 87:  /* 001010111 FCMPEq: */
                    873:     _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
                    874:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    875:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
                    876:     _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_sub,
                    877:                              fpreg_rs1, fpreg_rs2, &fpreg_rd);
                    878:     _tme_sparc_fpu_fcc_quad(ic, &fpreg_rd, TRUE);
                    879:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                    880:     break;
                    881: 
1.1.1.2 ! root      882:   default:
        !           883:     _TME_SPARC_FPU_UNIMPL;
        !           884:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
        !           885:     break;
1.1       root      886: 
                    887: #undef _TME_SPARC_FPU_FORMAT_RS1
                    888: #undef _TME_SPARC_FPU_FORMAT_RS2
                    889: #undef _TME_SPARC_FPU_FORMAT_RD
                    890:   }
                    891: 
                    892:   /* store any destination: */
                    893:   if (fpreg_rd_format != TME_IEEE754_FPREG_FORMAT_NULL) {
                    894:     tme_sparc_fpu_fpreg_format(ic, fpreg_rd_number, fpreg_rd_format);
                    895:     ic->tme_sparc_fpu_fpregs[fpreg_rd_number] = fpreg_rd;
1.1.1.2 ! root      896:     TME_SPARC_FPU_DIRTY(ic, fpreg_rd_number);
1.1       root      897:   }
                    898: 
                    899: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.