Annotation of tme/ic/sparc/sparc-vis-auto.c, revision 1.1.1.1

1.1       root        1: /* automatically generated by sparc-vis-auto.sh, do not edit! */
                      2: _TME_RCSID("$Id: sparc-vis-auto.sh,v 1.4 2010/02/20 22:01:40 fredette Exp $");
                      3: 
                      4: /* this handles VIS instructions: */
                      5: void
                      6: tme_sparc_vis(struct tme_sparc *ic)
                      7: {
                      8:   unsigned int opf;
                      9:   unsigned int fpreg_rd_number_encoded;
                     10:   const struct tme_float *fpreg_rs1;
                     11:   const struct tme_float *fpreg_rs2;
                     12:   unsigned int fpreg_rd_format;
                     13:   unsigned int fpreg_rd_number;
                     14:   struct tme_float fpreg_rd;
                     15:   tme_uint64_t value_fpreg_rs1;
                     16:   tme_uint64_t value_fpreg_rs2;
                     17:   unsigned int compare_result;
                     18:   unsigned int reg_rd;
                     19:   unsigned int alignaddr_off;
                     20: 
                     21:   TME_SPARC_INSN_FPU;
                     22: 
                     23:   /* extract the opf field: */
                     24:   opf = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x1ff << 5));
                     25: 
                     26:   /* extract the encoded rd: */
                     27:   fpreg_rd_number_encoded = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
                     28: 
                     29: #ifdef _TME_SPARC_RECODE_VERIFY
                     30:   /* clear the rd buffer: */
                     31:   memset(&fpreg_rd, 0, sizeof(fpreg_rd));
                     32: #endif /* _TME_SPARC_RECODE_VERIFY */
                     33: 
                     34:   /* dispatch on the opf field: */
                     35:   switch (opf) {
                     36: #define _TME_SPARC_FPU_FORMAT_RS1(format) fpreg_rs1 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS1, (format))
                     37: #define _TME_SPARC_FPU_FORMAT_RS2(format) fpreg_rs2 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS2, (format))
                     38: #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)
                     39: 
                     40:   case 32:  /* 000100000 FCMPLE16: */
                     41:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                     42:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                     43:     value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
                     44:     value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
                     45:     compare_result = 0;
                     46:     if (((tme_uint16_t) value_fpreg_rs1)
                     47:         <= (tme_uint16_t) value_fpreg_rs2) {
                     48:       compare_result += (1 << (0 / 16));
                     49:     }
                     50:     value_fpreg_rs1 >>= 16;
                     51:     value_fpreg_rs2 >>= 16;
                     52:     if (((tme_uint16_t) value_fpreg_rs1)
                     53:         <= (tme_uint16_t) value_fpreg_rs2) {
                     54:       compare_result += (1 << (16 / 16));
                     55:     }
                     56:     value_fpreg_rs1 >>= 16;
                     57:     value_fpreg_rs2 >>= 16;
                     58:     if (((tme_uint16_t) value_fpreg_rs1)
                     59:         <= (tme_uint16_t) value_fpreg_rs2) {
                     60:       compare_result += (1 << (32 / 16));
                     61:     }
                     62:     value_fpreg_rs1 >>= 16;
                     63:     value_fpreg_rs2 >>= 16;
                     64:     if (((tme_uint16_t) value_fpreg_rs1)
                     65:         <= (tme_uint16_t) value_fpreg_rs2) {
                     66:       compare_result += (1 << (48 / 16));
                     67:     }
                     68:     value_fpreg_rs1 >>= 16;
                     69:     value_fpreg_rs2 >>= 16;
                     70:     reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
                     71:     TME_SPARC_REG_INDEX(ic, reg_rd);
                     72:     ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
                     73:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                     74:     fpreg_rd_number = 0;
                     75:     break;
                     76: 
                     77:   case 34:  /* 000100010 FCMPNE16: */
                     78:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                     79:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                     80:     value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
                     81:     value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
                     82:     compare_result = 0;
                     83:     if (((tme_uint16_t) value_fpreg_rs1)
                     84:         != (tme_uint16_t) value_fpreg_rs2) {
                     85:       compare_result += (1 << (0 / 16));
                     86:     }
                     87:     value_fpreg_rs1 >>= 16;
                     88:     value_fpreg_rs2 >>= 16;
                     89:     if (((tme_uint16_t) value_fpreg_rs1)
                     90:         != (tme_uint16_t) value_fpreg_rs2) {
                     91:       compare_result += (1 << (16 / 16));
                     92:     }
                     93:     value_fpreg_rs1 >>= 16;
                     94:     value_fpreg_rs2 >>= 16;
                     95:     if (((tme_uint16_t) value_fpreg_rs1)
                     96:         != (tme_uint16_t) value_fpreg_rs2) {
                     97:       compare_result += (1 << (32 / 16));
                     98:     }
                     99:     value_fpreg_rs1 >>= 16;
                    100:     value_fpreg_rs2 >>= 16;
                    101:     if (((tme_uint16_t) value_fpreg_rs1)
                    102:         != (tme_uint16_t) value_fpreg_rs2) {
                    103:       compare_result += (1 << (48 / 16));
                    104:     }
                    105:     value_fpreg_rs1 >>= 16;
                    106:     value_fpreg_rs2 >>= 16;
                    107:     reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
                    108:     TME_SPARC_REG_INDEX(ic, reg_rd);
                    109:     ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
                    110:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                    111:     fpreg_rd_number = 0;
                    112:     break;
                    113: 
                    114:   case 36:  /* 000100100 FCMPLE32: */
                    115:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    116:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    117:     value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
                    118:     value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
                    119:     compare_result = 0;
                    120:     if (((tme_uint32_t) value_fpreg_rs1)
                    121:         <= (tme_uint32_t) value_fpreg_rs2) {
                    122:       compare_result += (1 << (0 / 32));
                    123:     }
                    124:     value_fpreg_rs1 >>= 32;
                    125:     value_fpreg_rs2 >>= 32;
                    126:     if (((tme_uint32_t) value_fpreg_rs1)
                    127:         <= (tme_uint32_t) value_fpreg_rs2) {
                    128:       compare_result += (1 << (32 / 32));
                    129:     }
                    130:     value_fpreg_rs1 >>= 32;
                    131:     value_fpreg_rs2 >>= 32;
                    132:     reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
                    133:     TME_SPARC_REG_INDEX(ic, reg_rd);
                    134:     ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
                    135:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                    136:     fpreg_rd_number = 0;
                    137:     break;
                    138: 
                    139:   case 38:  /* 000100110 FCMPNE32: */
                    140:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    141:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    142:     value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
                    143:     value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
                    144:     compare_result = 0;
                    145:     if (((tme_uint32_t) value_fpreg_rs1)
                    146:         != (tme_uint32_t) value_fpreg_rs2) {
                    147:       compare_result += (1 << (0 / 32));
                    148:     }
                    149:     value_fpreg_rs1 >>= 32;
                    150:     value_fpreg_rs2 >>= 32;
                    151:     if (((tme_uint32_t) value_fpreg_rs1)
                    152:         != (tme_uint32_t) value_fpreg_rs2) {
                    153:       compare_result += (1 << (32 / 32));
                    154:     }
                    155:     value_fpreg_rs1 >>= 32;
                    156:     value_fpreg_rs2 >>= 32;
                    157:     reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
                    158:     TME_SPARC_REG_INDEX(ic, reg_rd);
                    159:     ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
                    160:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                    161:     fpreg_rd_number = 0;
                    162:     break;
                    163: 
                    164:   case 40:  /* 000101000 FCMPGT16: */
                    165:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    166:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    167:     value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
                    168:     value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
                    169:     compare_result = 0;
                    170:     if (((tme_uint16_t) value_fpreg_rs1)
                    171:         > (tme_uint16_t) value_fpreg_rs2) {
                    172:       compare_result += (1 << (0 / 16));
                    173:     }
                    174:     value_fpreg_rs1 >>= 16;
                    175:     value_fpreg_rs2 >>= 16;
                    176:     if (((tme_uint16_t) value_fpreg_rs1)
                    177:         > (tme_uint16_t) value_fpreg_rs2) {
                    178:       compare_result += (1 << (16 / 16));
                    179:     }
                    180:     value_fpreg_rs1 >>= 16;
                    181:     value_fpreg_rs2 >>= 16;
                    182:     if (((tme_uint16_t) value_fpreg_rs1)
                    183:         > (tme_uint16_t) value_fpreg_rs2) {
                    184:       compare_result += (1 << (32 / 16));
                    185:     }
                    186:     value_fpreg_rs1 >>= 16;
                    187:     value_fpreg_rs2 >>= 16;
                    188:     if (((tme_uint16_t) value_fpreg_rs1)
                    189:         > (tme_uint16_t) value_fpreg_rs2) {
                    190:       compare_result += (1 << (48 / 16));
                    191:     }
                    192:     value_fpreg_rs1 >>= 16;
                    193:     value_fpreg_rs2 >>= 16;
                    194:     reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
                    195:     TME_SPARC_REG_INDEX(ic, reg_rd);
                    196:     ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
                    197:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                    198:     fpreg_rd_number = 0;
                    199:     break;
                    200: 
                    201:   case 42:  /* 000101010 FCMPEQ16: */
                    202:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    203:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    204:     value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
                    205:     value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
                    206:     compare_result = 0;
                    207:     if (((tme_uint16_t) value_fpreg_rs1)
                    208:         == (tme_uint16_t) value_fpreg_rs2) {
                    209:       compare_result += (1 << (0 / 16));
                    210:     }
                    211:     value_fpreg_rs1 >>= 16;
                    212:     value_fpreg_rs2 >>= 16;
                    213:     if (((tme_uint16_t) value_fpreg_rs1)
                    214:         == (tme_uint16_t) value_fpreg_rs2) {
                    215:       compare_result += (1 << (16 / 16));
                    216:     }
                    217:     value_fpreg_rs1 >>= 16;
                    218:     value_fpreg_rs2 >>= 16;
                    219:     if (((tme_uint16_t) value_fpreg_rs1)
                    220:         == (tme_uint16_t) value_fpreg_rs2) {
                    221:       compare_result += (1 << (32 / 16));
                    222:     }
                    223:     value_fpreg_rs1 >>= 16;
                    224:     value_fpreg_rs2 >>= 16;
                    225:     if (((tme_uint16_t) value_fpreg_rs1)
                    226:         == (tme_uint16_t) value_fpreg_rs2) {
                    227:       compare_result += (1 << (48 / 16));
                    228:     }
                    229:     value_fpreg_rs1 >>= 16;
                    230:     value_fpreg_rs2 >>= 16;
                    231:     reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
                    232:     TME_SPARC_REG_INDEX(ic, reg_rd);
                    233:     ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
                    234:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                    235:     fpreg_rd_number = 0;
                    236:     break;
                    237: 
                    238:   case 44:  /* 000101100 FCMPGT32: */
                    239:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    240:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    241:     value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
                    242:     value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
                    243:     compare_result = 0;
                    244:     if (((tme_uint32_t) value_fpreg_rs1)
                    245:         > (tme_uint32_t) value_fpreg_rs2) {
                    246:       compare_result += (1 << (0 / 32));
                    247:     }
                    248:     value_fpreg_rs1 >>= 32;
                    249:     value_fpreg_rs2 >>= 32;
                    250:     if (((tme_uint32_t) value_fpreg_rs1)
                    251:         > (tme_uint32_t) value_fpreg_rs2) {
                    252:       compare_result += (1 << (32 / 32));
                    253:     }
                    254:     value_fpreg_rs1 >>= 32;
                    255:     value_fpreg_rs2 >>= 32;
                    256:     reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
                    257:     TME_SPARC_REG_INDEX(ic, reg_rd);
                    258:     ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
                    259:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                    260:     fpreg_rd_number = 0;
                    261:     break;
                    262: 
                    263:   case 46:  /* 000101110 FCMPEQ32: */
                    264:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    265:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    266:     value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
                    267:     value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
                    268:     compare_result = 0;
                    269:     if (((tme_uint32_t) value_fpreg_rs1)
                    270:         == (tme_uint32_t) value_fpreg_rs2) {
                    271:       compare_result += (1 << (0 / 32));
                    272:     }
                    273:     value_fpreg_rs1 >>= 32;
                    274:     value_fpreg_rs2 >>= 32;
                    275:     if (((tme_uint32_t) value_fpreg_rs1)
                    276:         == (tme_uint32_t) value_fpreg_rs2) {
                    277:       compare_result += (1 << (32 / 32));
                    278:     }
                    279:     value_fpreg_rs1 >>= 32;
                    280:     value_fpreg_rs2 >>= 32;
                    281:     reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
                    282:     TME_SPARC_REG_INDEX(ic, reg_rd);
                    283:     ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
                    284:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                    285:     fpreg_rd_number = 0;
                    286:     break;
                    287: 
                    288:   case 72:  /* 001001000 FALIGNDATA: */
                    289:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    290:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    291:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    292:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    293:     fpreg_rd.tme_float_value_ieee754_double = fpreg_rs1->tme_float_value_ieee754_double;
                    294:     alignaddr_off = TME_FIELD_MASK_EXTRACTU(ic->tme_sparc_vis_gsr, TME_SPARC_VIS_GSR_ALIGNADDR_OFF);
                    295:     if (alignaddr_off) {
                    296:       fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint
                    297:         = ((fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint
                    298:             << (8 * alignaddr_off))
                    299:            + (fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint
                    300:               >> (64 - (8 * alignaddr_off))));
                    301:     }
                    302:     break;
                    303: 
                    304:   case 96:  /* 001100000 (0000) FZERO: */
                    305:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    306:     _TME_SPARC_FPU_BEGIN;
                    307:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    308:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = 0;
                    309:     break;
                    310: 
                    311:   case 97:  /* 001100001 (0000) FZEROS: */
                    312:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    313:     _TME_SPARC_FPU_BEGIN;
                    314:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    315:     fpreg_rd.tme_float_value_ieee754_single = 0;
                    316:     break;
                    317: 
                    318:   case 98:  /* 001100010 (0001) FNOR: */
                    319:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    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.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    324:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = ~(fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint | fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
                    325:     break;
                    326: 
                    327:   case 99:  /* 001100011 (0001) FNORS: */
                    328:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    329:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    330:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    331:     _TME_SPARC_FPU_BEGIN;
                    332:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    333:     fpreg_rd.tme_float_value_ieee754_single = ~(fpreg_rs1->tme_float_value_ieee754_single | fpreg_rs2->tme_float_value_ieee754_single);
                    334:     break;
                    335: 
                    336:   case 100:  /* 001100100 (0010) FANDNOT2: */
                    337:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    338:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    339:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    340:     _TME_SPARC_FPU_BEGIN;
                    341:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    342:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint & ~fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
                    343:     break;
                    344: 
                    345:   case 101:  /* 001100101 (0010) FANDNOT2S: */
                    346:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    347:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    348:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    349:     _TME_SPARC_FPU_BEGIN;
                    350:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    351:     fpreg_rd.tme_float_value_ieee754_single = (fpreg_rs1->tme_float_value_ieee754_single & ~fpreg_rs2->tme_float_value_ieee754_single);
                    352:     break;
                    353: 
                    354:   case 102:  /* 001100110 (0011) FNOT2: */
                    355:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    356:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    357:     _TME_SPARC_FPU_BEGIN;
                    358:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    359:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = ~fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
                    360:     break;
                    361: 
                    362:   case 103:  /* 001100111 (0011) FNOT2S: */
                    363:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    364:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    365:     _TME_SPARC_FPU_BEGIN;
                    366:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    367:     fpreg_rd.tme_float_value_ieee754_single = ~fpreg_rs2->tme_float_value_ieee754_single;
                    368:     break;
                    369: 
                    370:   case 104:  /* 001101000 (0100) FANDNOT1: */
                    371:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    372:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    373:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    374:     _TME_SPARC_FPU_BEGIN;
                    375:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    376:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint & ~fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint);
                    377:     break;
                    378: 
                    379:   case 105:  /* 001101001 (0100) FANDNOT1S: */
                    380:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    381:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    382:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    383:     _TME_SPARC_FPU_BEGIN;
                    384:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    385:     fpreg_rd.tme_float_value_ieee754_single = (fpreg_rs2->tme_float_value_ieee754_single & ~fpreg_rs1->tme_float_value_ieee754_single);
                    386:     break;
                    387: 
                    388:   case 106:  /* 001101010 (0101) FNOT1: */
                    389:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    390:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    391:     _TME_SPARC_FPU_BEGIN;
                    392:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    393:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = ~fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
                    394:     break;
                    395: 
                    396:   case 107:  /* 001101011 (0101) FNOT1S: */
                    397:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    398:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    399:     _TME_SPARC_FPU_BEGIN;
                    400:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    401:     fpreg_rd.tme_float_value_ieee754_single = ~fpreg_rs1->tme_float_value_ieee754_single;
                    402:     break;
                    403: 
                    404:   case 108:  /* 001101100 (0110) FXOR: */
                    405:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    406:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    407:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    408:     _TME_SPARC_FPU_BEGIN;
                    409:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    410:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint ^ fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
                    411:     break;
                    412: 
                    413:   case 109:  /* 001101101 (0110) FXORS: */
                    414:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    415:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    416:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    417:     _TME_SPARC_FPU_BEGIN;
                    418:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    419:     fpreg_rd.tme_float_value_ieee754_single = (fpreg_rs1->tme_float_value_ieee754_single ^ fpreg_rs2->tme_float_value_ieee754_single);
                    420:     break;
                    421: 
                    422:   case 110:  /* 001101110 (0111) FNAND: */
                    423:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    424:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    425:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    426:     _TME_SPARC_FPU_BEGIN;
                    427:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    428:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = ~(fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint & fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
                    429:     break;
                    430: 
                    431:   case 111:  /* 001101111 (0111) FNANDS: */
                    432:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    433:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    434:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    435:     _TME_SPARC_FPU_BEGIN;
                    436:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    437:     fpreg_rd.tme_float_value_ieee754_single = ~(fpreg_rs1->tme_float_value_ieee754_single & fpreg_rs2->tme_float_value_ieee754_single);
                    438:     break;
                    439: 
                    440:   case 112:  /* 001110000 (1000) FAND: */
                    441:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    442:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    443:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    444:     _TME_SPARC_FPU_BEGIN;
                    445:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    446:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint & fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
                    447:     break;
                    448: 
                    449:   case 113:  /* 001110001 (1000) FANDS: */
                    450:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    451:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    452:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    453:     _TME_SPARC_FPU_BEGIN;
                    454:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    455:     fpreg_rd.tme_float_value_ieee754_single = (fpreg_rs1->tme_float_value_ieee754_single & fpreg_rs2->tme_float_value_ieee754_single);
                    456:     break;
                    457: 
                    458:   case 114:  /* 001110010 (1001) FXNOR: */
                    459:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    460:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    461:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    462:     _TME_SPARC_FPU_BEGIN;
                    463:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    464:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = ~(fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint ^ fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
                    465:     break;
                    466: 
                    467:   case 115:  /* 001110011 (1001) FXNORS: */
                    468:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    469:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    470:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    471:     _TME_SPARC_FPU_BEGIN;
                    472:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    473:     fpreg_rd.tme_float_value_ieee754_single = ~(fpreg_rs1->tme_float_value_ieee754_single ^ fpreg_rs2->tme_float_value_ieee754_single);
                    474:     break;
                    475: 
                    476:   case 116:  /* 001110100 (1010) FSRC1: */
                    477:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    478:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    479:     _TME_SPARC_FPU_BEGIN;
                    480:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    481:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
                    482:     break;
                    483: 
                    484:   case 117:  /* 001110101 (1010) FSRC1S: */
                    485:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    486:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    487:     _TME_SPARC_FPU_BEGIN;
                    488:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    489:     fpreg_rd.tme_float_value_ieee754_single = fpreg_rs1->tme_float_value_ieee754_single;
                    490:     break;
                    491: 
                    492:   case 118:  /* 001110110 (1011) FORNOT2: */
                    493:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    494:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    495:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    496:     _TME_SPARC_FPU_BEGIN;
                    497:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    498:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint | ~fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
                    499:     break;
                    500: 
                    501:   case 119:  /* 001110111 (1011) FORNOT2S: */
                    502:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    503:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    504:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    505:     _TME_SPARC_FPU_BEGIN;
                    506:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    507:     fpreg_rd.tme_float_value_ieee754_single = (fpreg_rs1->tme_float_value_ieee754_single | ~fpreg_rs2->tme_float_value_ieee754_single);
                    508:     break;
                    509: 
                    510:   case 120:  /* 001111000 (1100) FSRC2: */
                    511:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    512:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    513:     _TME_SPARC_FPU_BEGIN;
                    514:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    515:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
                    516:     break;
                    517: 
                    518:   case 121:  /* 001111001 (1100) FSRC2S: */
                    519:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    520:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    521:     _TME_SPARC_FPU_BEGIN;
                    522:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    523:     fpreg_rd.tme_float_value_ieee754_single = fpreg_rs2->tme_float_value_ieee754_single;
                    524:     break;
                    525: 
                    526:   case 122:  /* 001111010 (1101) FORNOT1: */
                    527:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    528:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    529:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    530:     _TME_SPARC_FPU_BEGIN;
                    531:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    532:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint | ~fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint);
                    533:     break;
                    534: 
                    535:   case 123:  /* 001111011 (1101) FORNOT1S: */
                    536:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    537:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    538:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    539:     _TME_SPARC_FPU_BEGIN;
                    540:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    541:     fpreg_rd.tme_float_value_ieee754_single = (fpreg_rs2->tme_float_value_ieee754_single | ~fpreg_rs1->tme_float_value_ieee754_single);
                    542:     break;
                    543: 
                    544:   case 124:  /* 001111100 (1110) FOR: */
                    545:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    546:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    547:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    548:     _TME_SPARC_FPU_BEGIN;
                    549:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    550:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint | fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
                    551:     break;
                    552: 
                    553:   case 125:  /* 001111101 (1110) FORS: */
                    554:     _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    555:     _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    556:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    557:     _TME_SPARC_FPU_BEGIN;
                    558:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    559:     fpreg_rd.tme_float_value_ieee754_single = (fpreg_rs1->tme_float_value_ieee754_single | fpreg_rs2->tme_float_value_ieee754_single);
                    560:     break;
                    561: 
                    562:   case 126:  /* 001111110 (1111) FONE: */
                    563:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    564:     _TME_SPARC_FPU_BEGIN;
                    565:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
                    566:     fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (0 - (tme_uint64_t) 1);
                    567:     break;
                    568: 
                    569:   case 127:  /* 001111111 (1111) FONES: */
                    570:     _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
                    571:     _TME_SPARC_FPU_BEGIN;
                    572:     fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
                    573:     fpreg_rd.tme_float_value_ieee754_single = (0 - (tme_uint32_t) 1);
                    574:     break;
                    575: 
                    576:   default:
                    577:     _TME_SPARC_FPU_UNIMPL;
                    578:     fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
                    579:     fpreg_rd_number = 0;
                    580:     break;
                    581: 
                    582: #undef _TME_SPARC_FPU_FORMAT_RS1
                    583: #undef _TME_SPARC_FPU_FORMAT_RS2
                    584: #undef _TME_SPARC_FPU_FORMAT_RD
                    585:   }
                    586: 
                    587:   /* store any destination: */
                    588:   if (fpreg_rd_format != TME_IEEE754_FPREG_FORMAT_NULL) {
                    589:     tme_sparc_fpu_fpreg_format(ic, fpreg_rd_number, fpreg_rd_format);
                    590:     ic->tme_sparc_fpu_fpregs[fpreg_rd_number] = fpreg_rd;
                    591:     TME_SPARC_FPU_DIRTY(ic, fpreg_rd_number);
                    592:   }
                    593: 
                    594: }
                    595: 
                    596: /* the sparc64 cycle handler for stdfa ASI_PST*: */
                    597: static void
                    598: _tme_sparc64_vis_ls_cycle_pstd(struct tme_sparc *ic, struct tme_sparc_ls *ls)
                    599: {
                    600:   unsigned int reg_rs2;
                    601:   tme_uint32_t mask_raw;
                    602:   unsigned int asi;
                    603:   tme_uint32_t mask_0_31;
                    604:   tme_uint32_t mask_32_63;
                    605:   tme_uint64_t mask;
                    606:   const struct tme_float *fpreg_rd;
                    607:   tme_uint64_t value_written;
                    608:   const struct tme_sparc_tlb *tlb;
                    609:   tme_uint64_t address;
                    610:   tme_shared tme_uint8_t *emulator_off;
                    611:   tme_shared tme_uint64_t *memory;
                    612:   tme_uint64_t value_read;
                    613:   tme_uint64_t value_cmp;
                    614: 
                    615:   /* decode rs2: */
                    616:   reg_rs2 = TME_FIELD_MASK_EXTRACTU(ic->_tme_sparc_insn, TME_SPARC_FORMAT3_MASK_RS2);
                    617:   TME_SPARC_REG_INDEX(ic, reg_rs2);
                    618: 
                    619:   /* get the raw mask: */
                    620:   mask_raw = ic->tme_sparc_ireg_uint64(reg_rs2);
                    621: 
                    622:   /* get the ASI: */
                    623:   asi
                    624:     = (TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask)
                    625:        & ~(TME_SPARC64_ASI_FLAG_SECONDARY
                    626:           | TME_SPARC64_ASI_FLAG_LITTLE));
                    627: 
                    628:   /* assume that this is ASI_PST32*: */
                    629:   mask_0_31 = 0 - (mask_raw & TME_BIT(0));
                    630:   mask_raw >>= 1;
                    631:   mask_32_63 = 0 - (mask_raw & TME_BIT(0));
                    632:   mask_raw >>= 1;
                    633: 
                    634:   /* if this is ASI_PST16*: */
                    635:   if (asi == TME_SPARC_VIS_ASI_PST16) {
                    636: 
                    637:     /* convert the ASI_PST32* mask into bits 0..31 of the ASI_PST16* mask: */
                    638:     mask_0_31
                    639:       = ((mask_0_31 & (((tme_uint32_t) 0xffff) << 0))
                    640:         + (mask_32_63 & (((tme_uint32_t) 0xffff) << 16)));
                    641: 
                    642:     /* make bits 32..63 of the ASI_PST16* mask: */
                    643:     mask_32_63
                    644:       = (((0 - (mask_raw & TME_BIT(0))) & (((tme_uint32_t) 0xffff) << 0))
                    645:         + ((0 - (mask_raw & TME_BIT(1))) & (((tme_uint32_t) 0xffff) << 16)));
                    646:   }
                    647: 
                    648:   /* otherwise, if this is ASI_PST8*: */
                    649:   else if (asi == TME_SPARC_VIS_ASI_PST8) {
                    650: 
                    651:     /* convert the ASI_PST32* mask into bits 0..15 of the ASI_PST8*
                    652:        mask, and make bits 16..31: */
                    653:     mask_0_31
                    654:       = ((mask_0_31 & (((tme_uint32_t) 0xff) << 0))
                    655:         + (mask_32_63 & (((tme_uint32_t) 0xff) << 8))
                    656:         + ((0 - (mask_raw & TME_BIT(0))) & (((tme_uint32_t) 0xff) << 16))
                    657:         + ((0 - (mask_raw & TME_BIT(1))) & (((tme_uint32_t) 0xff) << 24)));
                    658: 
                    659:     /* make bits 32..63 of the ASI_PST8* mask: */
                    660:     mask_raw >>= 2;
                    661:     mask_32_63
                    662:       = (((0 - (mask_raw & TME_BIT(0))) & (((tme_uint32_t) 0xff) << 0))
                    663:         + ((0 - (mask_raw & TME_BIT(1))) & (((tme_uint32_t) 0xff) << 8))
                    664:         + ((0 - (mask_raw & TME_BIT(2))) & (((tme_uint32_t) 0xff) << 16))
                    665:         + ((0 - (mask_raw & TME_BIT(3))) & (((tme_uint32_t) 0xff) << 24)));
                    666:   }
                    667: 
                    668:   /* make the full mask: */
                    669:   mask = 0;
                    670:   mask |= (((tme_uint64_t) mask_32_63) << 32);
                    671:   mask |= mask_0_31;
                    672: 
                    673:   /* get the value to store from the double-precision fp register: */
                    674:   fpreg_rd = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RD, TME_IEEE754_FPREG_FORMAT_DOUBLE);
                    675:   value_written = fpreg_rd->tme_float_value_ieee754_double.tme_value64_uint;
                    676: 
                    677:   /* get the TLB entry: */
                    678:   tlb = ls->tme_sparc_ls_tlb;
                    679: 
                    680:   /* swap the mask and the value to store: */
                    681:   if (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_ENDIAN_LITTLE) {
                    682:     value_written = tme_htole_u64(value_written);
                    683:     mask = tme_htole_u64(mask);
                    684:   }
                    685:   else {
                    686:     value_written = tme_htobe_u64(value_written);
                    687:     mask = tme_htobe_u64(mask);
                    688:   }
                    689: 
                    690:   /* get the current address: */
                    691:   address = ls->tme_sparc_ls_address64;
                    692: 
                    693:   /* if this is the first transfer, and the TLB entry allows fast
                    694:      transfer of all of the addresses: */
                    695:   emulator_off = tlb->tme_sparc_tlb_emulator_off_write;
                    696:   if (__tme_predict_true(ls->tme_sparc_ls_state == 0
                    697:                         && ((tme_bus_addr64_t) tlb->tme_sparc_tlb_addr_last) >= (address + sizeof(tme_uint64_t) - 1)
                    698:                         && emulator_off != TME_EMULATOR_OFF_UNDEF
                    699:                         && emulator_off == tlb->tme_sparc_tlb_emulator_off_read)) {
                    700: 
                    701:     /* make the pointer to the memory to store: */
                    702:     memory = (tme_shared tme_uint64_t *) (emulator_off + address);
                    703: 
                    704:     /* loop until we can do the atomic partial store: */
                    705:     value_read = tme_memory_bus_read64(memory,
                    706:                                       tlb->tme_sparc_tlb_bus_rwlock,
                    707:                                       sizeof(tme_uint64_t),
                    708:                                       sizeof(tme_uint64_t));
                    709:     do {
                    710: 
                    711:       /* make the value to write: */
                    712:       value_written
                    713:        = ((value_written & mask)
                    714:           + (value_read & ~mask));
                    715: 
                    716:       /* try an atomic compare-and-exchange: */
                    717:       value_cmp = value_read;
                    718:       value_read
                    719:        = tme_memory_atomic_cx64(memory,
                    720:                                 value_cmp,
                    721:                                 value_written,
                    722:                                 tlb->tme_sparc_tlb_bus_rwlock,
                    723:                                 sizeof(tme_uint64_t));
                    724: 
                    725:       /* loop while the atomic compare-and-exchange failed: */
                    726:     } while (value_read != value_cmp);
                    727: 
                    728:     /* we finished this transfer: */
                    729:     ls->tme_sparc_ls_size = 0;
                    730:     return;
                    731:   }
                    732: 
                    733:   /* otherwise, we have to do a slow transfer: */
                    734:   ls->tme_sparc_ls_buffer_offset = 0;
                    735:   /* XXX WRITEME: */
                    736:   abort();
                    737: }
                    738: 
                    739: /* the sparc64 ASI handler for ASI_PST*: */
                    740: void
                    741: tme_sparc64_vis_ls_asi_pst(struct tme_sparc *ic, struct tme_sparc_ls *ls)
                    742: {
                    743:   tme_uint32_t insn;
                    744:   unsigned int reg_rs1;
                    745:   tme_uint64_t address_first;
                    746: 
                    747:   /* NB: this checks for various traps in priority order: */
                    748: 
                    749:   /* the only faults that may have been set so far are an alignment
                    750:      fault, which is probably wrong because the address checked was
                    751:      (rs1 + rs2), instead of just rs1, and any ldd/std rd-odd fault.
                    752:      we will override both faults: */
                    753:   assert ((ls->tme_sparc_ls_faults
                    754:           | TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED
                    755:           | TME_SPARC_LS_FAULT_LDD_STD_RD_ODD)
                    756:          == (TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED
                    757:              | TME_SPARC_LS_FAULT_LDD_STD_RD_ODD));
                    758: 
                    759:   /* we need to do the complete transfer: */
                    760:   ls->tme_sparc_ls_faults = TME_SPARC_LS_FAULT_NONE;
                    761:   ls->tme_sparc_ls_lsinfo |= TME_SPARC_LSINFO_SLOW_CYCLES;
                    762:   ls->tme_sparc_ls_state = 0;
                    763: 
                    764:   /* get the instruction: */
                    765:   insn = ic->_tme_sparc_insn;
                    766: 
                    767:   /* NB: the exception for a non-stdfa opcode appears to be explicitly
                    768:      prioritized above an illegal_instruction trap for an immediate
                    769:      instruction: */
                    770: 
                    771:   /* if this is an stdfa: */
                    772:   if (__tme_predict_true((insn
                    773:                          & (0x3f << 19))
                    774:                         == (0x37 << 19))) {
                    775: 
                    776:     /* set the slow cycle function: */
                    777:     assert (ls->tme_sparc_ls_size == sizeof(tme_uint64_t));
                    778:     ls->tme_sparc_ls_cycle = _tme_sparc64_vis_ls_cycle_pstd;
                    779:   }
                    780: 
                    781:   /* any other instruction is illegal: */
                    782:   else {
                    783:     ls->tme_sparc_ls_faults = ic->tme_sparc_vis_ls_fault_illegal;
                    784:     return;
                    785:   }
                    786: 
                    787:   /* immediate instruction forms are illegal: */
                    788:   if (__tme_predict_false(insn & TME_BIT(13))) {
                    789:     tme_sparc_tlb_unbusy(ls->tme_sparc_ls_tlb);
                    790:     TME_SPARC_INSN_ILL(ic);
                    791:   }
                    792: 
                    793:   /* the stdfa instruction handler must have already checked that the
                    794:      FPU is enabled: */
                    795:   assert (!TME_SPARC_FPU_IS_DISABLED(ic));
                    796: 
                    797:   /* decode rs1: */
                    798:   reg_rs1 = TME_FIELD_MASK_EXTRACTU(insn, TME_SPARC_FORMAT3_MASK_RS1);
                    799:   TME_SPARC_REG_INDEX(ic, reg_rs1);
                    800: 
                    801:   /* get the address: */
                    802:   address_first = ic->tme_sparc_ireg_uint64(reg_rs1);
                    803:   ls->tme_sparc_ls_address64 = address_first;
                    804: 
                    805:   /* the address must be aligned: */
                    806:   if (__tme_predict_false((((tme_uint32_t) address_first)
                    807:                           & (ls->tme_sparc_ls_size - 1)) != 0)) {
                    808:     ls->tme_sparc_ls_faults = TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED;
                    809:     return;
                    810:   }
                    811: 
                    812:   /* the stdfa instruction handler must have already checked that the
                    813:      FPU mode is not exception_pending: */
                    814:   assert (ic->tme_sparc_fpu_mode != TME_SPARC_FPU_MODE_EXCEPTION_PENDING);
                    815: }
                    816: 
                    817: /* the sparc64 cycle handler for lddfa and stdfa ASI_FL*: */
                    818: static void
                    819: _tme_sparc64_vis_ls_cycle_fld(struct tme_sparc *ic, struct tme_sparc_ls *ls)
                    820: {
                    821:   tme_uint64_t value;
                    822:   unsigned int buffer_offset;
                    823: 
                    824:   /* if this is an stdfa: */
                    825:   if (ic->_tme_sparc_insn & (4 << 19)) {
                    826: 
                    827:     /* the actual store cycles will be done directly: */
                    828:     ls->tme_sparc_ls_cycle = tme_sparc64_store;
                    829: 
                    830:     /* initialize the memory buffer with the value to store: */
                    831:     value = *ls->tme_sparc_ls_rd64;
                    832:   }
                    833: 
                    834:   /* otherwise, this is an lddfa: */
                    835:   else {
                    836: 
                    837:     /* the actual load cycles will be done directly: */
                    838:     ls->tme_sparc_ls_cycle = tme_sparc64_load;
                    839: 
                    840:     /* initialize the memory buffer with zero: */
                    841:     value = 0;
                    842:   }
                    843: 
                    844:   /* initialize the memory buffer: */
                    845:   if (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_ENDIAN_LITTLE) {
                    846:     value = tme_htole_u64(value);
                    847:     buffer_offset = 0;
                    848:   }
                    849:   else {
                    850:     value = tme_htobe_u64(value);
                    851:     buffer_offset = sizeof(value) - ls->tme_sparc_ls_size;
                    852:   }
                    853:   ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer64s[0] = value;
                    854:   ls->tme_sparc_ls_buffer_offset = buffer_offset;
                    855: 
                    856:   /* do the (first) actual cycle: */
                    857:   (*ls->tme_sparc_ls_cycle)(ic, ls);
                    858: }
                    859: 
                    860: /* the sparc64 ASI handler for ASI_FL*: */
                    861: void
                    862: tme_sparc64_vis_ls_asi_fl(struct tme_sparc *ic, struct tme_sparc_ls *ls)
                    863: {
                    864:   tme_uint32_t insn;
                    865: 
                    866:   /* NB: this checks for various traps in priority order: */
                    867: 
                    868:   /* the only faults that may have been set so far are an alignment
                    869:      fault, which is probably wrong because the size used for the
                    870:      alignment check was wrong, and any ldd/std rd-odd fault.  we will
                    871:      override both faults: */
                    872:   assert ((ls->tme_sparc_ls_faults
                    873:           | TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED
                    874:           | TME_SPARC_LS_FAULT_LDD_STD_RD_ODD)
                    875:          == (TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED
                    876:              | TME_SPARC_LS_FAULT_LDD_STD_RD_ODD));
                    877: 
                    878:   /* get the instruction: */
                    879:   insn = ic->_tme_sparc_insn;
                    880: 
                    881:   /* we need to do the complete transfer: */
                    882:   ls->tme_sparc_ls_faults = TME_SPARC_LS_FAULT_NONE;
                    883:   ls->tme_sparc_ls_lsinfo |= TME_SPARC_LSINFO_SLOW_CYCLES;
                    884:   ls->tme_sparc_ls_state = 0;
                    885: 
                    886:   /* set the cycle size: */
                    887: #if (TME_SPARC_VIS_ASI_FL16 & (TME_SPARC_VIS_ASI_FL16 - 1)) != TME_SPARC_VIS_ASI_FL8
                    888: #error "TME_SPARC_VIS_ASI_FL values changed"
                    889: #endif
                    890:   ls->tme_sparc_ls_size
                    891:     = (sizeof(tme_uint8_t)
                    892:        + ((TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask)
                    893:           / (TME_SPARC_VIS_ASI_FL16
                    894:              ^ TME_SPARC_VIS_ASI_FL8))
                    895:          & 1));
                    896: 
                    897:   /* if this is an stdfa or an lddfa: */
                    898:   if (__tme_predict_true((insn
                    899:                          & (0x3b << 19))
                    900:                         == (0x33 << 19))) {
                    901: 
                    902:     /* set the slow cycle function: */
                    903:     ls->tme_sparc_ls_cycle = _tme_sparc64_vis_ls_cycle_fld;
                    904: 
                    905:     /* the stdfa or lddfa instruction handler must have already
                    906:        checked that the FPU is enabled: */
                    907:     assert (!TME_SPARC_FPU_IS_DISABLED(ic));
                    908:   }
                    909: 
                    910:   /* any other instruction is illegal: */
                    911:   /* XXX FIXME - is this correct?  the UltraSPARC User's Manual
                    912:      doesn't document data_access_exception for an illegal opcode: */
                    913:   else {
                    914:     ls->tme_sparc_ls_faults = ic->tme_sparc_vis_ls_fault_illegal;
                    915:     return;
                    916:   }
                    917: 
                    918:   /* the address must be aligned: */
                    919:   if (__tme_predict_false((((tme_uint32_t) ls->tme_sparc_ls_address64)
                    920:                           & (ls->tme_sparc_ls_size - 1)) != 0)) {
                    921:     ls->tme_sparc_ls_faults = TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED;
                    922:     return;
                    923:   }
                    924: 
                    925:   /* the stdfa or lddfa instruction handler must have already checked
                    926:      that the FPU mode is execute: */
                    927:   assert (ic->tme_sparc_fpu_mode == TME_SPARC_FPU_MODE_EXECUTE);
                    928: }
                    929: 
                    930: /* the sparc64 VIS alternate ASI misalignment function: */
                    931: tme_uint32_t
                    932: tme_sparc64_vis_ls_asi_misaligned(struct tme_sparc *ic,
                    933:                                   tme_uint32_t misaligned)
                    934: {
                    935:   tme_uint32_t insn;
                    936:   tme_uint32_t asi;
                    937:   tme_uint32_t asi_base;
                    938:   unsigned int reg_rs1;
                    939: 
                    940:   /* get the instruction: */
                    941:   insn = TME_SPARC_INSN;
                    942: 
                    943:   /* get the ASI, assuming that the i bit is zero: */
                    944:   asi = TME_FIELD_MASK_EXTRACTU(insn, (0xff << 5));
                    945: 
                    946:   /* if the i bit is one, use the ASI register: */
                    947:   if (insn & TME_BIT(13)) {
                    948:     asi = ic->tme_sparc64_ireg_asi;
                    949:   }
                    950: 
                    951:   /* make a base version of the ASI, with the secondary and
                    952:      little-endian flags cleared: */
                    953:   asi_base = (asi & ~(TME_SPARC64_ASI_FLAG_SECONDARY | TME_SPARC64_ASI_FLAG_LITTLE));
                    954: 
                    955:   /* ASI_FL8* requires 8-bit alignment: */
                    956:   if (asi_base == TME_SPARC_VIS_ASI_FL8) {
                    957:     misaligned %= sizeof(tme_uint8_t);
                    958:   }
                    959: 
                    960:   /* ASI_FL16* requires 16-bit alignment: */
                    961:   else if (asi_base == TME_SPARC_VIS_ASI_FL16) {
                    962:     misaligned %= sizeof(tme_uint16_t);
                    963:   }
                    964: 
                    965:   /* if this is an ASI_PST*: */
                    966:   else if (asi_base == TME_SPARC_VIS_ASI_PST8
                    967:           || asi_base == TME_SPARC_VIS_ASI_PST16
                    968:           || asi_base == TME_SPARC_VIS_ASI_PST32) {
                    969: 
                    970:     /* decode rs1: */
                    971:     reg_rs1 = TME_FIELD_MASK_EXTRACTU(insn, TME_SPARC_FORMAT3_MASK_RS1);
                    972:     TME_SPARC_REG_INDEX(ic, reg_rs1);
                    973: 
                    974:     /* if this is not a register mode stdfa: */
                    975:     if (__tme_predict_false((insn
                    976:                             & ((0x3f << 19)
                    977:                                + TME_BIT(13)))
                    978:                            != (0x37 << 19))) {
                    979: 
                    980:       /* start a slow load/store, which will call the ASI handler,
                    981:         which will cause the appropriate fault: */
                    982:       tme_sparc64_ls(ic,
                    983:                     ic->tme_sparc_ireg_uint64(reg_rs1),
                    984:                     (tme_uint64_t *) NULL, /* _rd */
                    985:                     (TME_SPARC_LSINFO_SIZE(1)
                    986:                      | TME_SPARC_LSINFO_ASI(asi)
                    987:                      | TME_SPARC_LSINFO_A));
                    988:       assert(FALSE);
                    989:     }
                    990: 
                    991:     /* get the least-significant 32 bits of the address: */
                    992:     misaligned = ic->tme_sparc_ireg_uint64(reg_rs1);
                    993: 
                    994:     /* ASI_PST* require 64-bit alignment, which the stdfa instruction
                    995:        handler is already checking: */
                    996:   }
                    997: 
                    998:   /* return a possibly updated misalignment: */
                    999:   return (misaligned);
                   1000: }

unix.superglobalmegacorp.com

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