|
|
1.1 ! root 1: /* automatically generated by sparc-insns-auto.sh, do not edit! */ ! 2: _TME_RCSID("$Id: sparc-insns-auto.sh,v 1.5 2007/03/29 01:16:09 fredette Exp $"); ! 3: ! 4: #include "sparc-impl.h" ! 5: ! 6: #undef TME_SPARC_VERSION ! 7: #define TME_SPARC_VERSION(ic) (8) ! 8: static tme_uint32_t ! 9: _tme_sparc32_alternate_asi_mask(struct tme_sparc *ic) ! 10: { ! 11: unsigned int asi_data; ! 12: tme_uint32_t asi_mask_data; ! 13: ! 14: /* get the ASI, assuming that the i bit is zero: */ ! 15: asi_data = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0xff << 5)); ! 16: ! 17: /* this is a privileged instruction: */ ! 18: TME_SPARC_INSN_PRIV; ! 19: ! 20: /* if the i bit is one, this is an illegal instruction: */ ! 21: if (__tme_predict_false(TME_SPARC_INSN & TME_BIT(13))) { ! 22: TME_SPARC_INSN_ILL; ! 23: } ! 24: ! 25: /* map the ASI into an ASI mask: */ ! 26: switch (asi_data) { ! 27: case TME_SPARC32_ASI_UI: asi_mask_data = TME_SPARC32_ASI_MASK_UI; break; ! 28: case TME_SPARC32_ASI_UD: asi_mask_data = TME_SPARC32_ASI_MASK_UD; break; ! 29: case TME_SPARC32_ASI_SI: asi_mask_data = TME_SPARC32_ASI_MASK_SI; break; ! 30: case TME_SPARC32_ASI_SD: asi_mask_data = TME_SPARC32_ASI_MASK_SD; break; ! 31: default: asi_mask_data = TME_SPARC_ASI_MASK(asi_data); break; ! 32: } ! 33: ! 34: return (asi_mask_data); ! 35: } ! 36: ! 37: /* this does a sparc32 "add SRC1, SRC2, DST": */ ! 38: TME_SPARC_FORMAT3(tme_sparc32_add, tme_uint32_t) ! 39: { ! 40: tme_uint32_t src1; ! 41: tme_uint32_t src2; ! 42: tme_uint32_t dst; ! 43: ! 44: /* get the operands: */ ! 45: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 46: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 47: ! 48: /* perform the operation: */ ! 49: dst = src1 + src2; ! 50: ! 51: /* store the destination: */ ! 52: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 53: ! 54: TME_SPARC_INSN_OK; ! 55: } ! 56: ! 57: /* this does a sparc32 "addcc SRC1, SRC2, DST": */ ! 58: TME_SPARC_FORMAT3(tme_sparc32_addcc, tme_uint32_t) ! 59: { ! 60: tme_uint32_t src1; ! 61: tme_uint32_t src2; ! 62: tme_uint32_t dst; ! 63: tme_uint32_t cc; ! 64: ! 65: /* get the operands: */ ! 66: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 67: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 68: ! 69: /* perform the operation: */ ! 70: dst = src1 + src2; ! 71: ! 72: /* store the destination: */ ! 73: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 74: ! 75: /* set Z if the destination is zero: */ ! 76: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 77: ! 78: /* set N if the destination is negative: */ ! 79: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 80: ! 81: /* if the operands are the same sign, and the destination has ! 82: a different sign, set V: */ ! 83: cc += ((((tme_int32_t) ((src2 ^ dst) & (src1 ^ (src2 ^ (((tme_uint32_t) 0) - 1))))) < 0) * TME_SPARC32_PSR_ICC_V); ! 84: ! 85: /* if src1 and src2 both have the high bit set, or if dst does ! 86: not have the high bit set and either src1 or src2 does, set C: */ ! 87: cc += (((tme_int32_t) (((tme_uint32_t) (src1 & src2)) | ((((tme_uint32_t) dst) ^ (((tme_uint32_t) 0) - 1)) & ((tme_uint32_t) (src1 | src2))))) < 0) * TME_SPARC32_PSR_ICC_C; ! 88: ! 89: /* set the condition codes: */ ! 90: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 91: ! 92: TME_SPARC_INSN_OK; ! 93: } ! 94: ! 95: /* this does a sparc32 "sub SRC1, SRC2, DST": */ ! 96: TME_SPARC_FORMAT3(tme_sparc32_sub, tme_uint32_t) ! 97: { ! 98: tme_uint32_t src1; ! 99: tme_uint32_t src2; ! 100: tme_uint32_t dst; ! 101: ! 102: /* get the operands: */ ! 103: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 104: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 105: ! 106: /* perform the operation: */ ! 107: dst = src1 - src2; ! 108: ! 109: /* store the destination: */ ! 110: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 111: ! 112: TME_SPARC_INSN_OK; ! 113: } ! 114: ! 115: /* this does a sparc32 "subcc SRC1, SRC2, DST": */ ! 116: TME_SPARC_FORMAT3(tme_sparc32_subcc, tme_uint32_t) ! 117: { ! 118: tme_uint32_t src1; ! 119: tme_uint32_t src2; ! 120: tme_uint32_t dst; ! 121: tme_uint32_t cc; ! 122: ! 123: /* get the operands: */ ! 124: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 125: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 126: ! 127: /* perform the operation: */ ! 128: dst = src1 - src2; ! 129: ! 130: /* store the destination: */ ! 131: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 132: ! 133: /* set Z if the destination is zero: */ ! 134: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 135: ! 136: /* set N if the destination is negative: */ ! 137: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 138: ! 139: /* if the operands are different signs, and the destination has ! 140: a different sign from the first operand, set V: */ ! 141: cc += ((((tme_int32_t) ((src1 ^ src2) & (src1 ^ dst))) < 0) * TME_SPARC32_PSR_ICC_V); ! 142: ! 143: /* if src2 is greater than src1, set C: */ ! 144: cc += ((((tme_uint32_t) src2) > ((tme_uint32_t) src1))) * TME_SPARC32_PSR_ICC_C; ! 145: ! 146: /* set the condition codes: */ ! 147: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 148: ! 149: TME_SPARC_INSN_OK; ! 150: } ! 151: ! 152: /* this does a sparc32 "or SRC1, SRC2, DST": */ ! 153: TME_SPARC_FORMAT3(tme_sparc32_or, tme_uint32_t) ! 154: { ! 155: tme_uint32_t src1; ! 156: tme_uint32_t src2; ! 157: tme_uint32_t dst; ! 158: ! 159: /* get the operands: */ ! 160: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 161: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 162: ! 163: /* perform the operation: */ ! 164: dst = src1 | src2; ! 165: ! 166: /* store the destination: */ ! 167: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 168: ! 169: TME_SPARC_INSN_OK; ! 170: } ! 171: ! 172: /* this does a sparc32 "orcc SRC1, SRC2, DST": */ ! 173: TME_SPARC_FORMAT3(tme_sparc32_orcc, tme_uint32_t) ! 174: { ! 175: tme_uint32_t src1; ! 176: tme_uint32_t src2; ! 177: tme_uint32_t dst; ! 178: tme_uint32_t cc; ! 179: ! 180: /* get the operands: */ ! 181: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 182: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 183: ! 184: /* perform the operation: */ ! 185: dst = src1 | src2; ! 186: ! 187: /* store the destination: */ ! 188: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 189: ! 190: /* set Z if the destination is zero: */ ! 191: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 192: ! 193: /* set N if the destination is negative: */ ! 194: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 195: ! 196: /* set the condition codes: */ ! 197: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 198: ! 199: TME_SPARC_INSN_OK; ! 200: } ! 201: ! 202: /* this does a sparc32 "orn SRC1, SRC2, DST": */ ! 203: TME_SPARC_FORMAT3(tme_sparc32_orn, tme_uint32_t) ! 204: { ! 205: tme_uint32_t src1; ! 206: tme_uint32_t src2; ! 207: tme_uint32_t dst; ! 208: ! 209: /* get the operands: */ ! 210: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 211: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 212: ! 213: /* perform the operation: */ ! 214: dst = src1 | ~src2; ! 215: ! 216: /* store the destination: */ ! 217: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 218: ! 219: TME_SPARC_INSN_OK; ! 220: } ! 221: ! 222: /* this does a sparc32 "orncc SRC1, SRC2, DST": */ ! 223: TME_SPARC_FORMAT3(tme_sparc32_orncc, tme_uint32_t) ! 224: { ! 225: tme_uint32_t src1; ! 226: tme_uint32_t src2; ! 227: tme_uint32_t dst; ! 228: tme_uint32_t cc; ! 229: ! 230: /* get the operands: */ ! 231: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 232: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 233: ! 234: /* perform the operation: */ ! 235: dst = src1 | ~src2; ! 236: ! 237: /* store the destination: */ ! 238: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 239: ! 240: /* set Z if the destination is zero: */ ! 241: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 242: ! 243: /* set N if the destination is negative: */ ! 244: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 245: ! 246: /* set the condition codes: */ ! 247: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 248: ! 249: TME_SPARC_INSN_OK; ! 250: } ! 251: ! 252: /* this does a sparc32 "and SRC1, SRC2, DST": */ ! 253: TME_SPARC_FORMAT3(tme_sparc32_and, tme_uint32_t) ! 254: { ! 255: tme_uint32_t src1; ! 256: tme_uint32_t src2; ! 257: tme_uint32_t dst; ! 258: ! 259: /* get the operands: */ ! 260: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 261: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 262: ! 263: /* perform the operation: */ ! 264: dst = src1 & src2; ! 265: ! 266: /* store the destination: */ ! 267: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 268: ! 269: TME_SPARC_INSN_OK; ! 270: } ! 271: ! 272: /* this does a sparc32 "andcc SRC1, SRC2, DST": */ ! 273: TME_SPARC_FORMAT3(tme_sparc32_andcc, tme_uint32_t) ! 274: { ! 275: tme_uint32_t src1; ! 276: tme_uint32_t src2; ! 277: tme_uint32_t dst; ! 278: tme_uint32_t cc; ! 279: ! 280: /* get the operands: */ ! 281: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 282: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 283: ! 284: /* perform the operation: */ ! 285: dst = src1 & src2; ! 286: ! 287: /* store the destination: */ ! 288: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 289: ! 290: /* set Z if the destination is zero: */ ! 291: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 292: ! 293: /* set N if the destination is negative: */ ! 294: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 295: ! 296: /* set the condition codes: */ ! 297: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 298: ! 299: TME_SPARC_INSN_OK; ! 300: } ! 301: ! 302: /* this does a sparc32 "andn SRC1, SRC2, DST": */ ! 303: TME_SPARC_FORMAT3(tme_sparc32_andn, tme_uint32_t) ! 304: { ! 305: tme_uint32_t src1; ! 306: tme_uint32_t src2; ! 307: tme_uint32_t dst; ! 308: ! 309: /* get the operands: */ ! 310: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 311: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 312: ! 313: /* perform the operation: */ ! 314: dst = src1 & ~src2; ! 315: ! 316: /* store the destination: */ ! 317: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 318: ! 319: TME_SPARC_INSN_OK; ! 320: } ! 321: ! 322: /* this does a sparc32 "andncc SRC1, SRC2, DST": */ ! 323: TME_SPARC_FORMAT3(tme_sparc32_andncc, tme_uint32_t) ! 324: { ! 325: tme_uint32_t src1; ! 326: tme_uint32_t src2; ! 327: tme_uint32_t dst; ! 328: tme_uint32_t cc; ! 329: ! 330: /* get the operands: */ ! 331: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 332: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 333: ! 334: /* perform the operation: */ ! 335: dst = src1 & ~src2; ! 336: ! 337: /* store the destination: */ ! 338: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 339: ! 340: /* set Z if the destination is zero: */ ! 341: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 342: ! 343: /* set N if the destination is negative: */ ! 344: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 345: ! 346: /* set the condition codes: */ ! 347: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 348: ! 349: TME_SPARC_INSN_OK; ! 350: } ! 351: ! 352: /* this does a sparc32 "xor SRC1, SRC2, DST": */ ! 353: TME_SPARC_FORMAT3(tme_sparc32_xor, tme_uint32_t) ! 354: { ! 355: tme_uint32_t src1; ! 356: tme_uint32_t src2; ! 357: tme_uint32_t dst; ! 358: ! 359: /* get the operands: */ ! 360: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 361: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 362: ! 363: /* perform the operation: */ ! 364: dst = src1 ^ src2; ! 365: ! 366: /* store the destination: */ ! 367: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 368: ! 369: TME_SPARC_INSN_OK; ! 370: } ! 371: ! 372: /* this does a sparc32 "xorcc SRC1, SRC2, DST": */ ! 373: TME_SPARC_FORMAT3(tme_sparc32_xorcc, tme_uint32_t) ! 374: { ! 375: tme_uint32_t src1; ! 376: tme_uint32_t src2; ! 377: tme_uint32_t dst; ! 378: tme_uint32_t cc; ! 379: ! 380: /* get the operands: */ ! 381: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 382: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 383: ! 384: /* perform the operation: */ ! 385: dst = src1 ^ src2; ! 386: ! 387: /* store the destination: */ ! 388: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 389: ! 390: /* set Z if the destination is zero: */ ! 391: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 392: ! 393: /* set N if the destination is negative: */ ! 394: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 395: ! 396: /* set the condition codes: */ ! 397: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 398: ! 399: TME_SPARC_INSN_OK; ! 400: } ! 401: ! 402: /* this does a sparc32 "xnor SRC1, SRC2, DST": */ ! 403: TME_SPARC_FORMAT3(tme_sparc32_xnor, tme_uint32_t) ! 404: { ! 405: tme_uint32_t src1; ! 406: tme_uint32_t src2; ! 407: tme_uint32_t dst; ! 408: ! 409: /* get the operands: */ ! 410: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 411: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 412: ! 413: /* perform the operation: */ ! 414: dst = src1 ^ ~src2; ! 415: ! 416: /* store the destination: */ ! 417: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 418: ! 419: TME_SPARC_INSN_OK; ! 420: } ! 421: ! 422: /* this does a sparc32 "xnorcc SRC1, SRC2, DST": */ ! 423: TME_SPARC_FORMAT3(tme_sparc32_xnorcc, tme_uint32_t) ! 424: { ! 425: tme_uint32_t src1; ! 426: tme_uint32_t src2; ! 427: tme_uint32_t dst; ! 428: tme_uint32_t cc; ! 429: ! 430: /* get the operands: */ ! 431: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 432: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 433: ! 434: /* perform the operation: */ ! 435: dst = src1 ^ ~src2; ! 436: ! 437: /* store the destination: */ ! 438: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 439: ! 440: /* set Z if the destination is zero: */ ! 441: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 442: ! 443: /* set N if the destination is negative: */ ! 444: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 445: ! 446: /* set the condition codes: */ ! 447: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 448: ! 449: TME_SPARC_INSN_OK; ! 450: } ! 451: ! 452: /* this does a sparc32 "addx SRC1, SRC2, DST": */ ! 453: TME_SPARC_FORMAT3(tme_sparc32_addx, tme_uint32_t) ! 454: { ! 455: tme_uint32_t src1; ! 456: tme_uint32_t src2; ! 457: tme_uint32_t dst; ! 458: ! 459: /* get the operands: */ ! 460: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 461: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 462: ! 463: /* perform the operation: */ ! 464: dst = src1 + src2; ! 465: dst += ((ic->tme_sparc32_ireg_psr & TME_SPARC32_PSR_ICC_C) != 0); ! 466: ! 467: /* store the destination: */ ! 468: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 469: ! 470: TME_SPARC_INSN_OK; ! 471: } ! 472: ! 473: /* this does a sparc32 "addxcc SRC1, SRC2, DST": */ ! 474: TME_SPARC_FORMAT3(tme_sparc32_addxcc, tme_uint32_t) ! 475: { ! 476: tme_uint32_t src1; ! 477: tme_uint32_t src2; ! 478: tme_uint32_t dst; ! 479: tme_uint32_t cc; ! 480: ! 481: /* get the operands: */ ! 482: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 483: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 484: ! 485: /* perform the operation: */ ! 486: dst = src1 + src2; ! 487: dst += ((ic->tme_sparc32_ireg_psr & TME_SPARC32_PSR_ICC_C) != 0); ! 488: ! 489: /* store the destination: */ ! 490: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 491: ! 492: /* set Z if the destination is zero: */ ! 493: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 494: ! 495: /* set N if the destination is negative: */ ! 496: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 497: ! 498: /* if the operands are the same sign, and the destination has ! 499: a different sign, set V: */ ! 500: cc += ((((tme_int32_t) ((src2 ^ dst) & (src1 ^ (src2 ^ (((tme_uint32_t) 0) - 1))))) < 0) * TME_SPARC32_PSR_ICC_V); ! 501: ! 502: /* if src1 and src2 both have the high bit set, or if dst does ! 503: not have the high bit set and either src1 or src2 does, set C: */ ! 504: cc += (((tme_int32_t) (((tme_uint32_t) (src1 & src2)) | ((((tme_uint32_t) dst) ^ (((tme_uint32_t) 0) - 1)) & ((tme_uint32_t) (src1 | src2))))) < 0) * TME_SPARC32_PSR_ICC_C; ! 505: ! 506: /* set the condition codes: */ ! 507: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 508: ! 509: TME_SPARC_INSN_OK; ! 510: } ! 511: ! 512: /* this does a sparc32 "subx SRC1, SRC2, DST": */ ! 513: TME_SPARC_FORMAT3(tme_sparc32_subx, tme_uint32_t) ! 514: { ! 515: tme_uint32_t src1; ! 516: tme_uint32_t src2; ! 517: tme_uint32_t dst; ! 518: ! 519: /* get the operands: */ ! 520: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 521: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 522: ! 523: /* perform the operation: */ ! 524: dst = src1 - src2; ! 525: dst -= ((ic->tme_sparc32_ireg_psr & TME_SPARC32_PSR_ICC_C) != 0); ! 526: ! 527: /* store the destination: */ ! 528: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 529: ! 530: TME_SPARC_INSN_OK; ! 531: } ! 532: ! 533: /* this does a sparc32 "subxcc SRC1, SRC2, DST": */ ! 534: TME_SPARC_FORMAT3(tme_sparc32_subxcc, tme_uint32_t) ! 535: { ! 536: tme_uint32_t src1; ! 537: tme_uint32_t src2; ! 538: tme_uint32_t dst; ! 539: tme_uint32_t cc; ! 540: ! 541: /* get the operands: */ ! 542: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 543: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 544: ! 545: /* perform the operation: */ ! 546: dst = src1 - src2; ! 547: dst -= ((ic->tme_sparc32_ireg_psr & TME_SPARC32_PSR_ICC_C) != 0); ! 548: ! 549: /* store the destination: */ ! 550: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 551: ! 552: /* set Z if the destination is zero: */ ! 553: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 554: ! 555: /* set N if the destination is negative: */ ! 556: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 557: ! 558: /* if the operands are different signs, and the destination has ! 559: a different sign from the first operand, set V: */ ! 560: cc += ((((tme_int32_t) ((src1 ^ src2) & (src1 ^ dst))) < 0) * TME_SPARC32_PSR_ICC_V); ! 561: ! 562: /* if src2 is greater than src1, set C: */ ! 563: cc += ((((tme_uint32_t) src2) > ((tme_uint32_t) src1)) || (((tme_uint32_t) src2) == ((tme_uint32_t) src1) && (ic->tme_sparc32_ireg_psr & TME_SPARC32_PSR_ICC_C))) * TME_SPARC32_PSR_ICC_C; ! 564: ! 565: /* set the condition codes: */ ! 566: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 567: ! 568: TME_SPARC_INSN_OK; ! 569: } ! 570: ! 571: /* this does a sparc32 "taddcc SRC1, SRC2, DST": */ ! 572: TME_SPARC_FORMAT3(tme_sparc32_taddcc, tme_uint32_t) ! 573: { ! 574: tme_uint32_t src1; ! 575: tme_uint32_t src2; ! 576: tme_uint32_t dst; ! 577: tme_uint32_t cc; ! 578: ! 579: /* get the operands: */ ! 580: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 581: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 582: ! 583: /* perform the operation: */ ! 584: dst = src1 + src2; ! 585: ! 586: /* store the destination: */ ! 587: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 588: ! 589: /* set Z if the destination is zero: */ ! 590: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 591: ! 592: /* set N if the destination is negative: */ ! 593: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 594: ! 595: /* if the operands are the same sign, and the destination has ! 596: a different sign, set V: */ ! 597: cc += ((((tme_int32_t) ((src2 ^ dst) & (src1 ^ (src2 ^ (((tme_uint32_t) 0) - 1))))) < 0) * TME_SPARC32_PSR_ICC_V); ! 598: ! 599: /* if src1 and src2 both have the high bit set, or if dst does ! 600: not have the high bit set and either src1 or src2 does, set C: */ ! 601: cc += (((tme_int32_t) (((tme_uint32_t) (src1 & src2)) | ((((tme_uint32_t) dst) ^ (((tme_uint32_t) 0) - 1)) & ((tme_uint32_t) (src1 | src2))))) < 0) * TME_SPARC32_PSR_ICC_C; ! 602: ! 603: /* set V if bits zero or one of src1 or src2 are set: */ ! 604: cc |= ((((src1 | src2) & 3) != 0) * TME_SPARC32_PSR_ICC_V); ! 605: ! 606: /* set the condition codes: */ ! 607: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 608: ! 609: TME_SPARC_INSN_OK; ! 610: } ! 611: ! 612: /* this does a sparc32 "taddcctv SRC1, SRC2, DST": */ ! 613: TME_SPARC_FORMAT3(tme_sparc32_taddcctv, tme_uint32_t) ! 614: { ! 615: tme_uint32_t src1; ! 616: tme_uint32_t src2; ! 617: tme_uint32_t dst; ! 618: tme_uint32_t cc; ! 619: ! 620: /* get the operands: */ ! 621: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 622: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 623: ! 624: /* perform the operation: */ ! 625: dst = src1 + src2; ! 626: ! 627: /* set Z if the destination is zero: */ ! 628: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 629: ! 630: /* set N if the destination is negative: */ ! 631: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 632: ! 633: /* if the operands are the same sign, and the destination has ! 634: a different sign, set V: */ ! 635: cc += ((((tme_int32_t) ((src2 ^ dst) & (src1 ^ (src2 ^ (((tme_uint32_t) 0) - 1))))) < 0) * TME_SPARC32_PSR_ICC_V); ! 636: ! 637: /* if src1 and src2 both have the high bit set, or if dst does ! 638: not have the high bit set and either src1 or src2 does, set C: */ ! 639: cc += (((tme_int32_t) (((tme_uint32_t) (src1 & src2)) | ((((tme_uint32_t) dst) ^ (((tme_uint32_t) 0) - 1)) & ((tme_uint32_t) (src1 | src2))))) < 0) * TME_SPARC32_PSR_ICC_C; ! 640: ! 641: /* set V if bits zero or one of src1 or src2 are set: */ ! 642: cc |= ((((src1 | src2) & 3) != 0) * TME_SPARC32_PSR_ICC_V); ! 643: ! 644: /* trap on a tagged overflow: */ ! 645: if (cc & TME_SPARC32_PSR_ICC_V) { ! 646: tme_sparc32_trap(ic, TME_SPARC_TRAP_tag_overflow); ! 647: } ! 648: /* store the destination: */ ! 649: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 650: ! 651: /* set the condition codes: */ ! 652: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 653: ! 654: TME_SPARC_INSN_OK; ! 655: } ! 656: ! 657: /* this does a sparc32 "tsubcc SRC1, SRC2, DST": */ ! 658: TME_SPARC_FORMAT3(tme_sparc32_tsubcc, tme_uint32_t) ! 659: { ! 660: tme_uint32_t src1; ! 661: tme_uint32_t src2; ! 662: tme_uint32_t dst; ! 663: tme_uint32_t cc; ! 664: ! 665: /* get the operands: */ ! 666: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 667: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 668: ! 669: /* perform the operation: */ ! 670: dst = src1 - src2; ! 671: ! 672: /* store the destination: */ ! 673: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 674: ! 675: /* set Z if the destination is zero: */ ! 676: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 677: ! 678: /* set N if the destination is negative: */ ! 679: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 680: ! 681: /* if the operands are different signs, and the destination has ! 682: a different sign from the first operand, set V: */ ! 683: cc += ((((tme_int32_t) ((src1 ^ src2) & (src1 ^ dst))) < 0) * TME_SPARC32_PSR_ICC_V); ! 684: ! 685: /* if src2 is greater than src1, set C: */ ! 686: cc += ((((tme_uint32_t) src2) > ((tme_uint32_t) src1))) * TME_SPARC32_PSR_ICC_C; ! 687: ! 688: /* set V if bits zero or one of src1 or src2 are set: */ ! 689: cc |= ((((src1 | src2) & 3) != 0) * TME_SPARC32_PSR_ICC_V); ! 690: ! 691: /* set the condition codes: */ ! 692: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 693: ! 694: TME_SPARC_INSN_OK; ! 695: } ! 696: ! 697: /* this does a sparc32 "tsubcctv SRC1, SRC2, DST": */ ! 698: TME_SPARC_FORMAT3(tme_sparc32_tsubcctv, tme_uint32_t) ! 699: { ! 700: tme_uint32_t src1; ! 701: tme_uint32_t src2; ! 702: tme_uint32_t dst; ! 703: tme_uint32_t cc; ! 704: ! 705: /* get the operands: */ ! 706: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 707: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 708: ! 709: /* perform the operation: */ ! 710: dst = src1 - src2; ! 711: ! 712: /* set Z if the destination is zero: */ ! 713: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 714: ! 715: /* set N if the destination is negative: */ ! 716: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 717: ! 718: /* if the operands are different signs, and the destination has ! 719: a different sign from the first operand, set V: */ ! 720: cc += ((((tme_int32_t) ((src1 ^ src2) & (src1 ^ dst))) < 0) * TME_SPARC32_PSR_ICC_V); ! 721: ! 722: /* if src2 is greater than src1, set C: */ ! 723: cc += ((((tme_uint32_t) src2) > ((tme_uint32_t) src1))) * TME_SPARC32_PSR_ICC_C; ! 724: ! 725: /* set V if bits zero or one of src1 or src2 are set: */ ! 726: cc |= ((((src1 | src2) & 3) != 0) * TME_SPARC32_PSR_ICC_V); ! 727: ! 728: /* trap on a tagged overflow: */ ! 729: if (cc & TME_SPARC32_PSR_ICC_V) { ! 730: tme_sparc32_trap(ic, TME_SPARC_TRAP_tag_overflow); ! 731: } ! 732: /* store the destination: */ ! 733: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 734: ! 735: /* set the condition codes: */ ! 736: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 737: ! 738: TME_SPARC_INSN_OK; ! 739: } ! 740: ! 741: /* this does a sparc32 "umul SRC1, SRC2, DST": */ ! 742: TME_SPARC_FORMAT3(tme_sparc32_umul, tme_uint32_t) ! 743: { ! 744: tme_uint32_t src1; ! 745: tme_uint32_t src2; ! 746: tme_uint32_t dst; ! 747: tme_uint64_t val64; ! 748: ! 749: /* get the operands: */ ! 750: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 751: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 752: ! 753: /* perform the operation: */ ! 754: val64 = (((tme_uint64_t) src1) * src2); ! 755: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y) = (((tme_uint64_t) val64) >> 32); ! 756: dst = ((tme_uint64_t) val64); ! 757: ! 758: /* store the destination: */ ! 759: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 760: ! 761: TME_SPARC_INSN_OK; ! 762: } ! 763: ! 764: /* this does a sparc32 "umulcc SRC1, SRC2, DST": */ ! 765: TME_SPARC_FORMAT3(tme_sparc32_umulcc, tme_uint32_t) ! 766: { ! 767: tme_uint32_t src1; ! 768: tme_uint32_t src2; ! 769: tme_uint32_t dst; ! 770: tme_uint64_t val64; ! 771: tme_uint32_t cc; ! 772: ! 773: /* get the operands: */ ! 774: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 775: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 776: ! 777: /* perform the operation: */ ! 778: val64 = (((tme_uint64_t) src1) * src2); ! 779: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y) = (((tme_uint64_t) val64) >> 32); ! 780: dst = ((tme_uint64_t) val64); ! 781: ! 782: /* store the destination: */ ! 783: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 784: ! 785: /* set Z if the destination is zero: */ ! 786: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 787: ! 788: /* set N if the destination is negative: */ ! 789: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 790: ! 791: /* set the condition codes: */ ! 792: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 793: ! 794: TME_SPARC_INSN_OK; ! 795: } ! 796: ! 797: /* this does a sparc32 "smul SRC1, SRC2, DST": */ ! 798: TME_SPARC_FORMAT3(tme_sparc32_smul, tme_uint32_t) ! 799: { ! 800: tme_int32_t src1; ! 801: tme_int32_t src2; ! 802: tme_int32_t dst; ! 803: tme_int64_t val64; ! 804: ! 805: /* get the operands: */ ! 806: src1 = (tme_int32_t) TME_SPARC_FORMAT3_RS1; ! 807: src2 = (tme_int32_t) TME_SPARC_FORMAT3_RS2; ! 808: ! 809: /* perform the operation: */ ! 810: val64 = (((tme_int64_t) src1) * src2); ! 811: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y) = (((tme_uint64_t) val64) >> 32); ! 812: dst = ((tme_int64_t) val64); ! 813: ! 814: /* store the destination: */ ! 815: TME_SPARC_FORMAT3_RD = (tme_int32_t) dst; ! 816: ! 817: TME_SPARC_INSN_OK; ! 818: } ! 819: ! 820: /* this does a sparc32 "smulcc SRC1, SRC2, DST": */ ! 821: TME_SPARC_FORMAT3(tme_sparc32_smulcc, tme_uint32_t) ! 822: { ! 823: tme_int32_t src1; ! 824: tme_int32_t src2; ! 825: tme_int32_t dst; ! 826: tme_int64_t val64; ! 827: tme_uint32_t cc; ! 828: ! 829: /* get the operands: */ ! 830: src1 = (tme_int32_t) TME_SPARC_FORMAT3_RS1; ! 831: src2 = (tme_int32_t) TME_SPARC_FORMAT3_RS2; ! 832: ! 833: /* perform the operation: */ ! 834: val64 = (((tme_int64_t) src1) * src2); ! 835: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y) = (((tme_uint64_t) val64) >> 32); ! 836: dst = ((tme_int64_t) val64); ! 837: ! 838: /* store the destination: */ ! 839: TME_SPARC_FORMAT3_RD = (tme_int32_t) dst; ! 840: ! 841: /* set Z if the destination is zero: */ ! 842: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 843: ! 844: /* set N if the destination is negative: */ ! 845: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 846: ! 847: /* set the condition codes: */ ! 848: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 849: ! 850: TME_SPARC_INSN_OK; ! 851: } ! 852: ! 853: /* this does a sparc32 "udiv SRC1, SRC2, DST": */ ! 854: TME_SPARC_FORMAT3(tme_sparc32_udiv, tme_uint32_t) ! 855: { ! 856: tme_uint32_t src1; ! 857: tme_uint32_t src2; ! 858: tme_uint32_t dst; ! 859: tme_uint64_t val64; ! 860: ! 861: /* get the operands: */ ! 862: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 863: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 864: ! 865: /* perform the operation: */ ! 866: val64 = ((((tme_uint64_t) ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y)) << 32) | ((tme_uint32_t) src1)); ! 867: val64 /= src2; ! 868: /* XXX FIXME - overflow handling is missing here: */ ! 869: dst = val64; ! 870: ! 871: /* store the destination: */ ! 872: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 873: ! 874: TME_SPARC_INSN_OK; ! 875: } ! 876: ! 877: /* this does a sparc32 "udivcc SRC1, SRC2, DST": */ ! 878: TME_SPARC_FORMAT3(tme_sparc32_udivcc, tme_uint32_t) ! 879: { ! 880: tme_uint32_t src1; ! 881: tme_uint32_t src2; ! 882: tme_uint32_t dst; ! 883: tme_uint64_t val64; ! 884: tme_uint32_t cc; ! 885: ! 886: /* get the operands: */ ! 887: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 888: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 889: ! 890: /* perform the operation: */ ! 891: val64 = ((((tme_uint64_t) ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y)) << 32) | ((tme_uint32_t) src1)); ! 892: val64 /= src2; ! 893: /* XXX FIXME - overflow handling is missing here: */ ! 894: dst = val64; ! 895: ! 896: /* store the destination: */ ! 897: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 898: ! 899: /* set Z if the destination is zero: */ ! 900: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 901: ! 902: /* set N if the destination is negative: */ ! 903: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 904: ! 905: /* set the condition codes: */ ! 906: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 907: ! 908: TME_SPARC_INSN_OK; ! 909: } ! 910: ! 911: /* this does a sparc32 "sdiv SRC1, SRC2, DST": */ ! 912: TME_SPARC_FORMAT3(tme_sparc32_sdiv, tme_uint32_t) ! 913: { ! 914: tme_int32_t src1; ! 915: tme_int32_t src2; ! 916: tme_int32_t dst; ! 917: tme_int64_t val64; ! 918: ! 919: /* get the operands: */ ! 920: src1 = (tme_int32_t) TME_SPARC_FORMAT3_RS1; ! 921: src2 = (tme_int32_t) TME_SPARC_FORMAT3_RS2; ! 922: ! 923: /* perform the operation: */ ! 924: val64 = ((((tme_uint64_t) ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y)) << 32) | ((tme_uint32_t) src1)); ! 925: val64 /= src2; ! 926: /* XXX FIXME - overflow handling is missing here: */ ! 927: dst = val64; ! 928: ! 929: /* store the destination: */ ! 930: TME_SPARC_FORMAT3_RD = (tme_int32_t) dst; ! 931: ! 932: TME_SPARC_INSN_OK; ! 933: } ! 934: ! 935: /* this does a sparc32 "sdivcc SRC1, SRC2, DST": */ ! 936: TME_SPARC_FORMAT3(tme_sparc32_sdivcc, tme_uint32_t) ! 937: { ! 938: tme_int32_t src1; ! 939: tme_int32_t src2; ! 940: tme_int32_t dst; ! 941: tme_int64_t val64; ! 942: tme_uint32_t cc; ! 943: ! 944: /* get the operands: */ ! 945: src1 = (tme_int32_t) TME_SPARC_FORMAT3_RS1; ! 946: src2 = (tme_int32_t) TME_SPARC_FORMAT3_RS2; ! 947: ! 948: /* perform the operation: */ ! 949: val64 = ((((tme_uint64_t) ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y)) << 32) | ((tme_uint32_t) src1)); ! 950: val64 /= src2; ! 951: /* XXX FIXME - overflow handling is missing here: */ ! 952: dst = val64; ! 953: ! 954: /* store the destination: */ ! 955: TME_SPARC_FORMAT3_RD = (tme_int32_t) dst; ! 956: ! 957: /* set Z if the destination is zero: */ ! 958: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 959: ! 960: /* set N if the destination is negative: */ ! 961: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 962: ! 963: /* set the condition codes: */ ! 964: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 965: ! 966: TME_SPARC_INSN_OK; ! 967: } ! 968: ! 969: /* the sparc32 sll function: */ ! 970: TME_SPARC_FORMAT3(tme_sparc32_sll, tme_uint32_t) ! 971: { ! 972: tme_uint32_t dst; ! 973: unsigned int count; ! 974: ! 975: /* get the value and the shift count: */ ! 976: dst = TME_SPARC_FORMAT3_RS1; ! 977: count = TME_SPARC_FORMAT3_RS2; ! 978: ! 979: /* limit the count: */ ! 980: count %= 32; ! 981: ! 982: /* do the shift: */ ! 983: #if (SHIFTMAX_INT32_T < (32 - 1)) ! 984: #error "cannot do full shifts of a tme_int32_t" ! 985: #endif /* (SHIFTMAX_INT32_T < (32 - 1)) */ ! 986: dst <<= count; ! 987: ! 988: /* store the destination: */ ! 989: TME_SPARC_FORMAT3_RD = dst; ! 990: ! 991: TME_SPARC_INSN_OK; ! 992: } ! 993: ! 994: /* the sparc32 srl function: */ ! 995: TME_SPARC_FORMAT3(tme_sparc32_srl, tme_uint32_t) ! 996: { ! 997: tme_uint32_t dst; ! 998: unsigned int count; ! 999: ! 1000: /* get the value and the shift count: */ ! 1001: dst = TME_SPARC_FORMAT3_RS1; ! 1002: count = TME_SPARC_FORMAT3_RS2; ! 1003: ! 1004: /* limit the count: */ ! 1005: count %= 32; ! 1006: ! 1007: /* do the shift: */ ! 1008: #if (SHIFTMAX_INT32_T < (32 - 1)) ! 1009: #error "cannot do full shifts of a tme_int32_t" ! 1010: #endif /* (SHIFTMAX_INT32_T < (32 - 1)) */ ! 1011: dst >>= count; ! 1012: ! 1013: /* store the destination: */ ! 1014: TME_SPARC_FORMAT3_RD = dst; ! 1015: ! 1016: TME_SPARC_INSN_OK; ! 1017: } ! 1018: ! 1019: /* the sparc32 sra function: */ ! 1020: TME_SPARC_FORMAT3(tme_sparc32_sra, tme_uint32_t) ! 1021: { ! 1022: tme_int32_t dst; ! 1023: unsigned int count; ! 1024: ! 1025: /* get the value and the shift count: */ ! 1026: dst = TME_SPARC_FORMAT3_RS1; ! 1027: count = TME_SPARC_FORMAT3_RS2; ! 1028: ! 1029: /* limit the count: */ ! 1030: count %= 32; ! 1031: ! 1032: /* do the shift: */ ! 1033: #ifdef SHIFTSIGNED_INT32_T ! 1034: #if (SHIFTMAX_INT32_T < (32 - 1)) ! 1035: #error "cannot do full shifts of a tme_int32_t" ! 1036: #endif /* (SHIFTMAX_INT32_T < (32 - 1)) */ ! 1037: dst >>= count; ! 1038: #else /* !SHIFTSIGNED_INT32_T */ ! 1039: for (; count-- > 0; ) { ! 1040: dst = (dst & ~((tme_int32_t) 1)) / 2; ! 1041: } ! 1042: #endif /* !SHIFTSIGNED_INT32_T */ ! 1043: ! 1044: /* store the destination: */ ! 1045: TME_SPARC_FORMAT3_RD = dst; ! 1046: ! 1047: TME_SPARC_INSN_OK; ! 1048: } ! 1049: ! 1050: /* this does a sparc32 ldb: */ ! 1051: TME_SPARC_FORMAT3(tme_sparc32_ldb, tme_uint32_t) ! 1052: { ! 1053: tme_uint32_t address; ! 1054: struct tme_sparc_tlb *dtlb; ! 1055: const tme_shared tme_uint8_t *memory; ! 1056: tme_uint32_t value; ! 1057: ! 1058: /* get the address: */ ! 1059: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 1060: ! 1061: #ifdef _TME_SPARC_STATS ! 1062: /* track statistics: */ ! 1063: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 1064: #endif /* _TME_SPARC_STATS */ ! 1065: ! 1066: /* get and busy the DTLB entry: */ ! 1067: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 1068: tme_sparc_tlb_busy(dtlb); ! 1069: ! 1070: /* assume that this DTLB applies and allows fast transfers: */ ! 1071: memory = dtlb->tme_sparc_tlb_emulator_off_read; ! 1072: ! 1073: /* we must call the slow load function if: */ ! 1074: if (__tme_predict_false( ! 1075: ! 1076: /* the DTLB entry is invalid: */ ! 1077: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 1078: ! 1079: /* the DTLB entry does not cover the needed addresses: */ ! 1080: || (dtlb->tme_sparc_tlb_addr_first > address) ! 1081: || (dtlb->tme_sparc_tlb_addr_last < (address + ((8 / 8) - 1))) ! 1082: ! 1083: /* the DTLB entry does not cover the needed address space: */ ! 1084: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data)) ! 1085: ! 1086: /* the DTLB entry does not allow fast transfers: */ ! 1087: || (memory == TME_EMULATOR_OFF_UNDEF) ! 1088: ! 1089: )) { ! 1090: ! 1091: /* call the slow load function: */ ! 1092: memory = tme_sparc32_load(ic, ! 1093: address, ! 1094: ((8 / 8))); ! 1095: } ! 1096: ! 1097: /* do the fast transfer: */ ! 1098: memory += address; ! 1099: value = tme_memory_bus_read8((const tme_shared tme_uint8_t *) memory, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t)); ! 1100: ! 1101: /* unbusy the DTLB entry: */ ! 1102: tme_sparc_tlb_unbusy(dtlb); ! 1103: ! 1104: /* possibly sign-extend the loaded value: */ ! 1105: if (TME_SPARC_INSN & TME_BIT(22)) { ! 1106: value = (tme_uint32_t) (tme_int32_t) (tme_int8_t) value; ! 1107: } ! 1108: ! 1109: /* set the loaded value: */ ! 1110: TME_SPARC_FORMAT3_RD = value; ! 1111: ! 1112: /* log the value loaded: */ ! 1113: tme_sparc_verify_mem8(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint8_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ); ! 1114: tme_sparc_log(ic, 1000, TME_OK, ! 1115: (TME_SPARC_LOG_HANDLE(ic), ! 1116: _("ldb\t0x%02x:0x%08x:\t0x%08x"), ! 1117: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data), ! 1118: address, ! 1119: TME_SPARC_FORMAT3_RD)); ! 1120: ! 1121: TME_SPARC_INSN_OK; ! 1122: } ! 1123: ! 1124: /* this does a sparc32 stb: */ ! 1125: TME_SPARC_FORMAT3(tme_sparc32_stb, tme_uint32_t) ! 1126: { ! 1127: tme_uint32_t address; ! 1128: struct tme_sparc_tlb *dtlb; ! 1129: tme_shared tme_uint8_t *memory; ! 1130: tme_uint32_t value; ! 1131: ! 1132: /* get the address: */ ! 1133: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 1134: ! 1135: #ifdef _TME_SPARC_STATS ! 1136: /* track statistics: */ ! 1137: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 1138: #endif /* _TME_SPARC_STATS */ ! 1139: ! 1140: /* log the value stored: */ ! 1141: tme_sparc_verify_mem8(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint8_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE); ! 1142: tme_sparc_log(ic, 1000, TME_OK, ! 1143: (TME_SPARC_LOG_HANDLE(ic), ! 1144: _("stb\t0x%02x:0x%08x:\t0x%02x"), ! 1145: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data), ! 1146: address, ! 1147: (tme_uint8_t) TME_SPARC_FORMAT3_RD)); ! 1148: ! 1149: /* get and busy the DTLB entry: */ ! 1150: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 1151: tme_sparc_tlb_busy(dtlb); ! 1152: ! 1153: /* assume that this DTLB applies and allows fast transfers: */ ! 1154: memory = dtlb->tme_sparc_tlb_emulator_off_write; ! 1155: ! 1156: /* we must call the slow store function if: */ ! 1157: if (__tme_predict_false( ! 1158: ! 1159: /* the DTLB entry is invalid: */ ! 1160: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 1161: ! 1162: /* the DTLB entry does not cover the needed addresses: */ ! 1163: || (dtlb->tme_sparc_tlb_addr_first > address) ! 1164: || (dtlb->tme_sparc_tlb_addr_last < (address + ((8 / 8) - 1))) ! 1165: ! 1166: /* the DTLB entry does not cover the needed address space: */ ! 1167: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data)) ! 1168: ! 1169: /* the DTLB entry does not allow fast transfers: */ ! 1170: || (memory == TME_EMULATOR_OFF_UNDEF) ! 1171: ! 1172: )) { ! 1173: ! 1174: /* call the slow store function: */ ! 1175: memory = tme_sparc32_store(ic, ! 1176: address, ! 1177: &TME_SPARC_FORMAT3_RD, ! 1178: ((8 / 8))); ! 1179: ! 1180: /* if the slow store function did the transfer, return now: */ ! 1181: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) { ! 1182: tme_sparc_tlb_unbusy(dtlb); ! 1183: TME_SPARC_INSN_OK; ! 1184: } ! 1185: } ! 1186: ! 1187: /* do the fast transfer: */ ! 1188: memory += address; ! 1189: value = (TME_SPARC_FORMAT3_RD); ! 1190: tme_memory_bus_write8((tme_shared tme_uint8_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t)); ! 1191: ! 1192: /* unbusy the DTLB entry: */ ! 1193: tme_sparc_tlb_unbusy(dtlb); ! 1194: ! 1195: TME_SPARC_INSN_OK; ! 1196: } ! 1197: ! 1198: /* this does a sparc32 ldh: */ ! 1199: TME_SPARC_FORMAT3(tme_sparc32_ldh, tme_uint32_t) ! 1200: { ! 1201: tme_uint32_t address; ! 1202: struct tme_sparc_tlb *dtlb; ! 1203: const tme_shared tme_uint8_t *memory; ! 1204: tme_uint32_t value; ! 1205: ! 1206: /* get the address: */ ! 1207: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 1208: ! 1209: #ifdef _TME_SPARC_STATS ! 1210: /* track statistics: */ ! 1211: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 1212: #endif /* _TME_SPARC_STATS */ ! 1213: ! 1214: /* get and busy the DTLB entry: */ ! 1215: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 1216: tme_sparc_tlb_busy(dtlb); ! 1217: ! 1218: /* assume that this DTLB applies and allows fast transfers: */ ! 1219: memory = dtlb->tme_sparc_tlb_emulator_off_read; ! 1220: ! 1221: /* we must call the slow load function if: */ ! 1222: if (__tme_predict_false( ! 1223: ! 1224: /* the DTLB entry is invalid: */ ! 1225: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 1226: ! 1227: /* the DTLB entry does not cover the needed addresses: */ ! 1228: || (dtlb->tme_sparc_tlb_addr_first > address) ! 1229: || (dtlb->tme_sparc_tlb_addr_last < (address + ((16 / 8) - 1))) ! 1230: ! 1231: /* the DTLB entry does not cover the needed address space: */ ! 1232: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data)) ! 1233: ! 1234: /* the DTLB entry does not allow fast transfers: */ ! 1235: || (memory == TME_EMULATOR_OFF_UNDEF) ! 1236: ! 1237: /* the address is misaligned: */ ! 1238: || ((address % (16 / 8)) != 0) ! 1239: ! 1240: )) { ! 1241: ! 1242: /* call the slow load function: */ ! 1243: memory = tme_sparc32_load(ic, ! 1244: address, ! 1245: ((16 / 8))); ! 1246: } ! 1247: ! 1248: /* do the fast transfer: */ ! 1249: memory += address; ! 1250: value = tme_memory_bus_read16((const tme_shared tme_uint16_t *) memory, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint16_t), sizeof(tme_uint32_t)); ! 1251: value = tme_betoh_u16(value); ! 1252: ! 1253: /* unbusy the DTLB entry: */ ! 1254: tme_sparc_tlb_unbusy(dtlb); ! 1255: ! 1256: /* possibly sign-extend the loaded value: */ ! 1257: if (TME_SPARC_INSN & TME_BIT(22)) { ! 1258: value = (tme_uint32_t) (tme_int32_t) (tme_int16_t) value; ! 1259: } ! 1260: ! 1261: /* set the loaded value: */ ! 1262: TME_SPARC_FORMAT3_RD = value; ! 1263: ! 1264: /* log the value loaded: */ ! 1265: tme_sparc_verify_mem16(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint16_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ); ! 1266: tme_sparc_log(ic, 1000, TME_OK, ! 1267: (TME_SPARC_LOG_HANDLE(ic), ! 1268: _("ldh\t0x%02x:0x%08x:\t0x%08x"), ! 1269: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data), ! 1270: address, ! 1271: TME_SPARC_FORMAT3_RD)); ! 1272: ! 1273: TME_SPARC_INSN_OK; ! 1274: } ! 1275: ! 1276: /* this does a sparc32 sth: */ ! 1277: TME_SPARC_FORMAT3(tme_sparc32_sth, tme_uint32_t) ! 1278: { ! 1279: tme_uint32_t address; ! 1280: struct tme_sparc_tlb *dtlb; ! 1281: tme_shared tme_uint8_t *memory; ! 1282: tme_uint32_t value; ! 1283: ! 1284: /* get the address: */ ! 1285: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 1286: ! 1287: #ifdef _TME_SPARC_STATS ! 1288: /* track statistics: */ ! 1289: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 1290: #endif /* _TME_SPARC_STATS */ ! 1291: ! 1292: /* log the value stored: */ ! 1293: tme_sparc_verify_mem16(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint16_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE); ! 1294: tme_sparc_log(ic, 1000, TME_OK, ! 1295: (TME_SPARC_LOG_HANDLE(ic), ! 1296: _("sth\t0x%02x:0x%08x:\t0x%04x"), ! 1297: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data), ! 1298: address, ! 1299: (tme_uint16_t) TME_SPARC_FORMAT3_RD)); ! 1300: ! 1301: /* get and busy the DTLB entry: */ ! 1302: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 1303: tme_sparc_tlb_busy(dtlb); ! 1304: ! 1305: /* assume that this DTLB applies and allows fast transfers: */ ! 1306: memory = dtlb->tme_sparc_tlb_emulator_off_write; ! 1307: ! 1308: /* we must call the slow store function if: */ ! 1309: if (__tme_predict_false( ! 1310: ! 1311: /* the DTLB entry is invalid: */ ! 1312: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 1313: ! 1314: /* the DTLB entry does not cover the needed addresses: */ ! 1315: || (dtlb->tme_sparc_tlb_addr_first > address) ! 1316: || (dtlb->tme_sparc_tlb_addr_last < (address + ((16 / 8) - 1))) ! 1317: ! 1318: /* the DTLB entry does not cover the needed address space: */ ! 1319: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data)) ! 1320: ! 1321: /* the DTLB entry does not allow fast transfers: */ ! 1322: || (memory == TME_EMULATOR_OFF_UNDEF) ! 1323: ! 1324: /* the address is misaligned: */ ! 1325: || ((address % (16 / 8)) != 0) ! 1326: ! 1327: )) { ! 1328: ! 1329: /* call the slow store function: */ ! 1330: memory = tme_sparc32_store(ic, ! 1331: address, ! 1332: &TME_SPARC_FORMAT3_RD, ! 1333: ((16 / 8))); ! 1334: ! 1335: /* if the slow store function did the transfer, return now: */ ! 1336: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) { ! 1337: tme_sparc_tlb_unbusy(dtlb); ! 1338: TME_SPARC_INSN_OK; ! 1339: } ! 1340: } ! 1341: ! 1342: /* do the fast transfer: */ ! 1343: memory += address; ! 1344: value = tme_htobe_u16(TME_SPARC_FORMAT3_RD); ! 1345: tme_memory_bus_write16((tme_shared tme_uint16_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint16_t), sizeof(tme_uint32_t)); ! 1346: ! 1347: /* unbusy the DTLB entry: */ ! 1348: tme_sparc_tlb_unbusy(dtlb); ! 1349: ! 1350: TME_SPARC_INSN_OK; ! 1351: } ! 1352: ! 1353: /* this does a sparc32 ld: */ ! 1354: TME_SPARC_FORMAT3(tme_sparc32_ld, tme_uint32_t) ! 1355: { ! 1356: tme_uint32_t address; ! 1357: struct tme_sparc_tlb *dtlb; ! 1358: const tme_shared tme_uint8_t *memory; ! 1359: tme_uint32_t value; ! 1360: ! 1361: /* get the address: */ ! 1362: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 1363: ! 1364: #ifdef _TME_SPARC_STATS ! 1365: /* track statistics: */ ! 1366: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 1367: #endif /* _TME_SPARC_STATS */ ! 1368: ! 1369: /* get and busy the DTLB entry: */ ! 1370: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 1371: tme_sparc_tlb_busy(dtlb); ! 1372: ! 1373: /* assume that this DTLB applies and allows fast transfers: */ ! 1374: memory = dtlb->tme_sparc_tlb_emulator_off_read; ! 1375: ! 1376: /* we must call the slow load function if: */ ! 1377: if (__tme_predict_false( ! 1378: ! 1379: /* the DTLB entry is invalid: */ ! 1380: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 1381: ! 1382: /* the DTLB entry does not cover the needed addresses: */ ! 1383: || (dtlb->tme_sparc_tlb_addr_first > address) ! 1384: || (dtlb->tme_sparc_tlb_addr_last < (address + ((32 / 8) - 1))) ! 1385: ! 1386: /* the DTLB entry does not cover the needed address space: */ ! 1387: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data)) ! 1388: ! 1389: /* the DTLB entry does not allow fast transfers: */ ! 1390: || (memory == TME_EMULATOR_OFF_UNDEF) ! 1391: ! 1392: /* the address is misaligned: */ ! 1393: || ((address % (32 / 8)) != 0) ! 1394: ! 1395: )) { ! 1396: ! 1397: /* call the slow load function: */ ! 1398: memory = tme_sparc32_load(ic, ! 1399: address, ! 1400: ((32 / 8))); ! 1401: } ! 1402: ! 1403: /* do the fast transfer: */ ! 1404: memory += address; ! 1405: value = tme_memory_bus_read32((const tme_shared tme_uint32_t *) memory, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t)); ! 1406: value = tme_betoh_u32(value); ! 1407: ! 1408: /* unbusy the DTLB entry: */ ! 1409: tme_sparc_tlb_unbusy(dtlb); ! 1410: ! 1411: /* set the loaded value: */ ! 1412: TME_SPARC_FORMAT3_RD = value; ! 1413: ! 1414: /* log the value loaded: */ ! 1415: tme_sparc_verify_mem32(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ); ! 1416: tme_sparc_log(ic, 1000, TME_OK, ! 1417: (TME_SPARC_LOG_HANDLE(ic), ! 1418: _("ld\t0x%02x:0x%08x:\t0x%08x"), ! 1419: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data), ! 1420: address, ! 1421: TME_SPARC_FORMAT3_RD)); ! 1422: ! 1423: TME_SPARC_INSN_OK; ! 1424: } ! 1425: ! 1426: /* this does a sparc32 st: */ ! 1427: TME_SPARC_FORMAT3(tme_sparc32_st, tme_uint32_t) ! 1428: { ! 1429: tme_uint32_t address; ! 1430: struct tme_sparc_tlb *dtlb; ! 1431: tme_shared tme_uint8_t *memory; ! 1432: tme_uint32_t value; ! 1433: ! 1434: /* get the address: */ ! 1435: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 1436: ! 1437: #ifdef _TME_SPARC_STATS ! 1438: /* track statistics: */ ! 1439: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 1440: #endif /* _TME_SPARC_STATS */ ! 1441: ! 1442: /* log the value stored: */ ! 1443: tme_sparc_verify_mem32(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE); ! 1444: tme_sparc_log(ic, 1000, TME_OK, ! 1445: (TME_SPARC_LOG_HANDLE(ic), ! 1446: _("st\t0x%02x:0x%08x:\t0x%08x"), ! 1447: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data), ! 1448: address, ! 1449: (tme_uint32_t) TME_SPARC_FORMAT3_RD)); ! 1450: ! 1451: /* get and busy the DTLB entry: */ ! 1452: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 1453: tme_sparc_tlb_busy(dtlb); ! 1454: ! 1455: /* assume that this DTLB applies and allows fast transfers: */ ! 1456: memory = dtlb->tme_sparc_tlb_emulator_off_write; ! 1457: ! 1458: /* we must call the slow store function if: */ ! 1459: if (__tme_predict_false( ! 1460: ! 1461: /* the DTLB entry is invalid: */ ! 1462: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 1463: ! 1464: /* the DTLB entry does not cover the needed addresses: */ ! 1465: || (dtlb->tme_sparc_tlb_addr_first > address) ! 1466: || (dtlb->tme_sparc_tlb_addr_last < (address + ((32 / 8) - 1))) ! 1467: ! 1468: /* the DTLB entry does not cover the needed address space: */ ! 1469: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data)) ! 1470: ! 1471: /* the DTLB entry does not allow fast transfers: */ ! 1472: || (memory == TME_EMULATOR_OFF_UNDEF) ! 1473: ! 1474: /* the address is misaligned: */ ! 1475: || ((address % (32 / 8)) != 0) ! 1476: ! 1477: )) { ! 1478: ! 1479: /* call the slow store function: */ ! 1480: memory = tme_sparc32_store(ic, ! 1481: address, ! 1482: &TME_SPARC_FORMAT3_RD, ! 1483: ((32 / 8))); ! 1484: ! 1485: /* if the slow store function did the transfer, return now: */ ! 1486: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) { ! 1487: tme_sparc_tlb_unbusy(dtlb); ! 1488: TME_SPARC_INSN_OK; ! 1489: } ! 1490: } ! 1491: ! 1492: /* do the fast transfer: */ ! 1493: memory += address; ! 1494: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD); ! 1495: tme_memory_bus_write32((tme_shared tme_uint32_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t)); ! 1496: ! 1497: /* unbusy the DTLB entry: */ ! 1498: tme_sparc_tlb_unbusy(dtlb); ! 1499: ! 1500: TME_SPARC_INSN_OK; ! 1501: } ! 1502: ! 1503: /* this does a sparc32 ldd: */ ! 1504: TME_SPARC_FORMAT3(tme_sparc32_ldd, tme_uint32_t) ! 1505: { ! 1506: tme_uint32_t address; ! 1507: struct tme_sparc_tlb *dtlb; ! 1508: const tme_shared tme_uint8_t *memory; ! 1509: tme_uint32_t value; ! 1510: ! 1511: /* get the address: */ ! 1512: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 1513: ! 1514: #ifdef _TME_SPARC_STATS ! 1515: /* track statistics: */ ! 1516: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 1517: #endif /* _TME_SPARC_STATS */ ! 1518: ! 1519: /* get and busy the DTLB entry: */ ! 1520: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 1521: tme_sparc_tlb_busy(dtlb); ! 1522: ! 1523: /* assume that this DTLB applies and allows fast transfers: */ ! 1524: memory = dtlb->tme_sparc_tlb_emulator_off_read; ! 1525: ! 1526: /* we must call the slow load function if: */ ! 1527: if (__tme_predict_false( ! 1528: ! 1529: /* the DTLB entry is invalid: */ ! 1530: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 1531: ! 1532: /* the DTLB entry does not cover the needed addresses: */ ! 1533: || (dtlb->tme_sparc_tlb_addr_first > address) ! 1534: || (dtlb->tme_sparc_tlb_addr_last < (address + ((64 / 8) - 1))) ! 1535: ! 1536: /* the DTLB entry does not cover the needed address space: */ ! 1537: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data)) ! 1538: ! 1539: /* the DTLB entry does not allow fast transfers: */ ! 1540: || (memory == TME_EMULATOR_OFF_UNDEF) ! 1541: ! 1542: /* the address is misaligned: */ ! 1543: || ((address % (64 / 8)) != 0) ! 1544: ! 1545: /* the destination register number is odd: */ ! 1546: || ((TME_SPARC_INSN & TME_BIT(25)) != 0) ! 1547: ! 1548: )) { ! 1549: ! 1550: /* call the slow load function: */ ! 1551: memory = tme_sparc32_load(ic, ! 1552: address, ! 1553: ((64 / 8))); ! 1554: } ! 1555: ! 1556: /* do the fast transfer: */ ! 1557: memory += address; ! 1558: value = tme_memory_bus_read32(((const tme_shared tme_uint32_t *) memory) + 0, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t) * 2, sizeof(tme_uint32_t)); ! 1559: TME_SPARC_FORMAT3_RD = tme_betoh_u32(value); ! 1560: value = tme_memory_bus_read32(((const tme_shared tme_uint32_t *) memory) + 1, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t)); ! 1561: TME_SPARC_FORMAT3_RD_ODD = tme_betoh_u32(value); ! 1562: ! 1563: /* unbusy the DTLB entry: */ ! 1564: tme_sparc_tlb_unbusy(dtlb); ! 1565: ! 1566: /* log the value loaded: */ ! 1567: tme_sparc_log(ic, 1000, TME_OK, ! 1568: (TME_SPARC_LOG_HANDLE(ic), ! 1569: _("ldd\t0x%02x:0x%08x:\t0x%08x 0x%08x"), ! 1570: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data), ! 1571: address, ! 1572: (tme_uint32_t) TME_SPARC_FORMAT3_RD, ! 1573: (tme_uint32_t) TME_SPARC_FORMAT3_RD_ODD)); ! 1574: ! 1575: TME_SPARC_INSN_OK; ! 1576: } ! 1577: ! 1578: /* this does a sparc32 std: */ ! 1579: TME_SPARC_FORMAT3(tme_sparc32_std, tme_uint32_t) ! 1580: { ! 1581: tme_uint32_t address; ! 1582: struct tme_sparc_tlb *dtlb; ! 1583: tme_shared tme_uint8_t *memory; ! 1584: tme_uint32_t value; ! 1585: ! 1586: /* get the address: */ ! 1587: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 1588: ! 1589: #ifdef _TME_SPARC_STATS ! 1590: /* track statistics: */ ! 1591: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 1592: #endif /* _TME_SPARC_STATS */ ! 1593: ! 1594: /* log the values stored: */ ! 1595: tme_sparc_log(ic, 1000, TME_OK, ! 1596: (TME_SPARC_LOG_HANDLE(ic), ! 1597: _("std\t0x%02x:0x%08x:\t0x%08x 0x%08x"), ! 1598: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data), ! 1599: address, ! 1600: (tme_uint32_t) TME_SPARC_FORMAT3_RD, ! 1601: (tme_uint32_t) TME_SPARC_FORMAT3_RD_ODD)); ! 1602: ! 1603: /* get and busy the DTLB entry: */ ! 1604: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 1605: tme_sparc_tlb_busy(dtlb); ! 1606: ! 1607: /* assume that this DTLB applies and allows fast transfers: */ ! 1608: memory = dtlb->tme_sparc_tlb_emulator_off_write; ! 1609: ! 1610: /* we must call the slow store function if: */ ! 1611: if (__tme_predict_false( ! 1612: ! 1613: /* the DTLB entry is invalid: */ ! 1614: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 1615: ! 1616: /* the DTLB entry does not cover the needed addresses: */ ! 1617: || (dtlb->tme_sparc_tlb_addr_first > address) ! 1618: || (dtlb->tme_sparc_tlb_addr_last < (address + ((64 / 8) - 1))) ! 1619: ! 1620: /* the DTLB entry does not cover the needed address space: */ ! 1621: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data)) ! 1622: ! 1623: /* the DTLB entry does not allow fast transfers: */ ! 1624: || (memory == TME_EMULATOR_OFF_UNDEF) ! 1625: ! 1626: /* the address is misaligned: */ ! 1627: || ((address % (64 / 8)) != 0) ! 1628: ! 1629: /* the destination register number is odd: */ ! 1630: || ((TME_SPARC_INSN & TME_BIT(25)) != 0) ! 1631: ! 1632: )) { ! 1633: ! 1634: /* call the slow store function: */ ! 1635: memory = tme_sparc32_store(ic, ! 1636: address, ! 1637: &TME_SPARC_FORMAT3_RD, ! 1638: ((64 / 8))); ! 1639: ! 1640: /* if the slow store function did the transfer, return now: */ ! 1641: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) { ! 1642: tme_sparc_tlb_unbusy(dtlb); ! 1643: TME_SPARC_INSN_OK; ! 1644: } ! 1645: } ! 1646: ! 1647: /* do the fast transfer: */ ! 1648: memory += address; ! 1649: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD); ! 1650: tme_memory_bus_write32(((tme_shared tme_uint32_t *) memory) + 0, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t) * 2, sizeof(tme_uint32_t)); ! 1651: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD_ODD); ! 1652: tme_memory_bus_write32(((tme_shared tme_uint32_t *) memory) + 1, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t)); ! 1653: ! 1654: /* unbusy the DTLB entry: */ ! 1655: tme_sparc_tlb_unbusy(dtlb); ! 1656: ! 1657: TME_SPARC_INSN_OK; ! 1658: } ! 1659: ! 1660: /* this does a sparc32 ldstub: */ ! 1661: TME_SPARC_FORMAT3(tme_sparc32_ldstub, tme_uint32_t) ! 1662: { ! 1663: tme_uint32_t address; ! 1664: struct tme_sparc_tlb *dtlb; ! 1665: tme_shared tme_uint8_t *memory; ! 1666: tme_uint32_t value; ! 1667: ! 1668: /* get the address: */ ! 1669: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 1670: ! 1671: #ifdef _TME_SPARC_STATS ! 1672: /* track statistics: */ ! 1673: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 1674: #endif /* _TME_SPARC_STATS */ ! 1675: ! 1676: /* get and busy the DTLB entry: */ ! 1677: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 1678: tme_sparc_tlb_busy(dtlb); ! 1679: ! 1680: /* assume that this DTLB applies and allows fast transfers: */ ! 1681: memory = dtlb->tme_sparc_tlb_emulator_off_write; ! 1682: ! 1683: /* we must call the slow store function if: */ ! 1684: if (__tme_predict_false( ! 1685: ! 1686: /* the DTLB entry is invalid: */ ! 1687: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 1688: ! 1689: /* the DTLB entry does not cover the needed addresses: */ ! 1690: || (dtlb->tme_sparc_tlb_addr_first > address) ! 1691: || (dtlb->tme_sparc_tlb_addr_last < (address + ((8 / 8) - 1))) ! 1692: ! 1693: /* the DTLB entry does not cover the needed address space: */ ! 1694: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data)) ! 1695: ! 1696: /* the DTLB entry does not allow fast transfers: */ ! 1697: || (memory != dtlb->tme_sparc_tlb_emulator_off_read) ! 1698: || (memory == TME_EMULATOR_OFF_UNDEF) ! 1699: ! 1700: )) { ! 1701: ! 1702: /* call the slow store function: */ ! 1703: memory = tme_sparc32_store(ic, ! 1704: address, ! 1705: &TME_SPARC_FORMAT3_RD, ! 1706: (TME_SPARC_SLOW_FLAG_ATOMIC ! 1707: | (8 / 8))); ! 1708: ! 1709: /* if the slow store function did the transfer, return now: */ ! 1710: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) { ! 1711: tme_sparc_tlb_unbusy(dtlb); ! 1712: TME_SPARC_INSN_OK; ! 1713: } ! 1714: } ! 1715: ! 1716: /* do the fast transfer: */ ! 1717: memory += address; ! 1718: value = tme_memory_atomic_xchg8(memory, 0xff, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t)); ! 1719: ! 1720: /* unbusy the DTLB entry: */ ! 1721: tme_sparc_tlb_unbusy(dtlb); ! 1722: ! 1723: /* possibly sign-extend the loaded value: */ ! 1724: if (TME_SPARC_INSN & TME_BIT(22)) { ! 1725: value = (tme_uint32_t) (tme_int32_t) (tme_int8_t) value; ! 1726: } ! 1727: ! 1728: /* set the loaded value: */ ! 1729: TME_SPARC_FORMAT3_RD = value; ! 1730: ! 1731: /* log the value loaded: */ ! 1732: tme_sparc_verify_mem8(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint8_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ); ! 1733: tme_sparc_log(ic, 1000, TME_OK, ! 1734: (TME_SPARC_LOG_HANDLE(ic), ! 1735: _("ldstub\t0x%02x:0x%08x:\t0x%08x"), ! 1736: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data), ! 1737: address, ! 1738: TME_SPARC_FORMAT3_RD)); ! 1739: ! 1740: TME_SPARC_INSN_OK; ! 1741: } ! 1742: ! 1743: /* this does a sparc32 ldstuba: */ ! 1744: TME_SPARC_FORMAT3(tme_sparc32_ldstuba, tme_uint32_t) ! 1745: { ! 1746: tme_uint32_t asi_mask_data; ! 1747: tme_uint32_t address; ! 1748: struct tme_sparc_tlb *dtlb; ! 1749: tme_shared tme_uint8_t *memory; ! 1750: tme_uint32_t value; ! 1751: ! 1752: /* get the alternate ASI mask: */ ! 1753: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic); ! 1754: ! 1755: /* get the address: */ ! 1756: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 1757: ! 1758: #ifdef _TME_SPARC_STATS ! 1759: /* track statistics: */ ! 1760: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 1761: #endif /* _TME_SPARC_STATS */ ! 1762: ! 1763: /* get and busy the DTLB entry: */ ! 1764: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 1765: tme_sparc_tlb_busy(dtlb); ! 1766: ! 1767: /* assume that this DTLB applies and allows fast transfers: */ ! 1768: memory = dtlb->tme_sparc_tlb_emulator_off_write; ! 1769: ! 1770: /* we must call the slow store function if: */ ! 1771: if (__tme_predict_false( ! 1772: ! 1773: /* the DTLB entry is invalid: */ ! 1774: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 1775: ! 1776: /* the DTLB entry does not cover the needed addresses: */ ! 1777: || (dtlb->tme_sparc_tlb_addr_first > address) ! 1778: || (dtlb->tme_sparc_tlb_addr_last < (address + ((8 / 8) - 1))) ! 1779: ! 1780: /* the DTLB entry does not cover the needed address space: */ ! 1781: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data)) ! 1782: ! 1783: /* the DTLB entry does not allow fast transfers: */ ! 1784: || (memory != dtlb->tme_sparc_tlb_emulator_off_read) ! 1785: || (memory == TME_EMULATOR_OFF_UNDEF) ! 1786: ! 1787: )) { ! 1788: ! 1789: /* call the slow store function: */ ! 1790: memory = tme_sparc32_store(ic, ! 1791: address, ! 1792: &TME_SPARC_FORMAT3_RD, ! 1793: (TME_SPARC_SLOW_FLAG_ATOMIC ! 1794: | TME_SPARC_SLOW_FLAG_A ! 1795: | (8 / 8))); ! 1796: ! 1797: /* if the slow store function did the transfer, return now: */ ! 1798: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) { ! 1799: tme_sparc_tlb_unbusy(dtlb); ! 1800: TME_SPARC_INSN_OK; ! 1801: } ! 1802: } ! 1803: ! 1804: /* do the fast transfer: */ ! 1805: memory += address; ! 1806: value = tme_memory_atomic_xchg8(memory, 0xff, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t)); ! 1807: ! 1808: /* unbusy the DTLB entry: */ ! 1809: tme_sparc_tlb_unbusy(dtlb); ! 1810: ! 1811: /* possibly sign-extend the loaded value: */ ! 1812: if (TME_SPARC_INSN & TME_BIT(22)) { ! 1813: value = (tme_uint32_t) (tme_int32_t) (tme_int8_t) value; ! 1814: } ! 1815: ! 1816: /* set the loaded value: */ ! 1817: TME_SPARC_FORMAT3_RD = value; ! 1818: ! 1819: /* log the value loaded: */ ! 1820: tme_sparc_verify_mem8(ic, asi_mask_data, address, (tme_uint8_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ); ! 1821: tme_sparc_log(ic, 1000, TME_OK, ! 1822: (TME_SPARC_LOG_HANDLE(ic), ! 1823: _("ldstuba\t0x%02x:0x%08x:\t0x%08x"), ! 1824: TME_SPARC_ASI_MASK_WHICH(asi_mask_data), ! 1825: address, ! 1826: TME_SPARC_FORMAT3_RD)); ! 1827: ! 1828: TME_SPARC_INSN_OK; ! 1829: } ! 1830: ! 1831: /* this does a sparc32 swap: */ ! 1832: TME_SPARC_FORMAT3(tme_sparc32_swap, tme_uint32_t) ! 1833: { ! 1834: tme_uint32_t address; ! 1835: struct tme_sparc_tlb *dtlb; ! 1836: tme_shared tme_uint8_t *memory; ! 1837: tme_uint32_t value; ! 1838: ! 1839: /* get the address: */ ! 1840: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 1841: ! 1842: #ifdef _TME_SPARC_STATS ! 1843: /* track statistics: */ ! 1844: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 1845: #endif /* _TME_SPARC_STATS */ ! 1846: ! 1847: /* log the value stored: */ ! 1848: tme_sparc_verify_mem32(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE); ! 1849: tme_sparc_log(ic, 1000, TME_OK, ! 1850: (TME_SPARC_LOG_HANDLE(ic), ! 1851: _("swap\t0x%02x:0x%08x:\t0x%08x"), ! 1852: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data), ! 1853: address, ! 1854: (tme_uint32_t) TME_SPARC_FORMAT3_RD)); ! 1855: ! 1856: /* get and busy the DTLB entry: */ ! 1857: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 1858: tme_sparc_tlb_busy(dtlb); ! 1859: ! 1860: /* assume that this DTLB applies and allows fast transfers: */ ! 1861: memory = dtlb->tme_sparc_tlb_emulator_off_write; ! 1862: ! 1863: /* we must call the slow store function if: */ ! 1864: if (__tme_predict_false( ! 1865: ! 1866: /* the DTLB entry is invalid: */ ! 1867: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 1868: ! 1869: /* the DTLB entry does not cover the needed addresses: */ ! 1870: || (dtlb->tme_sparc_tlb_addr_first > address) ! 1871: || (dtlb->tme_sparc_tlb_addr_last < (address + ((32 / 8) - 1))) ! 1872: ! 1873: /* the DTLB entry does not cover the needed address space: */ ! 1874: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data)) ! 1875: ! 1876: /* the DTLB entry does not allow fast transfers: */ ! 1877: || (memory != dtlb->tme_sparc_tlb_emulator_off_read) ! 1878: || (memory == TME_EMULATOR_OFF_UNDEF) ! 1879: ! 1880: /* the address is misaligned: */ ! 1881: || ((address % (32 / 8)) != 0) ! 1882: ! 1883: )) { ! 1884: ! 1885: /* call the slow store function: */ ! 1886: memory = tme_sparc32_store(ic, ! 1887: address, ! 1888: &TME_SPARC_FORMAT3_RD, ! 1889: (TME_SPARC_SLOW_FLAG_ATOMIC ! 1890: | (32 / 8))); ! 1891: ! 1892: /* if the slow store function did the transfer, return now: */ ! 1893: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) { ! 1894: tme_sparc_tlb_unbusy(dtlb); ! 1895: TME_SPARC_INSN_OK; ! 1896: } ! 1897: } ! 1898: ! 1899: /* do the fast transfer: */ ! 1900: memory += address; ! 1901: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD); ! 1902: value = tme_memory_atomic_xchg32((tme_shared tme_uint32_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t)); ! 1903: ! 1904: /* unbusy the DTLB entry: */ ! 1905: tme_sparc_tlb_unbusy(dtlb); ! 1906: ! 1907: /* set the loaded value: */ ! 1908: TME_SPARC_FORMAT3_RD = value; ! 1909: ! 1910: /* log the value loaded: */ ! 1911: tme_sparc_verify_mem32(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ); ! 1912: tme_sparc_log(ic, 1000, TME_OK, ! 1913: (TME_SPARC_LOG_HANDLE(ic), ! 1914: _("swap\t0x%02x:0x%08x:\t0x%08x"), ! 1915: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data), ! 1916: address, ! 1917: TME_SPARC_FORMAT3_RD)); ! 1918: ! 1919: TME_SPARC_INSN_OK; ! 1920: } ! 1921: ! 1922: /* this does a sparc32 swapa: */ ! 1923: TME_SPARC_FORMAT3(tme_sparc32_swapa, tme_uint32_t) ! 1924: { ! 1925: tme_uint32_t asi_mask_data; ! 1926: tme_uint32_t address; ! 1927: struct tme_sparc_tlb *dtlb; ! 1928: tme_shared tme_uint8_t *memory; ! 1929: tme_uint32_t value; ! 1930: ! 1931: /* get the alternate ASI mask: */ ! 1932: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic); ! 1933: ! 1934: /* get the address: */ ! 1935: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 1936: ! 1937: #ifdef _TME_SPARC_STATS ! 1938: /* track statistics: */ ! 1939: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 1940: #endif /* _TME_SPARC_STATS */ ! 1941: ! 1942: /* log the value stored: */ ! 1943: tme_sparc_verify_mem32(ic, asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE); ! 1944: tme_sparc_log(ic, 1000, TME_OK, ! 1945: (TME_SPARC_LOG_HANDLE(ic), ! 1946: _("swapa\t0x%02x:0x%08x:\t0x%08x"), ! 1947: TME_SPARC_ASI_MASK_WHICH(asi_mask_data), ! 1948: address, ! 1949: (tme_uint32_t) TME_SPARC_FORMAT3_RD)); ! 1950: ! 1951: /* get and busy the DTLB entry: */ ! 1952: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 1953: tme_sparc_tlb_busy(dtlb); ! 1954: ! 1955: /* assume that this DTLB applies and allows fast transfers: */ ! 1956: memory = dtlb->tme_sparc_tlb_emulator_off_write; ! 1957: ! 1958: /* we must call the slow store function if: */ ! 1959: if (__tme_predict_false( ! 1960: ! 1961: /* the DTLB entry is invalid: */ ! 1962: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 1963: ! 1964: /* the DTLB entry does not cover the needed addresses: */ ! 1965: || (dtlb->tme_sparc_tlb_addr_first > address) ! 1966: || (dtlb->tme_sparc_tlb_addr_last < (address + ((32 / 8) - 1))) ! 1967: ! 1968: /* the DTLB entry does not cover the needed address space: */ ! 1969: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data)) ! 1970: ! 1971: /* the DTLB entry does not allow fast transfers: */ ! 1972: || (memory != dtlb->tme_sparc_tlb_emulator_off_read) ! 1973: || (memory == TME_EMULATOR_OFF_UNDEF) ! 1974: ! 1975: /* the address is misaligned: */ ! 1976: || ((address % (32 / 8)) != 0) ! 1977: ! 1978: )) { ! 1979: ! 1980: /* call the slow store function: */ ! 1981: memory = tme_sparc32_store(ic, ! 1982: address, ! 1983: &TME_SPARC_FORMAT3_RD, ! 1984: (TME_SPARC_SLOW_FLAG_ATOMIC ! 1985: | TME_SPARC_SLOW_FLAG_A ! 1986: | (32 / 8))); ! 1987: ! 1988: /* if the slow store function did the transfer, return now: */ ! 1989: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) { ! 1990: tme_sparc_tlb_unbusy(dtlb); ! 1991: TME_SPARC_INSN_OK; ! 1992: } ! 1993: } ! 1994: ! 1995: /* do the fast transfer: */ ! 1996: memory += address; ! 1997: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD); ! 1998: value = tme_memory_atomic_xchg32((tme_shared tme_uint32_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t)); ! 1999: ! 2000: /* unbusy the DTLB entry: */ ! 2001: tme_sparc_tlb_unbusy(dtlb); ! 2002: ! 2003: /* set the loaded value: */ ! 2004: TME_SPARC_FORMAT3_RD = value; ! 2005: ! 2006: /* log the value loaded: */ ! 2007: tme_sparc_verify_mem32(ic, asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ); ! 2008: tme_sparc_log(ic, 1000, TME_OK, ! 2009: (TME_SPARC_LOG_HANDLE(ic), ! 2010: _("swapa\t0x%02x:0x%08x:\t0x%08x"), ! 2011: TME_SPARC_ASI_MASK_WHICH(asi_mask_data), ! 2012: address, ! 2013: TME_SPARC_FORMAT3_RD)); ! 2014: ! 2015: TME_SPARC_INSN_OK; ! 2016: } ! 2017: ! 2018: /* this does a sparc32 ldba: */ ! 2019: TME_SPARC_FORMAT3(tme_sparc32_ldba, tme_uint32_t) ! 2020: { ! 2021: tme_uint32_t asi_mask_data; ! 2022: tme_uint32_t address; ! 2023: struct tme_sparc_tlb *dtlb; ! 2024: const tme_shared tme_uint8_t *memory; ! 2025: tme_uint32_t value; ! 2026: ! 2027: /* get the alternate ASI mask: */ ! 2028: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic); ! 2029: ! 2030: /* get the address: */ ! 2031: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 2032: ! 2033: #ifdef _TME_SPARC_STATS ! 2034: /* track statistics: */ ! 2035: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 2036: #endif /* _TME_SPARC_STATS */ ! 2037: ! 2038: /* get and busy the DTLB entry: */ ! 2039: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 2040: tme_sparc_tlb_busy(dtlb); ! 2041: ! 2042: /* assume that this DTLB applies and allows fast transfers: */ ! 2043: memory = dtlb->tme_sparc_tlb_emulator_off_read; ! 2044: ! 2045: /* we must call the slow load function if: */ ! 2046: if (__tme_predict_false( ! 2047: ! 2048: /* the DTLB entry is invalid: */ ! 2049: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 2050: ! 2051: /* the DTLB entry does not cover the needed addresses: */ ! 2052: || (dtlb->tme_sparc_tlb_addr_first > address) ! 2053: || (dtlb->tme_sparc_tlb_addr_last < (address + ((8 / 8) - 1))) ! 2054: ! 2055: /* the DTLB entry does not cover the needed address space: */ ! 2056: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data)) ! 2057: ! 2058: /* the DTLB entry does not allow fast transfers: */ ! 2059: || (memory == TME_EMULATOR_OFF_UNDEF) ! 2060: ! 2061: )) { ! 2062: ! 2063: /* call the slow load function: */ ! 2064: memory = tme_sparc32_load(ic, ! 2065: address, ! 2066: (TME_SPARC_SLOW_FLAG_A ! 2067: | (8 / 8))); ! 2068: } ! 2069: ! 2070: /* do the fast transfer: */ ! 2071: memory += address; ! 2072: value = tme_memory_bus_read8((const tme_shared tme_uint8_t *) memory, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t)); ! 2073: ! 2074: /* unbusy the DTLB entry: */ ! 2075: tme_sparc_tlb_unbusy(dtlb); ! 2076: ! 2077: /* possibly sign-extend the loaded value: */ ! 2078: if (TME_SPARC_INSN & TME_BIT(22)) { ! 2079: value = (tme_uint32_t) (tme_int32_t) (tme_int8_t) value; ! 2080: } ! 2081: ! 2082: /* set the loaded value: */ ! 2083: TME_SPARC_FORMAT3_RD = value; ! 2084: ! 2085: /* log the value loaded: */ ! 2086: tme_sparc_verify_mem8(ic, asi_mask_data, address, (tme_uint8_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ); ! 2087: tme_sparc_log(ic, 1000, TME_OK, ! 2088: (TME_SPARC_LOG_HANDLE(ic), ! 2089: _("ldba\t0x%02x:0x%08x:\t0x%08x"), ! 2090: TME_SPARC_ASI_MASK_WHICH(asi_mask_data), ! 2091: address, ! 2092: TME_SPARC_FORMAT3_RD)); ! 2093: ! 2094: TME_SPARC_INSN_OK; ! 2095: } ! 2096: ! 2097: /* this does a sparc32 stba: */ ! 2098: TME_SPARC_FORMAT3(tme_sparc32_stba, tme_uint32_t) ! 2099: { ! 2100: tme_uint32_t asi_mask_data; ! 2101: tme_uint32_t address; ! 2102: struct tme_sparc_tlb *dtlb; ! 2103: tme_shared tme_uint8_t *memory; ! 2104: tme_uint32_t value; ! 2105: ! 2106: /* get the alternate ASI mask: */ ! 2107: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic); ! 2108: ! 2109: /* get the address: */ ! 2110: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 2111: ! 2112: #ifdef _TME_SPARC_STATS ! 2113: /* track statistics: */ ! 2114: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 2115: #endif /* _TME_SPARC_STATS */ ! 2116: ! 2117: /* log the value stored: */ ! 2118: tme_sparc_verify_mem8(ic, asi_mask_data, address, (tme_uint8_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE); ! 2119: tme_sparc_log(ic, 1000, TME_OK, ! 2120: (TME_SPARC_LOG_HANDLE(ic), ! 2121: _("stba\t0x%02x:0x%08x:\t0x%02x"), ! 2122: TME_SPARC_ASI_MASK_WHICH(asi_mask_data), ! 2123: address, ! 2124: (tme_uint8_t) TME_SPARC_FORMAT3_RD)); ! 2125: ! 2126: /* get and busy the DTLB entry: */ ! 2127: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 2128: tme_sparc_tlb_busy(dtlb); ! 2129: ! 2130: /* assume that this DTLB applies and allows fast transfers: */ ! 2131: memory = dtlb->tme_sparc_tlb_emulator_off_write; ! 2132: ! 2133: /* we must call the slow store function if: */ ! 2134: if (__tme_predict_false( ! 2135: ! 2136: /* the DTLB entry is invalid: */ ! 2137: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 2138: ! 2139: /* the DTLB entry does not cover the needed addresses: */ ! 2140: || (dtlb->tme_sparc_tlb_addr_first > address) ! 2141: || (dtlb->tme_sparc_tlb_addr_last < (address + ((8 / 8) - 1))) ! 2142: ! 2143: /* the DTLB entry does not cover the needed address space: */ ! 2144: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data)) ! 2145: ! 2146: /* the DTLB entry does not allow fast transfers: */ ! 2147: || (memory == TME_EMULATOR_OFF_UNDEF) ! 2148: ! 2149: )) { ! 2150: ! 2151: /* call the slow store function: */ ! 2152: memory = tme_sparc32_store(ic, ! 2153: address, ! 2154: &TME_SPARC_FORMAT3_RD, ! 2155: (TME_SPARC_SLOW_FLAG_A ! 2156: | (8 / 8))); ! 2157: ! 2158: /* if the slow store function did the transfer, return now: */ ! 2159: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) { ! 2160: tme_sparc_tlb_unbusy(dtlb); ! 2161: TME_SPARC_INSN_OK; ! 2162: } ! 2163: } ! 2164: ! 2165: /* do the fast transfer: */ ! 2166: memory += address; ! 2167: value = (TME_SPARC_FORMAT3_RD); ! 2168: tme_memory_bus_write8((tme_shared tme_uint8_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t)); ! 2169: ! 2170: /* unbusy the DTLB entry: */ ! 2171: tme_sparc_tlb_unbusy(dtlb); ! 2172: ! 2173: TME_SPARC_INSN_OK; ! 2174: } ! 2175: ! 2176: /* this does a sparc32 ldha: */ ! 2177: TME_SPARC_FORMAT3(tme_sparc32_ldha, tme_uint32_t) ! 2178: { ! 2179: tme_uint32_t asi_mask_data; ! 2180: tme_uint32_t address; ! 2181: struct tme_sparc_tlb *dtlb; ! 2182: const tme_shared tme_uint8_t *memory; ! 2183: tme_uint32_t value; ! 2184: ! 2185: /* get the alternate ASI mask: */ ! 2186: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic); ! 2187: ! 2188: /* get the address: */ ! 2189: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 2190: ! 2191: #ifdef _TME_SPARC_STATS ! 2192: /* track statistics: */ ! 2193: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 2194: #endif /* _TME_SPARC_STATS */ ! 2195: ! 2196: /* get and busy the DTLB entry: */ ! 2197: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 2198: tme_sparc_tlb_busy(dtlb); ! 2199: ! 2200: /* assume that this DTLB applies and allows fast transfers: */ ! 2201: memory = dtlb->tme_sparc_tlb_emulator_off_read; ! 2202: ! 2203: /* we must call the slow load function if: */ ! 2204: if (__tme_predict_false( ! 2205: ! 2206: /* the DTLB entry is invalid: */ ! 2207: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 2208: ! 2209: /* the DTLB entry does not cover the needed addresses: */ ! 2210: || (dtlb->tme_sparc_tlb_addr_first > address) ! 2211: || (dtlb->tme_sparc_tlb_addr_last < (address + ((16 / 8) - 1))) ! 2212: ! 2213: /* the DTLB entry does not cover the needed address space: */ ! 2214: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data)) ! 2215: ! 2216: /* the DTLB entry does not allow fast transfers: */ ! 2217: || (memory == TME_EMULATOR_OFF_UNDEF) ! 2218: ! 2219: /* the address is misaligned: */ ! 2220: || ((address % (16 / 8)) != 0) ! 2221: ! 2222: )) { ! 2223: ! 2224: /* call the slow load function: */ ! 2225: memory = tme_sparc32_load(ic, ! 2226: address, ! 2227: (TME_SPARC_SLOW_FLAG_A ! 2228: | (16 / 8))); ! 2229: } ! 2230: ! 2231: /* do the fast transfer: */ ! 2232: memory += address; ! 2233: value = tme_memory_bus_read16((const tme_shared tme_uint16_t *) memory, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint16_t), sizeof(tme_uint32_t)); ! 2234: value = tme_betoh_u16(value); ! 2235: ! 2236: /* unbusy the DTLB entry: */ ! 2237: tme_sparc_tlb_unbusy(dtlb); ! 2238: ! 2239: /* possibly sign-extend the loaded value: */ ! 2240: if (TME_SPARC_INSN & TME_BIT(22)) { ! 2241: value = (tme_uint32_t) (tme_int32_t) (tme_int16_t) value; ! 2242: } ! 2243: ! 2244: /* set the loaded value: */ ! 2245: TME_SPARC_FORMAT3_RD = value; ! 2246: ! 2247: /* log the value loaded: */ ! 2248: tme_sparc_verify_mem16(ic, asi_mask_data, address, (tme_uint16_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ); ! 2249: tme_sparc_log(ic, 1000, TME_OK, ! 2250: (TME_SPARC_LOG_HANDLE(ic), ! 2251: _("ldha\t0x%02x:0x%08x:\t0x%08x"), ! 2252: TME_SPARC_ASI_MASK_WHICH(asi_mask_data), ! 2253: address, ! 2254: TME_SPARC_FORMAT3_RD)); ! 2255: ! 2256: TME_SPARC_INSN_OK; ! 2257: } ! 2258: ! 2259: /* this does a sparc32 stha: */ ! 2260: TME_SPARC_FORMAT3(tme_sparc32_stha, tme_uint32_t) ! 2261: { ! 2262: tme_uint32_t asi_mask_data; ! 2263: tme_uint32_t address; ! 2264: struct tme_sparc_tlb *dtlb; ! 2265: tme_shared tme_uint8_t *memory; ! 2266: tme_uint32_t value; ! 2267: ! 2268: /* get the alternate ASI mask: */ ! 2269: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic); ! 2270: ! 2271: /* get the address: */ ! 2272: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 2273: ! 2274: #ifdef _TME_SPARC_STATS ! 2275: /* track statistics: */ ! 2276: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 2277: #endif /* _TME_SPARC_STATS */ ! 2278: ! 2279: /* log the value stored: */ ! 2280: tme_sparc_verify_mem16(ic, asi_mask_data, address, (tme_uint16_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE); ! 2281: tme_sparc_log(ic, 1000, TME_OK, ! 2282: (TME_SPARC_LOG_HANDLE(ic), ! 2283: _("stha\t0x%02x:0x%08x:\t0x%04x"), ! 2284: TME_SPARC_ASI_MASK_WHICH(asi_mask_data), ! 2285: address, ! 2286: (tme_uint16_t) TME_SPARC_FORMAT3_RD)); ! 2287: ! 2288: /* get and busy the DTLB entry: */ ! 2289: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 2290: tme_sparc_tlb_busy(dtlb); ! 2291: ! 2292: /* assume that this DTLB applies and allows fast transfers: */ ! 2293: memory = dtlb->tme_sparc_tlb_emulator_off_write; ! 2294: ! 2295: /* we must call the slow store function if: */ ! 2296: if (__tme_predict_false( ! 2297: ! 2298: /* the DTLB entry is invalid: */ ! 2299: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 2300: ! 2301: /* the DTLB entry does not cover the needed addresses: */ ! 2302: || (dtlb->tme_sparc_tlb_addr_first > address) ! 2303: || (dtlb->tme_sparc_tlb_addr_last < (address + ((16 / 8) - 1))) ! 2304: ! 2305: /* the DTLB entry does not cover the needed address space: */ ! 2306: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data)) ! 2307: ! 2308: /* the DTLB entry does not allow fast transfers: */ ! 2309: || (memory == TME_EMULATOR_OFF_UNDEF) ! 2310: ! 2311: /* the address is misaligned: */ ! 2312: || ((address % (16 / 8)) != 0) ! 2313: ! 2314: )) { ! 2315: ! 2316: /* call the slow store function: */ ! 2317: memory = tme_sparc32_store(ic, ! 2318: address, ! 2319: &TME_SPARC_FORMAT3_RD, ! 2320: (TME_SPARC_SLOW_FLAG_A ! 2321: | (16 / 8))); ! 2322: ! 2323: /* if the slow store function did the transfer, return now: */ ! 2324: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) { ! 2325: tme_sparc_tlb_unbusy(dtlb); ! 2326: TME_SPARC_INSN_OK; ! 2327: } ! 2328: } ! 2329: ! 2330: /* do the fast transfer: */ ! 2331: memory += address; ! 2332: value = tme_htobe_u16(TME_SPARC_FORMAT3_RD); ! 2333: tme_memory_bus_write16((tme_shared tme_uint16_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint16_t), sizeof(tme_uint32_t)); ! 2334: ! 2335: /* unbusy the DTLB entry: */ ! 2336: tme_sparc_tlb_unbusy(dtlb); ! 2337: ! 2338: TME_SPARC_INSN_OK; ! 2339: } ! 2340: ! 2341: /* this does a sparc32 lda: */ ! 2342: TME_SPARC_FORMAT3(tme_sparc32_lda, tme_uint32_t) ! 2343: { ! 2344: tme_uint32_t asi_mask_data; ! 2345: tme_uint32_t address; ! 2346: struct tme_sparc_tlb *dtlb; ! 2347: const tme_shared tme_uint8_t *memory; ! 2348: tme_uint32_t value; ! 2349: ! 2350: /* get the alternate ASI mask: */ ! 2351: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic); ! 2352: ! 2353: /* get the address: */ ! 2354: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 2355: ! 2356: #ifdef _TME_SPARC_STATS ! 2357: /* track statistics: */ ! 2358: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 2359: #endif /* _TME_SPARC_STATS */ ! 2360: ! 2361: /* get and busy the DTLB entry: */ ! 2362: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 2363: tme_sparc_tlb_busy(dtlb); ! 2364: ! 2365: /* assume that this DTLB applies and allows fast transfers: */ ! 2366: memory = dtlb->tme_sparc_tlb_emulator_off_read; ! 2367: ! 2368: /* we must call the slow load function if: */ ! 2369: if (__tme_predict_false( ! 2370: ! 2371: /* the DTLB entry is invalid: */ ! 2372: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 2373: ! 2374: /* the DTLB entry does not cover the needed addresses: */ ! 2375: || (dtlb->tme_sparc_tlb_addr_first > address) ! 2376: || (dtlb->tme_sparc_tlb_addr_last < (address + ((32 / 8) - 1))) ! 2377: ! 2378: /* the DTLB entry does not cover the needed address space: */ ! 2379: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data)) ! 2380: ! 2381: /* the DTLB entry does not allow fast transfers: */ ! 2382: || (memory == TME_EMULATOR_OFF_UNDEF) ! 2383: ! 2384: /* the address is misaligned: */ ! 2385: || ((address % (32 / 8)) != 0) ! 2386: ! 2387: )) { ! 2388: ! 2389: /* call the slow load function: */ ! 2390: memory = tme_sparc32_load(ic, ! 2391: address, ! 2392: (TME_SPARC_SLOW_FLAG_A ! 2393: | (32 / 8))); ! 2394: } ! 2395: ! 2396: /* do the fast transfer: */ ! 2397: memory += address; ! 2398: value = tme_memory_bus_read32((const tme_shared tme_uint32_t *) memory, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t)); ! 2399: value = tme_betoh_u32(value); ! 2400: ! 2401: /* unbusy the DTLB entry: */ ! 2402: tme_sparc_tlb_unbusy(dtlb); ! 2403: ! 2404: /* set the loaded value: */ ! 2405: TME_SPARC_FORMAT3_RD = value; ! 2406: ! 2407: /* log the value loaded: */ ! 2408: tme_sparc_verify_mem32(ic, asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ); ! 2409: tme_sparc_log(ic, 1000, TME_OK, ! 2410: (TME_SPARC_LOG_HANDLE(ic), ! 2411: _("lda\t0x%02x:0x%08x:\t0x%08x"), ! 2412: TME_SPARC_ASI_MASK_WHICH(asi_mask_data), ! 2413: address, ! 2414: TME_SPARC_FORMAT3_RD)); ! 2415: ! 2416: TME_SPARC_INSN_OK; ! 2417: } ! 2418: ! 2419: /* this does a sparc32 sta: */ ! 2420: TME_SPARC_FORMAT3(tme_sparc32_sta, tme_uint32_t) ! 2421: { ! 2422: tme_uint32_t asi_mask_data; ! 2423: tme_uint32_t address; ! 2424: struct tme_sparc_tlb *dtlb; ! 2425: tme_shared tme_uint8_t *memory; ! 2426: tme_uint32_t value; ! 2427: ! 2428: /* get the alternate ASI mask: */ ! 2429: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic); ! 2430: ! 2431: /* get the address: */ ! 2432: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 2433: ! 2434: #ifdef _TME_SPARC_STATS ! 2435: /* track statistics: */ ! 2436: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 2437: #endif /* _TME_SPARC_STATS */ ! 2438: ! 2439: /* log the value stored: */ ! 2440: tme_sparc_verify_mem32(ic, asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE); ! 2441: tme_sparc_log(ic, 1000, TME_OK, ! 2442: (TME_SPARC_LOG_HANDLE(ic), ! 2443: _("sta\t0x%02x:0x%08x:\t0x%08x"), ! 2444: TME_SPARC_ASI_MASK_WHICH(asi_mask_data), ! 2445: address, ! 2446: (tme_uint32_t) TME_SPARC_FORMAT3_RD)); ! 2447: ! 2448: /* get and busy the DTLB entry: */ ! 2449: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 2450: tme_sparc_tlb_busy(dtlb); ! 2451: ! 2452: /* assume that this DTLB applies and allows fast transfers: */ ! 2453: memory = dtlb->tme_sparc_tlb_emulator_off_write; ! 2454: ! 2455: /* we must call the slow store function if: */ ! 2456: if (__tme_predict_false( ! 2457: ! 2458: /* the DTLB entry is invalid: */ ! 2459: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 2460: ! 2461: /* the DTLB entry does not cover the needed addresses: */ ! 2462: || (dtlb->tme_sparc_tlb_addr_first > address) ! 2463: || (dtlb->tme_sparc_tlb_addr_last < (address + ((32 / 8) - 1))) ! 2464: ! 2465: /* the DTLB entry does not cover the needed address space: */ ! 2466: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data)) ! 2467: ! 2468: /* the DTLB entry does not allow fast transfers: */ ! 2469: || (memory == TME_EMULATOR_OFF_UNDEF) ! 2470: ! 2471: /* the address is misaligned: */ ! 2472: || ((address % (32 / 8)) != 0) ! 2473: ! 2474: )) { ! 2475: ! 2476: /* call the slow store function: */ ! 2477: memory = tme_sparc32_store(ic, ! 2478: address, ! 2479: &TME_SPARC_FORMAT3_RD, ! 2480: (TME_SPARC_SLOW_FLAG_A ! 2481: | (32 / 8))); ! 2482: ! 2483: /* if the slow store function did the transfer, return now: */ ! 2484: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) { ! 2485: tme_sparc_tlb_unbusy(dtlb); ! 2486: TME_SPARC_INSN_OK; ! 2487: } ! 2488: } ! 2489: ! 2490: /* do the fast transfer: */ ! 2491: memory += address; ! 2492: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD); ! 2493: tme_memory_bus_write32((tme_shared tme_uint32_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t)); ! 2494: ! 2495: /* unbusy the DTLB entry: */ ! 2496: tme_sparc_tlb_unbusy(dtlb); ! 2497: ! 2498: TME_SPARC_INSN_OK; ! 2499: } ! 2500: ! 2501: /* this does a sparc32 ldda: */ ! 2502: TME_SPARC_FORMAT3(tme_sparc32_ldda, tme_uint32_t) ! 2503: { ! 2504: tme_uint32_t asi_mask_data; ! 2505: tme_uint32_t address; ! 2506: struct tme_sparc_tlb *dtlb; ! 2507: const tme_shared tme_uint8_t *memory; ! 2508: tme_uint32_t value; ! 2509: ! 2510: /* get the alternate ASI mask: */ ! 2511: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic); ! 2512: ! 2513: /* get the address: */ ! 2514: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 2515: ! 2516: #ifdef _TME_SPARC_STATS ! 2517: /* track statistics: */ ! 2518: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 2519: #endif /* _TME_SPARC_STATS */ ! 2520: ! 2521: /* get and busy the DTLB entry: */ ! 2522: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 2523: tme_sparc_tlb_busy(dtlb); ! 2524: ! 2525: /* assume that this DTLB applies and allows fast transfers: */ ! 2526: memory = dtlb->tme_sparc_tlb_emulator_off_read; ! 2527: ! 2528: /* we must call the slow load function if: */ ! 2529: if (__tme_predict_false( ! 2530: ! 2531: /* the DTLB entry is invalid: */ ! 2532: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 2533: ! 2534: /* the DTLB entry does not cover the needed addresses: */ ! 2535: || (dtlb->tme_sparc_tlb_addr_first > address) ! 2536: || (dtlb->tme_sparc_tlb_addr_last < (address + ((64 / 8) - 1))) ! 2537: ! 2538: /* the DTLB entry does not cover the needed address space: */ ! 2539: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data)) ! 2540: ! 2541: /* the DTLB entry does not allow fast transfers: */ ! 2542: || (memory == TME_EMULATOR_OFF_UNDEF) ! 2543: ! 2544: /* the address is misaligned: */ ! 2545: || ((address % (64 / 8)) != 0) ! 2546: ! 2547: /* the destination register number is odd: */ ! 2548: || ((TME_SPARC_INSN & TME_BIT(25)) != 0) ! 2549: ! 2550: )) { ! 2551: ! 2552: /* call the slow load function: */ ! 2553: memory = tme_sparc32_load(ic, ! 2554: address, ! 2555: (TME_SPARC_SLOW_FLAG_A ! 2556: | (64 / 8))); ! 2557: } ! 2558: ! 2559: /* do the fast transfer: */ ! 2560: memory += address; ! 2561: value = tme_memory_bus_read32(((const tme_shared tme_uint32_t *) memory) + 0, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t) * 2, sizeof(tme_uint32_t)); ! 2562: TME_SPARC_FORMAT3_RD = tme_betoh_u32(value); ! 2563: value = tme_memory_bus_read32(((const tme_shared tme_uint32_t *) memory) + 1, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t)); ! 2564: TME_SPARC_FORMAT3_RD_ODD = tme_betoh_u32(value); ! 2565: ! 2566: /* unbusy the DTLB entry: */ ! 2567: tme_sparc_tlb_unbusy(dtlb); ! 2568: ! 2569: /* log the value loaded: */ ! 2570: tme_sparc_log(ic, 1000, TME_OK, ! 2571: (TME_SPARC_LOG_HANDLE(ic), ! 2572: _("ldda\t0x%02x:0x%08x:\t0x%08x 0x%08x"), ! 2573: TME_SPARC_ASI_MASK_WHICH(asi_mask_data), ! 2574: address, ! 2575: (tme_uint32_t) TME_SPARC_FORMAT3_RD, ! 2576: (tme_uint32_t) TME_SPARC_FORMAT3_RD_ODD)); ! 2577: ! 2578: TME_SPARC_INSN_OK; ! 2579: } ! 2580: ! 2581: /* this does a sparc32 stda: */ ! 2582: TME_SPARC_FORMAT3(tme_sparc32_stda, tme_uint32_t) ! 2583: { ! 2584: tme_uint32_t asi_mask_data; ! 2585: tme_uint32_t address; ! 2586: struct tme_sparc_tlb *dtlb; ! 2587: tme_shared tme_uint8_t *memory; ! 2588: tme_uint32_t value; ! 2589: ! 2590: /* get the alternate ASI mask: */ ! 2591: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic); ! 2592: ! 2593: /* get the address: */ ! 2594: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 2595: ! 2596: #ifdef _TME_SPARC_STATS ! 2597: /* track statistics: */ ! 2598: ic->tme_sparc_stats.tme_sparc_stats_memory_total++; ! 2599: #endif /* _TME_SPARC_STATS */ ! 2600: ! 2601: /* log the values stored: */ ! 2602: tme_sparc_log(ic, 1000, TME_OK, ! 2603: (TME_SPARC_LOG_HANDLE(ic), ! 2604: _("stda\t0x%02x:0x%08x:\t0x%08x 0x%08x"), ! 2605: TME_SPARC_ASI_MASK_WHICH(asi_mask_data), ! 2606: address, ! 2607: (tme_uint32_t) TME_SPARC_FORMAT3_RD, ! 2608: (tme_uint32_t) TME_SPARC_FORMAT3_RD_ODD)); ! 2609: ! 2610: /* get and busy the DTLB entry: */ ! 2611: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 2612: tme_sparc_tlb_busy(dtlb); ! 2613: ! 2614: /* assume that this DTLB applies and allows fast transfers: */ ! 2615: memory = dtlb->tme_sparc_tlb_emulator_off_write; ! 2616: ! 2617: /* we must call the slow store function if: */ ! 2618: if (__tme_predict_false( ! 2619: ! 2620: /* the DTLB entry is invalid: */ ! 2621: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 2622: ! 2623: /* the DTLB entry does not cover the needed addresses: */ ! 2624: || (dtlb->tme_sparc_tlb_addr_first > address) ! 2625: || (dtlb->tme_sparc_tlb_addr_last < (address + ((64 / 8) - 1))) ! 2626: ! 2627: /* the DTLB entry does not cover the needed address space: */ ! 2628: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data)) ! 2629: ! 2630: /* the DTLB entry does not allow fast transfers: */ ! 2631: || (memory == TME_EMULATOR_OFF_UNDEF) ! 2632: ! 2633: /* the address is misaligned: */ ! 2634: || ((address % (64 / 8)) != 0) ! 2635: ! 2636: /* the destination register number is odd: */ ! 2637: || ((TME_SPARC_INSN & TME_BIT(25)) != 0) ! 2638: ! 2639: )) { ! 2640: ! 2641: /* call the slow store function: */ ! 2642: memory = tme_sparc32_store(ic, ! 2643: address, ! 2644: &TME_SPARC_FORMAT3_RD, ! 2645: (TME_SPARC_SLOW_FLAG_A ! 2646: | (64 / 8))); ! 2647: ! 2648: /* if the slow store function did the transfer, return now: */ ! 2649: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) { ! 2650: tme_sparc_tlb_unbusy(dtlb); ! 2651: TME_SPARC_INSN_OK; ! 2652: } ! 2653: } ! 2654: ! 2655: /* do the fast transfer: */ ! 2656: memory += address; ! 2657: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD); ! 2658: tme_memory_bus_write32(((tme_shared tme_uint32_t *) memory) + 0, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t) * 2, sizeof(tme_uint32_t)); ! 2659: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD_ODD); ! 2660: tme_memory_bus_write32(((tme_shared tme_uint32_t *) memory) + 1, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t)); ! 2661: ! 2662: /* unbusy the DTLB entry: */ ! 2663: tme_sparc_tlb_unbusy(dtlb); ! 2664: ! 2665: TME_SPARC_INSN_OK; ! 2666: } ! 2667: ! 2668: /* this does a sparc32 jmpl: */ ! 2669: TME_SPARC_FORMAT3(tme_sparc32_jmpl, tme_uint32_t) ! 2670: { ! 2671: tme_uint32_t pc_next_next; ! 2672: ! 2673: /* "The JMPL instruction causes a register-indirect delayed control ! 2674: transfer to the address given by r[rs1] + r[rs2] if the i field is ! 2675: zero, or r[rs1] + sign_ext(simm13) if the i field is one. The JMPL ! 2676: instruction copies the PC, which contains the address of the JMPL ! 2677: instruction, into register r[rd]. If either of the low-order two ! 2678: bits of the jump address is nonzero, a mem_address_not_aligned ! 2679: trap occurs." */ ! 2680: ! 2681: pc_next_next = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2; ! 2682: if (__tme_predict_false((pc_next_next % sizeof(tme_uint32_t)) != 0)) { ! 2683: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_mem_address_not_aligned); ! 2684: } ! 2685: ! 2686: /* write the PC of the jmpl into r[rd]: */ ! 2687: TME_SPARC_FORMAT3_RD = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_PC); ! 2688: ! 2689: /* log an indirect call instruction, which has 15 (%o7) for rd: */ ! 2690: if (TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD) == 15) { ! 2691: tme_sparc_log(ic, 250, TME_OK, ! 2692: (TME_SPARC_LOG_HANDLE(ic), ! 2693: _("call 0x%08x"), ! 2694: pc_next_next)); ! 2695: } ! 2696: ! 2697: /* log a ret or retl instruction, which has 0 (%g0) for rd, ! 2698: either 31 (%i7) or 15 (%o7) for rs1, and 8 for simm13: */ ! 2699: else if ((TME_SPARC_INSN | (16 << 14)) ! 2700: == ((tme_uint32_t) (0x2 << 30) | (0 << 25) | (0x38 << 19) | (31 << 14) | (0x1 << 13) | 8)) { ! 2701: tme_sparc_log(ic, 250, TME_OK, ! 2702: (TME_SPARC_LOG_HANDLE(ic), ! 2703: _("retl 0x%08x"), ! 2704: pc_next_next)); ! 2705: } ! 2706: ! 2707: /* set the delayed control transfer: */ ! 2708: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_PC_NEXT_NEXT) = pc_next_next; ! 2709: ! 2710: TME_SPARC_INSN_OK; ! 2711: } ! 2712: ! 2713: /* this does a sparc32 ldf: */ ! 2714: TME_SPARC_FORMAT3(tme_sparc32_ldf, tme_uint32_t) ! 2715: { ! 2716: unsigned int fpreg_number; ! 2717: ! 2718: TME_SPARC_INSN_FPU; ! 2719: ! 2720: /* decode rd: */ ! 2721: fpreg_number = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD); ! 2722: ! 2723: /* make sure this floating-point register is single-precision: */ ! 2724: tme_sparc_fpu_fpreg_format(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN); ! 2725: ! 2726: /* do the load: */ ! 2727: tme_sparc32_ld(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX)); ! 2728: ! 2729: /* set the floating-point register value: */ ! 2730: ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE; ! 2731: ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_value_ieee754_single ! 2732: = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX); ! 2733: ! 2734: TME_SPARC_INSN_OK; ! 2735: } ! 2736: ! 2737: /* this does a sparc32 lddf: */ ! 2738: TME_SPARC_FORMAT3(tme_sparc32_lddf, tme_uint32_t) ! 2739: { ! 2740: unsigned int fpreg_number; ! 2741: ! 2742: TME_SPARC_INSN_FPU; ! 2743: ! 2744: /* decode rd: */ ! 2745: fpreg_number = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD); ! 2746: ! 2747: /* make sure rd is aligned: */ ! 2748: if (!tme_sparc_fpu_fpreg_aligned(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_DOUBLE)) { ! 2749: fpreg_number -= 1; ! 2750: } ! 2751: ! 2752: /* make sure that the double floating-point register is double-precision: */ ! 2753: tme_sparc_fpu_fpreg_format(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN); ! 2754: ! 2755: /* do the load: */ ! 2756: tme_sparc32_ldd(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX)); ! 2757: ! 2758: /* set the double floating-point register value: */ ! 2759: ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE; ! 2760: ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_value_ieee754_double.tme_value64_uint32_hi ! 2761: = ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX) + 0); ! 2762: ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_value_ieee754_double.tme_value64_uint32_lo ! 2763: = ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX) + 1); ! 2764: ! 2765: TME_SPARC_INSN_OK; ! 2766: } ! 2767: ! 2768: /* this does a sparc32 ldfsr: */ ! 2769: TME_SPARC_FORMAT3(tme_sparc32_ldfsr, tme_uint32_t) ! 2770: { ! 2771: tme_uint32_t fsr; ! 2772: ! 2773: TME_SPARC_INSN_FPU; ! 2774: ! 2775: /* do the load: */ ! 2776: tme_sparc32_ld(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX)); ! 2777: ! 2778: /* update the FSR: */ ! 2779: fsr = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX); ! 2780: /* "An LDFSR instruction does not affect ftt." */ ! 2781: /* "The LDFSR instruction does not affect qne." */ ! 2782: fsr &= ~(TME_SPARC_FSR_VER | TME_SPARC_FSR_FTT | TME_SPARC_FSR_QNE); ! 2783: ic->tme_sparc_fpu_fsr = (ic->tme_sparc_fpu_fsr & (TME_SPARC_FSR_VER | TME_SPARC_FSR_FTT | TME_SPARC_FSR_QNE)) | fsr; ! 2784: ! 2785: TME_SPARC_INSN_OK; ! 2786: } ! 2787: ! 2788: /* this does a sparc32 stf: */ ! 2789: TME_SPARC_FORMAT3(tme_sparc32_stf, tme_uint32_t) ! 2790: { ! 2791: unsigned int fpreg_number; ! 2792: const tme_uint32_t *value_single; ! 2793: tme_uint32_t value_single_buffer; ! 2794: ! 2795: TME_SPARC_INSN_FPU_STORE(sizeof(tme_uint32_t)); ! 2796: ! 2797: /* decode rd: */ ! 2798: fpreg_number = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD); ! 2799: ! 2800: /* make sure this floating-point register is single-precision: */ ! 2801: tme_sparc_fpu_fpreg_format(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN); ! 2802: ! 2803: /* get this single floating-point register in IEEE754 single-precision format: */ ! 2804: value_single = tme_ieee754_single_value_get(&ic->tme_sparc_fpu_fpregs[fpreg_number], &value_single_buffer); ! 2805: ! 2806: /* set the floating-point register value: */ ! 2807: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX) = *value_single; ! 2808: ! 2809: /* do the store: */ ! 2810: tme_sparc32_st(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX)); ! 2811: ! 2812: TME_SPARC_INSN_OK; ! 2813: } ! 2814: ! 2815: /* this does a sparc32 stdf: */ ! 2816: TME_SPARC_FORMAT3(tme_sparc32_stdf, tme_uint32_t) ! 2817: { ! 2818: unsigned int fpreg_number; ! 2819: const union tme_value64 *value_double; ! 2820: union tme_value64 value_double_buffer; ! 2821: ! 2822: TME_SPARC_INSN_FPU_STORE(sizeof(tme_uint32_t) * 2); ! 2823: ! 2824: /* decode rd: */ ! 2825: fpreg_number = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD); ! 2826: ! 2827: /* make sure rd is aligned: */ ! 2828: if (!tme_sparc_fpu_fpreg_aligned(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_DOUBLE)) { ! 2829: fpreg_number -= 1; ! 2830: } ! 2831: ! 2832: /* make sure the double floating-point register is double-precision: */ ! 2833: tme_sparc_fpu_fpreg_format(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN); ! 2834: ! 2835: /* get this double floating-point register in IEEE754 double-precision format: */ ! 2836: value_double = tme_ieee754_double_value_get(&ic->tme_sparc_fpu_fpregs[fpreg_number], &value_double_buffer); ! 2837: ! 2838: /* set the floating-point register value: */ ! 2839: ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX) + 0) ! 2840: = value_double->tme_value64_uint32_hi; ! 2841: ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX) + 1) ! 2842: = value_double->tme_value64_uint32_lo; ! 2843: ! 2844: /* do the store: */ ! 2845: tme_sparc32_std(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX)); ! 2846: ! 2847: TME_SPARC_INSN_OK; ! 2848: } ! 2849: ! 2850: /* this does a sparc32 stfsr: */ ! 2851: TME_SPARC_FORMAT3(tme_sparc32_stfsr, tme_uint32_t) ! 2852: { ! 2853: ! 2854: TME_SPARC_INSN_FPU_STORE(sizeof(ic->tme_sparc_fpu_fsr)); ! 2855: ! 2856: /* set the FSR value to store: */ ! 2857: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX) = ic->tme_sparc_fpu_fsr; ! 2858: ! 2859: /* do the store: */ ! 2860: tme_sparc32_st(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX)); ! 2861: ! 2862: TME_SPARC_INSN_OK; ! 2863: } ! 2864: ! 2865: /* this does a sparc32 "mulscc SRC1, SRC2, DST": */ ! 2866: TME_SPARC_FORMAT3(tme_sparc32_mulscc, tme_uint32_t) ! 2867: { ! 2868: tme_uint32_t src1; ! 2869: tme_uint32_t src2; ! 2870: tme_uint32_t dst; ! 2871: tme_uint32_t y; ! 2872: tme_uint32_t cc; ! 2873: ! 2874: /* get the operands: */ ! 2875: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1; ! 2876: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2; ! 2877: ! 2878: /* perform the operation: */ ! 2879: ! 2880: /* "(1) The multiplier is established as r[rs2] if the i field is zero, or ! 2881: sign_ext(simm13) if the i field is one." ! 2882: ! 2883: "(3) If the least significant bit of the Y register = 1, the shifted ! 2884: value from step (2) is added to the multiplier. If the LSB of the ! 2885: Y register = 0, then 0 is added to the shifted value from step (2)." */ ! 2886: y = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y); ! 2887: if ((y & 1) == 0) { ! 2888: src2 = 0; ! 2889: } ! 2890: ! 2891: /* "(6) The Y register is shifted right by one bit, with the LSB of the ! 2892: unshifted r[rs1] replacing the MSB of Y." */ ! 2893: y >>= 1; ! 2894: if (src1 & 1) { ! 2895: y += 0x80000000; ! 2896: } ! 2897: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y) = y; ! 2898: ! 2899: /* "(2) A 32-bit value is computed by shifting r[rs1] right by one ! 2900: bit with (N xor V) from the PSR replacing the high-order bit. ! 2901: (This is the proper sign for the previous partial product.)" */ ! 2902: src1 >>= 1; ! 2903: if (((ic->tme_sparc32_ireg_psr ^ (ic->tme_sparc32_ireg_psr * (TME_SPARC32_PSR_ICC_N / TME_SPARC32_PSR_ICC_V))) & TME_SPARC32_PSR_ICC_N) != 0) { ! 2904: src1 += 0x80000000; ! 2905: } ! 2906: ! 2907: /* "(4) The sum from step (3) is written into r[rd]." */ ! 2908: dst = src1 + src2; ! 2909: ! 2910: /* "(5) The integer condition codes, icc, are updated according to the ! 2911: addition performed in step (3)." */ ! 2912: ! 2913: /* store the destination: */ ! 2914: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst; ! 2915: ! 2916: /* set Z if the destination is zero: */ ! 2917: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z)); ! 2918: ! 2919: /* set N if the destination is negative: */ ! 2920: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N); ! 2921: ! 2922: /* if the operands are the same sign, and the destination has ! 2923: a different sign, set V: */ ! 2924: cc += ((((tme_int32_t) ((src2 ^ dst) & (src1 ^ (src2 ^ (((tme_uint32_t) 0) - 1))))) < 0) * TME_SPARC32_PSR_ICC_V); ! 2925: ! 2926: /* if src1 and src2 both have the high bit set, or if dst does ! 2927: not have the high bit set and either src1 or src2 does, set C: */ ! 2928: cc += (((tme_int32_t) (((tme_uint32_t) (src1 & src2)) | ((((tme_uint32_t) dst) ^ (((tme_uint32_t) 0) - 1)) & ((tme_uint32_t) (src1 | src2))))) < 0) * TME_SPARC32_PSR_ICC_C; ! 2929: ! 2930: /* set the condition codes: */ ! 2931: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc; ! 2932: ! 2933: TME_SPARC_INSN_OK; ! 2934: } ! 2935: ! 2936: /* this does a slow load: */ ! 2937: const tme_shared tme_uint8_t * ! 2938: tme_sparc32_load(struct tme_sparc *ic, ! 2939: tme_uint32_t address, ! 2940: const unsigned int flags) ! 2941: { ! 2942: unsigned int size; ! 2943: tme_uint32_t asi_mask_data; ! 2944: struct tme_sparc_tlb *dtlb; ! 2945: tme_bus_addr_t physical_address; ! 2946: int shift; ! 2947: struct tme_bus_cycle cycle; ! 2948: unsigned int transferred, resid, cycle_size; ! 2949: unsigned int trap; ! 2950: int err; ! 2951: ! 2952: /* get the transfer size. we can do at most a 64-bit transfer: */ ! 2953: size = (flags % (sizeof(tme_uint64_t) * 2)); ! 2954: ! 2955: /* get the DTLB entry. our caller has already busied it: */ ! 2956: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 2957: ! 2958: /* if the address is not aligned: */ ! 2959: if (__tme_predict_false((address & (size - 1)) != 0)) { ! 2960: tme_sparc_tlb_unbusy(dtlb); ! 2961: tme_sparc32_trap(ic, TME_SPARC_TRAP_mem_address_not_aligned); ! 2962: } ! 2963: ! 2964: /* if this is a ldd or a std (and not an lddf or an stdf) ! 2965: and the destination register address is odd: */ ! 2966: /* NB: we detect lddf and stdf by testing bit 24 in the ! 2967: instruction word: */ ! 2968: if (__tme_predict_false(size == (sizeof(tme_uint32_t) * 2) ! 2969: && (TME_SPARC_INSN & TME_BIT(25)) != 0 ! 2970: && (TME_SPARC_INSN & TME_BIT(24)) == 0)) { ! 2971: tme_sparc_tlb_unbusy(dtlb); ! 2972: tme_sparc32_trap(ic, TME_SPARC_TRAP_illegal_instruction); ! 2973: } ! 2974: ! 2975: /* get the ASI and its mask: */ ! 2976: asi_mask_data = ic->tme_sparc_asi_mask_data; ! 2977: if (__tme_predict_false((flags & TME_SPARC_SLOW_FLAG_INSN) != 0)) { ! 2978: asi_mask_data = ic->tme_sparc_asi_mask_insn; ! 2979: } ! 2980: if (__tme_predict_false((flags & TME_SPARC_SLOW_FLAG_A) != 0)) { ! 2981: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic); ! 2982: } ! 2983: ! 2984: /* loop until the load is completed: */ ! 2985: trap = TME_SPARC_TRAP_none; ! 2986: transferred = 0; ! 2987: do { ! 2988: ! 2989: /* while the DTLB entry is invalid, or does not cover this address ! 2990: and address space, or if it does not allow for slow or fast reads: */ ! 2991: for (; (tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 2992: || (dtlb->tme_sparc_tlb_addr_first > address) ! 2993: || (dtlb->tme_sparc_tlb_addr_last < address) ! 2994: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data)) ! 2995: || (dtlb->tme_sparc_tlb_emulator_off_read == TME_EMULATOR_OFF_UNDEF ! 2996: && (dtlb->tme_sparc_tlb_cycles_ok & TME_BUS_CYCLE_READ) == 0)); ) { ! 2997: ! 2998: /* unbusy this DTLB entry for filling: */ ! 2999: tme_bus_tlb_unbusy_fill(&dtlb->tme_sparc_tlb_bus_tlb); ! 3000: ! 3001: /* we never fill TLB entries on the stack because we never ! 3002: callout multiple fills at the same time, so the global TLB ! 3003: entry pointer always points back to the TLB entry. this ! 3004: also means that we do not have to call tme_bus_tlb_back() ! 3005: after the fill: */ ! 3006: dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_global = &dtlb->tme_sparc_tlb_bus_tlb; ! 3007: ! 3008: /* reload the DTLB entry: */ ! 3009: tme_sparc_callout_unlock(ic); ! 3010: #ifdef _TME_SPARC_STATS ! 3011: ic->tme_sparc_stats.tme_sparc_stats_dtlb_fill++; ! 3012: #endif /* _TME_SPARC_STATS */ ! 3013: err = (*ic->_tme_sparc_bus_connection->tme_sparc_bus_tlb_fill) ! 3014: (ic->_tme_sparc_bus_connection, ! 3015: dtlb, ! 3016: asi_mask_data, ! 3017: address, ! 3018: TME_BUS_CYCLE_READ); ! 3019: assert (err == TME_OK); ! 3020: tme_sparc_callout_relock(ic); ! 3021: ! 3022: /* rebusy the DTLB entry: */ ! 3023: tme_sparc_tlb_busy(dtlb); ! 3024: } ! 3025: ! 3026: /* if this DTLB entry allows fast reads: */ ! 3027: if (__tme_predict_true(dtlb->tme_sparc_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF)) { ! 3028: ! 3029: /* if we have not transferred anything yet, and this ! 3030: DTLB entry covers all of the addresses and allows ! 3031: fast transfers: */ ! 3032: if (__tme_predict_true(transferred == 0 ! 3033: && dtlb->tme_sparc_tlb_addr_last >= address + (size - 1) ! 3034: )) { ! 3035: ! 3036: /* return and let our caller do the transfer: */ ! 3037: return (dtlb->tme_sparc_tlb_emulator_off_read); ! 3038: } ! 3039: ! 3040: /* calculate the cycle size: */ ! 3041: cycle_size = (dtlb->tme_sparc_tlb_addr_last - address) + 1; ! 3042: cycle_size = TME_MIN(cycle_size, sizeof(tme_uint32_t) - (address % sizeof(tme_uint32_t))); ! 3043: cycle_size = TME_MIN(cycle_size, size - transferred); ! 3044: cycle.tme_bus_cycle_size = cycle_size; ! 3045: ! 3046: /* do a read: */ ! 3047: tme_memory_bus_read_buffer((dtlb->tme_sparc_tlb_emulator_off_read + address), ! 3048: (&ic->tme_sparc_memory_buffer[0] + transferred), ! 3049: cycle_size, ! 3050: dtlb->tme_sparc_tlb_bus_rwlock, ! 3051: sizeof(tme_uint8_t), ! 3052: sizeof(tme_uint32_t)); ! 3053: } ! 3054: ! 3055: /* otherwise, this DTLB entry does not allow fast reads: */ ! 3056: else { ! 3057: ! 3058: /* make the bus cycle structure: */ ! 3059: resid = size - transferred; ! 3060: cycle.tme_bus_cycle_type = TME_BUS_CYCLE_READ; ! 3061: cycle.tme_bus_cycle_buffer = (tme_uint8_t *) (&ic->tme_sparc_memory_buffer[0] + transferred); ! 3062: cycle.tme_bus_cycle_buffer_increment = 1; ! 3063: cycle_size = TME_MIN(resid, sizeof(tme_uint32_t) - (address % sizeof(tme_uint32_t))); ! 3064: cycle.tme_bus_cycle_size = cycle_size; ! 3065: cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS32_LOG2); ! 3066: cycle.tme_bus_cycle_lane_routing = ! 3067: &tme_sparc32_router[TME_SPARC_BUS_ROUTER_INDEX(TME_BUS32_LOG2, cycle_size, address)]; ! 3068: ! 3069: /* form the physical address for the bus cycle handler: */ ! 3070: physical_address = dtlb->tme_sparc_tlb_addr_offset + address; ! 3071: shift = dtlb->tme_sparc_tlb_addr_shift; ! 3072: if (shift < 0) { ! 3073: physical_address <<= (0 - shift); ! 3074: } ! 3075: else if (shift > 0) { ! 3076: physical_address >>= shift; ! 3077: } ! 3078: cycle.tme_bus_cycle_address = physical_address; ! 3079: ! 3080: /* callout the bus cycle: */ ! 3081: tme_sparc_tlb_unbusy(dtlb); ! 3082: tme_sparc_callout_unlock(ic); ! 3083: err = (*dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_cycle) ! 3084: (dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_cycle_private, &cycle); ! 3085: tme_sparc_callout_relock(ic); ! 3086: tme_sparc_tlb_busy(dtlb); ! 3087: ! 3088: /* if the TLB entry was invalidated before the load: */ ! 3089: if (err == EBADF ! 3090: && tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)) { ! 3091: cycle.tme_bus_cycle_size = 0; ! 3092: } ! 3093: ! 3094: /* otherwise, any other error might be a bus error: */ ! 3095: else if (err != TME_OK) { ! 3096: ! 3097: /* if a real bus error may have happened, instead of ! 3098: some synchronous event: */ ! 3099: if (err != TME_BUS_CYCLE_SYNCHRONOUS_EVENT) { ! 3100: ! 3101: /* call the bus fault handlers: */ ! 3102: err = tme_bus_tlb_fault(&dtlb->tme_sparc_tlb_bus_tlb, &cycle, err); ! 3103: } ! 3104: ! 3105: /* if some synchronous event has happened: */ ! 3106: if (err == TME_BUS_CYCLE_SYNCHRONOUS_EVENT) { ! 3107: ! 3108: /* after the currently executing instruction finishes, check ! 3109: for external resets, halts, or interrupts: */ ! 3110: ic->_tme_sparc_instruction_burst_remaining = 0; ! 3111: } ! 3112: ! 3113: /* otherwise, if a real bus fault happened: */ ! 3114: else if (err != TME_OK) { ! 3115: trap = (*ic->_tme_sparc_bus_fault)(ic, &cycle, flags, err); ! 3116: if (trap != TME_SPARC_TRAP_none) { ! 3117: break; ! 3118: } ! 3119: } ! 3120: } ! 3121: } ! 3122: ! 3123: /* update: */ ! 3124: address += cycle.tme_bus_cycle_size; ! 3125: transferred += cycle.tme_bus_cycle_size; ! 3126: } while (transferred < size); ! 3127: ! 3128: /* if we faulted, start trap processing: */ ! 3129: if (__tme_predict_false(trap != TME_SPARC_TRAP_none)) { ! 3130: tme_sparc_tlb_unbusy(dtlb); ! 3131: tme_sparc32_trap(ic, trap); ! 3132: } ! 3133: ! 3134: return (ic->tme_sparc_memory_buffer - (address - size)); ! 3135: } ! 3136: ! 3137: /* this does a slow store: */ ! 3138: tme_shared tme_uint8_t * ! 3139: tme_sparc32_store(struct tme_sparc *ic, ! 3140: tme_uint32_t address, ! 3141: const tme_uint32_t * const _rd, ! 3142: const unsigned int flags) ! 3143: { ! 3144: unsigned int size; ! 3145: tme_uint32_t asi_mask_data; ! 3146: struct tme_sparc_tlb *dtlb; ! 3147: tme_bus_addr_t physical_address; ! 3148: int shift; ! 3149: struct tme_bus_cycle cycle; ! 3150: unsigned int transferred, resid, cycle_size; ! 3151: unsigned int trap; ! 3152: int err; ! 3153: tme_uint32_t stored_registers[2]; ! 3154: const tme_uint8_t *buffer; ! 3155: ! 3156: /* get the transfer size. we can do at most a 64-bit transfer: */ ! 3157: size = (flags % (sizeof(tme_uint64_t) * 2)); ! 3158: ! 3159: /* get the DTLB entry. our caller has already busied it: */ ! 3160: dtlb = TME_SPARC_DTLB_ENTRY(ic, address); ! 3161: ! 3162: /* if the address is not aligned: */ ! 3163: if (__tme_predict_false((address & (size - 1)) != 0)) { ! 3164: tme_sparc_tlb_unbusy(dtlb); ! 3165: tme_sparc32_trap(ic, TME_SPARC_TRAP_mem_address_not_aligned); ! 3166: } ! 3167: ! 3168: /* if this is a ldd or a std (and not an lddf or an stdf) ! 3169: and the destination register address is odd: */ ! 3170: /* NB: we detect lddf and stdf by testing bit 24 in the ! 3171: instruction word: */ ! 3172: if (__tme_predict_false(size == (sizeof(tme_uint32_t) * 2) ! 3173: && (TME_SPARC_INSN & TME_BIT(25)) != 0 ! 3174: && (TME_SPARC_INSN & TME_BIT(24)) == 0)) { ! 3175: tme_sparc_tlb_unbusy(dtlb); ! 3176: tme_sparc32_trap(ic, TME_SPARC_TRAP_illegal_instruction); ! 3177: } ! 3178: ! 3179: /* get the ASI and its mask: */ ! 3180: asi_mask_data = ic->tme_sparc_asi_mask_data; ! 3181: if (__tme_predict_false((flags & TME_SPARC_SLOW_FLAG_INSN) != 0)) { ! 3182: asi_mask_data = ic->tme_sparc_asi_mask_insn; ! 3183: } ! 3184: if (__tme_predict_false((flags & TME_SPARC_SLOW_FLAG_A) != 0)) { ! 3185: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic); ! 3186: } ! 3187: ! 3188: /* store big-endian versions of the registers to store in ! 3189: a buffer. we always assume that this is a std and copy ! 3190: r[rd] and r[rd + 1] into the buffer: */ ! 3191: stored_registers[0] = tme_htobe_u32(TME_SPARC_FORMAT3_RD); ! 3192: stored_registers[1] = tme_htobe_u32(TME_SPARC_FORMAT3_RD_ODD); ! 3193: ! 3194: /* make the initial pointer into the buffer: */ ! 3195: buffer = (const tme_uint8_t *) stored_registers; ! 3196: if (size < sizeof(tme_uint32_t)) { ! 3197: buffer += sizeof(tme_uint32_t) - size; ! 3198: } ! 3199: ! 3200: /* loop until the store is completed: */ ! 3201: trap = TME_SPARC_TRAP_none; ! 3202: transferred = 0; ! 3203: do { ! 3204: ! 3205: /* while the DTLB entry is invalid, or does not cover this address ! 3206: and address space, or if it does not allow for slow or fast writes: */ ! 3207: for (; (tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb) ! 3208: || (dtlb->tme_sparc_tlb_addr_first > address) ! 3209: || (dtlb->tme_sparc_tlb_addr_last < address) ! 3210: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data)) ! 3211: || (dtlb->tme_sparc_tlb_emulator_off_write == TME_EMULATOR_OFF_UNDEF ! 3212: && (dtlb->tme_sparc_tlb_cycles_ok & TME_BUS_CYCLE_WRITE) == 0)); ) { ! 3213: ! 3214: /* unbusy this DTLB entry for filling: */ ! 3215: tme_bus_tlb_unbusy_fill(&dtlb->tme_sparc_tlb_bus_tlb); ! 3216: ! 3217: /* we never fill TLB entries on the stack because we never ! 3218: callout multiple fills at the same time, so the global TLB ! 3219: entry pointer always points back to the TLB entry. this ! 3220: also means that we do not have to call tme_bus_tlb_back() ! 3221: after the fill: */ ! 3222: dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_global = &dtlb->tme_sparc_tlb_bus_tlb; ! 3223: ! 3224: /* reload the DTLB entry: */ ! 3225: tme_sparc_callout_unlock(ic); ! 3226: #ifdef _TME_SPARC_STATS ! 3227: ic->tme_sparc_stats.tme_sparc_stats_dtlb_fill++; ! 3228: #endif /* _TME_SPARC_STATS */ ! 3229: err = (*ic->_tme_sparc_bus_connection->tme_sparc_bus_tlb_fill) ! 3230: (ic->_tme_sparc_bus_connection, ! 3231: dtlb, ! 3232: asi_mask_data, ! 3233: address, ! 3234: TME_BUS_CYCLE_WRITE); ! 3235: assert (err == TME_OK); ! 3236: tme_sparc_callout_relock(ic); ! 3237: ! 3238: /* rebusy the DTLB entry: */ ! 3239: tme_sparc_tlb_busy(dtlb); ! 3240: } ! 3241: ! 3242: /* if this DTLB entry allows fast writes: */ ! 3243: if (__tme_predict_true(dtlb->tme_sparc_tlb_emulator_off_write != TME_EMULATOR_OFF_UNDEF)) { ! 3244: ! 3245: /* if we have not transferred anything yet, and this ! 3246: DTLB entry covers all of the addresses and allows ! 3247: fast transfers: */ ! 3248: if (__tme_predict_true(transferred == 0 ! 3249: && dtlb->tme_sparc_tlb_addr_last >= address + (size - 1) ! 3250: ! 3251: && ((flags & TME_SPARC_SLOW_FLAG_ATOMIC) == 0 ! 3252: || dtlb->tme_sparc_tlb_emulator_off_read == dtlb->tme_sparc_tlb_emulator_off_write))) { ! 3253: ! 3254: /* return and let our caller do the transfer: */ ! 3255: return (dtlb->tme_sparc_tlb_emulator_off_write); ! 3256: } ! 3257: ! 3258: /* calculate the cycle size: */ ! 3259: cycle_size = (dtlb->tme_sparc_tlb_addr_last - address) + 1; ! 3260: cycle_size = TME_MIN(cycle_size, sizeof(tme_uint32_t) - (address % sizeof(tme_uint32_t))); ! 3261: cycle_size = TME_MIN(cycle_size, size - transferred); ! 3262: cycle.tme_bus_cycle_size = cycle_size; ! 3263: ! 3264: /* do a write: */ ! 3265: tme_memory_bus_write_buffer((dtlb->tme_sparc_tlb_emulator_off_write + address), ! 3266: (buffer + transferred), ! 3267: cycle_size, ! 3268: dtlb->tme_sparc_tlb_bus_rwlock, ! 3269: sizeof(tme_uint8_t), ! 3270: sizeof(tme_uint32_t)); ! 3271: } ! 3272: ! 3273: /* otherwise, this DTLB entry does not allow fast writes: */ ! 3274: else { ! 3275: ! 3276: /* make the bus cycle structure: */ ! 3277: resid = size - transferred; ! 3278: cycle.tme_bus_cycle_type = TME_BUS_CYCLE_WRITE; ! 3279: cycle.tme_bus_cycle_buffer = (tme_uint8_t *) (buffer + transferred); ! 3280: cycle.tme_bus_cycle_buffer_increment = 1; ! 3281: cycle_size = TME_MIN(resid, sizeof(tme_uint32_t) - (address % sizeof(tme_uint32_t))); ! 3282: cycle.tme_bus_cycle_size = cycle_size; ! 3283: cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS32_LOG2); ! 3284: cycle.tme_bus_cycle_lane_routing = ! 3285: &tme_sparc32_router[TME_SPARC_BUS_ROUTER_INDEX(TME_BUS32_LOG2, cycle_size, address)]; ! 3286: ! 3287: /* form the physical address for the bus cycle handler: */ ! 3288: physical_address = dtlb->tme_sparc_tlb_addr_offset + address; ! 3289: shift = dtlb->tme_sparc_tlb_addr_shift; ! 3290: if (shift < 0) { ! 3291: physical_address <<= (0 - shift); ! 3292: } ! 3293: else if (shift > 0) { ! 3294: physical_address >>= shift; ! 3295: } ! 3296: cycle.tme_bus_cycle_address = physical_address; ! 3297: ! 3298: /* callout the bus cycle: */ ! 3299: tme_sparc_tlb_unbusy(dtlb); ! 3300: tme_sparc_callout_unlock(ic); ! 3301: err = (*dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_cycle) ! 3302: (dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_cycle_private, &cycle); ! 3303: tme_sparc_callout_relock(ic); ! 3304: tme_sparc_tlb_busy(dtlb); ! 3305: ! 3306: /* if the TLB entry was invalidated before the store: */ ! 3307: if (err == EBADF ! 3308: && tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)) { ! 3309: cycle.tme_bus_cycle_size = 0; ! 3310: } ! 3311: ! 3312: /* otherwise, any other error might be a bus error: */ ! 3313: else if (err != TME_OK) { ! 3314: ! 3315: /* if a real bus error may have happened, instead of ! 3316: some synchronous event: */ ! 3317: if (err != TME_BUS_CYCLE_SYNCHRONOUS_EVENT) { ! 3318: ! 3319: /* call the bus fault handlers: */ ! 3320: err = tme_bus_tlb_fault(&dtlb->tme_sparc_tlb_bus_tlb, &cycle, err); ! 3321: } ! 3322: ! 3323: /* if some synchronous event has happened: */ ! 3324: if (err == TME_BUS_CYCLE_SYNCHRONOUS_EVENT) { ! 3325: ! 3326: /* after the currently executing instruction finishes, check ! 3327: for external resets, halts, or interrupts: */ ! 3328: ic->_tme_sparc_instruction_burst_remaining = 0; ! 3329: } ! 3330: ! 3331: /* otherwise, if a real bus fault happened: */ ! 3332: else if (err != TME_OK) { ! 3333: trap = (*ic->_tme_sparc_bus_fault)(ic, &cycle, flags, err); ! 3334: if (trap != TME_SPARC_TRAP_none) { ! 3335: break; ! 3336: } ! 3337: } ! 3338: } ! 3339: ! 3340: /* if this was an atomic operation, and data was transferred: */ ! 3341: if (__tme_predict_false((flags & TME_SPARC_SLOW_FLAG_ATOMIC) != 0 ! 3342: && cycle.tme_bus_cycle_size > 0)) { ! 3343: ! 3344: /* we do not support atomic operations in TLB entries that ! 3345: do not support both fast reads and fast writes. assuming ! 3346: that all atomic operations are to regular memory, we ! 3347: should always get fast read and fast write TLBs. when ! 3348: we do not, it should only be because the memory has been ! 3349: made read-only in the MMU. the write above was supposed ! 3350: to cause a fault (with the instruction rerun later with ! 3351: a fast read and fast write TLB entry), but instead it ! 3352: succeeded and transferred some data. we have modified ! 3353: memory and cannot recover: */ ! 3354: abort(); ! 3355: } ! 3356: } ! 3357: ! 3358: /* update: */ ! 3359: address += cycle.tme_bus_cycle_size; ! 3360: transferred += cycle.tme_bus_cycle_size; ! 3361: } while (transferred < size); ! 3362: ! 3363: /* if we faulted, start trap processing: */ ! 3364: if (__tme_predict_false(trap != TME_SPARC_TRAP_none)) { ! 3365: tme_sparc_tlb_unbusy(dtlb); ! 3366: tme_sparc32_trap(ic, trap); ! 3367: } ! 3368: ! 3369: return ((tme_uint8_t *) TME_EMULATOR_OFF_UNDEF); ! 3370: } ! 3371: ! 3372: #undef TME_SPARC_VERSION ! 3373: #define TME_SPARC_VERSION(ic) _TME_SPARC_VERSION(ic) ! 3374: /* automatically generated by sparc-misc-auto.sh, do not edit! */ ! 3375: ! 3376: /* the icc->conditions mapping: */ ! 3377: const tme_uint8_t _tme_sparc_conds_icc[16] = { ! 3378: 0, ! 3379: 0 | TME_BIT(4) | TME_BIT(5), ! 3380: 0 | TME_BIT(2) | TME_BIT(3) | TME_BIT(7), ! 3381: 0 | TME_BIT(2) | TME_BIT(3) | TME_BIT(4) | TME_BIT(5) | TME_BIT(7), ! 3382: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(4), ! 3383: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(4) | TME_BIT(5), ! 3384: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(3) | TME_BIT(4) | TME_BIT(7), ! 3385: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(3) | TME_BIT(4) | TME_BIT(5) | TME_BIT(7), ! 3386: 0 | TME_BIT(2) | TME_BIT(3) | TME_BIT(6), ! 3387: 0 | TME_BIT(2) | TME_BIT(3) | TME_BIT(4) | TME_BIT(5) | TME_BIT(6), ! 3388: 0 | TME_BIT(6) | TME_BIT(7), ! 3389: 0 | TME_BIT(4) | TME_BIT(5) | TME_BIT(6) | TME_BIT(7), ! 3390: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(3) | TME_BIT(4) | TME_BIT(6), ! 3391: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(3) | TME_BIT(4) | TME_BIT(5) | TME_BIT(6), ! 3392: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(4) | TME_BIT(6) | TME_BIT(7), ! 3393: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(4) | TME_BIT(5) | TME_BIT(6) | TME_BIT(7), ! 3394: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.