|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.