|
|
1.1 ! root 1: /* ! 2: * Alpha emulation cpu translation for qemu. ! 3: * ! 4: * Copyright (c) 2007 Jocelyn Mayer ! 5: * ! 6: * This library is free software; you can redistribute it and/or ! 7: * modify it under the terms of the GNU Lesser General Public ! 8: * License as published by the Free Software Foundation; either ! 9: * version 2 of the License, or (at your option) any later version. ! 10: * ! 11: * This library is distributed in the hope that it will be useful, ! 12: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 14: * Lesser General Public License for more details. ! 15: * ! 16: * You should have received a copy of the GNU Lesser General Public ! 17: * License along with this library; if not, write to the Free Software ! 18: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ! 19: */ ! 20: ! 21: #include <stdint.h> ! 22: #include <stdlib.h> ! 23: #include <stdio.h> ! 24: ! 25: #include "cpu.h" ! 26: #include "exec-all.h" ! 27: #include "disas.h" ! 28: ! 29: #define DO_SINGLE_STEP ! 30: #define GENERATE_NOP ! 31: #define ALPHA_DEBUG_DISAS ! 32: #define DO_TB_FLUSH ! 33: ! 34: typedef struct DisasContext DisasContext; ! 35: struct DisasContext { ! 36: uint64_t pc; ! 37: int mem_idx; ! 38: #if !defined (CONFIG_USER_ONLY) ! 39: int pal_mode; ! 40: #endif ! 41: uint32_t amask; ! 42: }; ! 43: ! 44: #ifdef USE_DIRECT_JUMP ! 45: #define TBPARAM(x) ! 46: #else ! 47: #define TBPARAM(x) (long)(x) ! 48: #endif ! 49: ! 50: enum { ! 51: #define DEF(s, n, copy_size) INDEX_op_ ## s, ! 52: #include "opc.h" ! 53: #undef DEF ! 54: NB_OPS, ! 55: }; ! 56: ! 57: static uint16_t *gen_opc_ptr; ! 58: static uint32_t *gen_opparam_ptr; ! 59: ! 60: #include "gen-op.h" ! 61: ! 62: static always_inline void gen_op_nop (void) ! 63: { ! 64: #if defined(GENERATE_NOP) ! 65: gen_op_no_op(); ! 66: #endif ! 67: } ! 68: ! 69: #define GEN32(func, NAME) \ ! 70: static GenOpFunc *NAME ## _table [32] = { \ ! 71: NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \ ! 72: NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \ ! 73: NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \ ! 74: NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \ ! 75: NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \ ! 76: NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \ ! 77: NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \ ! 78: NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \ ! 79: }; \ ! 80: static always_inline void func (int n) \ ! 81: { \ ! 82: NAME ## _table[n](); \ ! 83: } ! 84: ! 85: /* IR moves */ ! 86: /* Special hacks for ir31 */ ! 87: #define gen_op_load_T0_ir31 gen_op_reset_T0 ! 88: #define gen_op_load_T1_ir31 gen_op_reset_T1 ! 89: #define gen_op_load_T2_ir31 gen_op_reset_T2 ! 90: #define gen_op_store_T0_ir31 gen_op_nop ! 91: #define gen_op_store_T1_ir31 gen_op_nop ! 92: #define gen_op_store_T2_ir31 gen_op_nop ! 93: #define gen_op_cmov_ir31 gen_op_nop ! 94: GEN32(gen_op_load_T0_ir, gen_op_load_T0_ir); ! 95: GEN32(gen_op_load_T1_ir, gen_op_load_T1_ir); ! 96: GEN32(gen_op_load_T2_ir, gen_op_load_T2_ir); ! 97: GEN32(gen_op_store_T0_ir, gen_op_store_T0_ir); ! 98: GEN32(gen_op_store_T1_ir, gen_op_store_T1_ir); ! 99: GEN32(gen_op_store_T2_ir, gen_op_store_T2_ir); ! 100: GEN32(gen_op_cmov_ir, gen_op_cmov_ir); ! 101: ! 102: static always_inline void gen_load_ir (DisasContext *ctx, int irn, int Tn) ! 103: { ! 104: switch (Tn) { ! 105: case 0: ! 106: gen_op_load_T0_ir(irn); ! 107: break; ! 108: case 1: ! 109: gen_op_load_T1_ir(irn); ! 110: break; ! 111: case 2: ! 112: gen_op_load_T2_ir(irn); ! 113: break; ! 114: } ! 115: } ! 116: ! 117: static always_inline void gen_store_ir (DisasContext *ctx, int irn, int Tn) ! 118: { ! 119: switch (Tn) { ! 120: case 0: ! 121: gen_op_store_T0_ir(irn); ! 122: break; ! 123: case 1: ! 124: gen_op_store_T1_ir(irn); ! 125: break; ! 126: case 2: ! 127: gen_op_store_T2_ir(irn); ! 128: break; ! 129: } ! 130: } ! 131: ! 132: /* FIR moves */ ! 133: /* Special hacks for fir31 */ ! 134: #define gen_op_load_FT0_fir31 gen_op_reset_FT0 ! 135: #define gen_op_load_FT1_fir31 gen_op_reset_FT1 ! 136: #define gen_op_load_FT2_fir31 gen_op_reset_FT2 ! 137: #define gen_op_store_FT0_fir31 gen_op_nop ! 138: #define gen_op_store_FT1_fir31 gen_op_nop ! 139: #define gen_op_store_FT2_fir31 gen_op_nop ! 140: #define gen_op_cmov_fir31 gen_op_nop ! 141: GEN32(gen_op_load_FT0_fir, gen_op_load_FT0_fir); ! 142: GEN32(gen_op_load_FT1_fir, gen_op_load_FT1_fir); ! 143: GEN32(gen_op_load_FT2_fir, gen_op_load_FT2_fir); ! 144: GEN32(gen_op_store_FT0_fir, gen_op_store_FT0_fir); ! 145: GEN32(gen_op_store_FT1_fir, gen_op_store_FT1_fir); ! 146: GEN32(gen_op_store_FT2_fir, gen_op_store_FT2_fir); ! 147: GEN32(gen_op_cmov_fir, gen_op_cmov_fir); ! 148: ! 149: static always_inline void gen_load_fir (DisasContext *ctx, int firn, int Tn) ! 150: { ! 151: switch (Tn) { ! 152: case 0: ! 153: gen_op_load_FT0_fir(firn); ! 154: break; ! 155: case 1: ! 156: gen_op_load_FT1_fir(firn); ! 157: break; ! 158: case 2: ! 159: gen_op_load_FT2_fir(firn); ! 160: break; ! 161: } ! 162: } ! 163: ! 164: static always_inline void gen_store_fir (DisasContext *ctx, int firn, int Tn) ! 165: { ! 166: switch (Tn) { ! 167: case 0: ! 168: gen_op_store_FT0_fir(firn); ! 169: break; ! 170: case 1: ! 171: gen_op_store_FT1_fir(firn); ! 172: break; ! 173: case 2: ! 174: gen_op_store_FT2_fir(firn); ! 175: break; ! 176: } ! 177: } ! 178: ! 179: /* Memory moves */ ! 180: #if defined(CONFIG_USER_ONLY) ! 181: #define OP_LD_TABLE(width) \ ! 182: static GenOpFunc *gen_op_ld##width[] = { \ ! 183: &gen_op_ld##width##_raw, \ ! 184: } ! 185: #define OP_ST_TABLE(width) \ ! 186: static GenOpFunc *gen_op_st##width[] = { \ ! 187: &gen_op_st##width##_raw, \ ! 188: } ! 189: #else ! 190: #define OP_LD_TABLE(width) \ ! 191: static GenOpFunc *gen_op_ld##width[] = { \ ! 192: &gen_op_ld##width##_kernel, \ ! 193: &gen_op_ld##width##_executive, \ ! 194: &gen_op_ld##width##_supervisor, \ ! 195: &gen_op_ld##width##_user, \ ! 196: } ! 197: #define OP_ST_TABLE(width) \ ! 198: static GenOpFunc *gen_op_st##width[] = { \ ! 199: &gen_op_st##width##_kernel, \ ! 200: &gen_op_st##width##_executive, \ ! 201: &gen_op_st##width##_supervisor, \ ! 202: &gen_op_st##width##_user, \ ! 203: } ! 204: #endif ! 205: ! 206: #define GEN_LD(width) \ ! 207: OP_LD_TABLE(width); \ ! 208: static always_inline void gen_ld##width (DisasContext *ctx) \ ! 209: { \ ! 210: (*gen_op_ld##width[ctx->mem_idx])(); \ ! 211: } ! 212: ! 213: #define GEN_ST(width) \ ! 214: OP_ST_TABLE(width); \ ! 215: static always_inline void gen_st##width (DisasContext *ctx) \ ! 216: { \ ! 217: (*gen_op_st##width[ctx->mem_idx])(); \ ! 218: } ! 219: ! 220: GEN_LD(bu); ! 221: GEN_ST(b); ! 222: GEN_LD(wu); ! 223: GEN_ST(w); ! 224: GEN_LD(l); ! 225: GEN_ST(l); ! 226: GEN_LD(q); ! 227: GEN_ST(q); ! 228: GEN_LD(q_u); ! 229: GEN_ST(q_u); ! 230: GEN_LD(l_l); ! 231: GEN_ST(l_c); ! 232: GEN_LD(q_l); ! 233: GEN_ST(q_c); ! 234: ! 235: #if 0 /* currently unused */ ! 236: GEN_LD(f); ! 237: GEN_ST(f); ! 238: GEN_LD(g); ! 239: GEN_ST(g); ! 240: #endif /* 0 */ ! 241: GEN_LD(s); ! 242: GEN_ST(s); ! 243: GEN_LD(t); ! 244: GEN_ST(t); ! 245: ! 246: #if defined(__i386__) || defined(__x86_64__) ! 247: static always_inline void gen_op_set_s16_T0 (int16_t imm) ! 248: { ! 249: gen_op_set_s32_T0((int32_t)imm); ! 250: } ! 251: ! 252: static always_inline void gen_op_set_s16_T1 (int16_t imm) ! 253: { ! 254: gen_op_set_s32_T1((int32_t)imm); ! 255: } ! 256: ! 257: static always_inline void gen_op_set_u16_T0 (uint16_t imm) ! 258: { ! 259: gen_op_set_s32_T0((uint32_t)imm); ! 260: } ! 261: ! 262: static always_inline void gen_op_set_u16_T1 (uint16_t imm) ! 263: { ! 264: gen_op_set_s32_T1((uint32_t)imm); ! 265: } ! 266: #endif ! 267: ! 268: static always_inline void gen_set_sT0 (DisasContext *ctx, int64_t imm) ! 269: { ! 270: int32_t imm32; ! 271: int16_t imm16; ! 272: ! 273: imm32 = imm; ! 274: if (imm32 == imm) { ! 275: imm16 = imm; ! 276: if (imm16 == imm) { ! 277: if (imm == 0) { ! 278: gen_op_reset_T0(); ! 279: } else { ! 280: gen_op_set_s16_T0(imm16); ! 281: } ! 282: } else { ! 283: gen_op_set_s32_T0(imm32); ! 284: } ! 285: } else { ! 286: #if 0 // Qemu does not know how to do this... ! 287: gen_op_set_64_T0(imm); ! 288: #else ! 289: gen_op_set_64_T0(imm >> 32, imm); ! 290: #endif ! 291: } ! 292: } ! 293: ! 294: static always_inline void gen_set_sT1 (DisasContext *ctx, int64_t imm) ! 295: { ! 296: int32_t imm32; ! 297: int16_t imm16; ! 298: ! 299: imm32 = imm; ! 300: if (imm32 == imm) { ! 301: imm16 = imm; ! 302: if (imm16 == imm) { ! 303: if (imm == 0) { ! 304: gen_op_reset_T1(); ! 305: } else { ! 306: gen_op_set_s16_T1(imm16); ! 307: } ! 308: } else { ! 309: gen_op_set_s32_T1(imm32); ! 310: } ! 311: } else { ! 312: #if 0 // Qemu does not know how to do this... ! 313: gen_op_set_64_T1(imm); ! 314: #else ! 315: gen_op_set_64_T1(imm >> 32, imm); ! 316: #endif ! 317: } ! 318: } ! 319: ! 320: static always_inline void gen_set_uT0 (DisasContext *ctx, uint64_t imm) ! 321: { ! 322: if (!(imm >> 32)) { ! 323: if ((!imm >> 16)) { ! 324: if (imm == 0) ! 325: gen_op_reset_T0(); ! 326: else ! 327: gen_op_set_u16_T0(imm); ! 328: } else { ! 329: gen_op_set_u32_T0(imm); ! 330: } ! 331: } else { ! 332: #if 0 // Qemu does not know how to do this... ! 333: gen_op_set_64_T0(imm); ! 334: #else ! 335: gen_op_set_64_T0(imm >> 32, imm); ! 336: #endif ! 337: } ! 338: } ! 339: ! 340: static always_inline void gen_set_uT1 (DisasContext *ctx, uint64_t imm) ! 341: { ! 342: if (!(imm >> 32)) { ! 343: if ((!imm >> 16)) { ! 344: if (imm == 0) ! 345: gen_op_reset_T1(); ! 346: else ! 347: gen_op_set_u16_T1(imm); ! 348: } else { ! 349: gen_op_set_u32_T1(imm); ! 350: } ! 351: } else { ! 352: #if 0 // Qemu does not know how to do this... ! 353: gen_op_set_64_T1(imm); ! 354: #else ! 355: gen_op_set_64_T1(imm >> 32, imm); ! 356: #endif ! 357: } ! 358: } ! 359: ! 360: static always_inline void gen_update_pc (DisasContext *ctx) ! 361: { ! 362: if (!(ctx->pc >> 32)) { ! 363: gen_op_update_pc32(ctx->pc); ! 364: } else { ! 365: #if 0 // Qemu does not know how to do this... ! 366: gen_op_update_pc(ctx->pc); ! 367: #else ! 368: gen_op_update_pc(ctx->pc >> 32, ctx->pc); ! 369: #endif ! 370: } ! 371: } ! 372: ! 373: static always_inline void _gen_op_bcond (DisasContext *ctx) ! 374: { ! 375: #if 0 // Qemu does not know how to do this... ! 376: gen_op_bcond(ctx->pc); ! 377: #else ! 378: gen_op_bcond(ctx->pc >> 32, ctx->pc); ! 379: #endif ! 380: } ! 381: ! 382: static always_inline void gen_excp (DisasContext *ctx, ! 383: int exception, int error_code) ! 384: { ! 385: gen_update_pc(ctx); ! 386: gen_op_excp(exception, error_code); ! 387: } ! 388: ! 389: static always_inline void gen_invalid (DisasContext *ctx) ! 390: { ! 391: gen_excp(ctx, EXCP_OPCDEC, 0); ! 392: } ! 393: ! 394: static always_inline void gen_load_mem (DisasContext *ctx, ! 395: void (*gen_load_op)(DisasContext *ctx), ! 396: int ra, int rb, int32_t disp16, ! 397: int clear) ! 398: { ! 399: if (ra == 31 && disp16 == 0) { ! 400: /* UNOP */ ! 401: gen_op_nop(); ! 402: } else { ! 403: gen_load_ir(ctx, rb, 0); ! 404: if (disp16 != 0) { ! 405: gen_set_sT1(ctx, disp16); ! 406: gen_op_addq(); ! 407: } ! 408: if (clear) ! 409: gen_op_n7(); ! 410: (*gen_load_op)(ctx); ! 411: gen_store_ir(ctx, ra, 1); ! 412: } ! 413: } ! 414: ! 415: static always_inline void gen_store_mem (DisasContext *ctx, ! 416: void (*gen_store_op)(DisasContext *ctx), ! 417: int ra, int rb, int32_t disp16, ! 418: int clear) ! 419: { ! 420: gen_load_ir(ctx, rb, 0); ! 421: if (disp16 != 0) { ! 422: gen_set_sT1(ctx, disp16); ! 423: gen_op_addq(); ! 424: } ! 425: if (clear) ! 426: gen_op_n7(); ! 427: gen_load_ir(ctx, ra, 1); ! 428: (*gen_store_op)(ctx); ! 429: } ! 430: ! 431: static always_inline void gen_load_fmem (DisasContext *ctx, ! 432: void (*gen_load_fop)(DisasContext *ctx), ! 433: int ra, int rb, int32_t disp16) ! 434: { ! 435: gen_load_ir(ctx, rb, 0); ! 436: if (disp16 != 0) { ! 437: gen_set_sT1(ctx, disp16); ! 438: gen_op_addq(); ! 439: } ! 440: (*gen_load_fop)(ctx); ! 441: gen_store_fir(ctx, ra, 1); ! 442: } ! 443: ! 444: static always_inline void gen_store_fmem (DisasContext *ctx, ! 445: void (*gen_store_fop)(DisasContext *ctx), ! 446: int ra, int rb, int32_t disp16) ! 447: { ! 448: gen_load_ir(ctx, rb, 0); ! 449: if (disp16 != 0) { ! 450: gen_set_sT1(ctx, disp16); ! 451: gen_op_addq(); ! 452: } ! 453: gen_load_fir(ctx, ra, 1); ! 454: (*gen_store_fop)(ctx); ! 455: } ! 456: ! 457: static always_inline void gen_bcond (DisasContext *ctx, ! 458: void (*gen_test_op)(void), ! 459: int ra, int32_t disp16) ! 460: { ! 461: if (disp16 != 0) { ! 462: gen_set_uT0(ctx, ctx->pc); ! 463: gen_set_sT1(ctx, disp16 << 2); ! 464: gen_op_addq1(); ! 465: } else { ! 466: gen_set_uT1(ctx, ctx->pc); ! 467: } ! 468: gen_load_ir(ctx, ra, 0); ! 469: (*gen_test_op)(); ! 470: _gen_op_bcond(ctx); ! 471: } ! 472: ! 473: static always_inline void gen_fbcond (DisasContext *ctx, ! 474: void (*gen_test_op)(void), ! 475: int ra, int32_t disp16) ! 476: { ! 477: if (disp16 != 0) { ! 478: gen_set_uT0(ctx, ctx->pc); ! 479: gen_set_sT1(ctx, disp16 << 2); ! 480: gen_op_addq1(); ! 481: } else { ! 482: gen_set_uT1(ctx, ctx->pc); ! 483: } ! 484: gen_load_fir(ctx, ra, 0); ! 485: (*gen_test_op)(); ! 486: _gen_op_bcond(ctx); ! 487: } ! 488: ! 489: static always_inline void gen_arith2 (DisasContext *ctx, ! 490: void (*gen_arith_op)(void), ! 491: int rb, int rc, int islit, int8_t lit) ! 492: { ! 493: if (islit) ! 494: gen_set_sT0(ctx, lit); ! 495: else ! 496: gen_load_ir(ctx, rb, 0); ! 497: (*gen_arith_op)(); ! 498: gen_store_ir(ctx, rc, 0); ! 499: } ! 500: ! 501: static always_inline void gen_arith3 (DisasContext *ctx, ! 502: void (*gen_arith_op)(void), ! 503: int ra, int rb, int rc, ! 504: int islit, int8_t lit) ! 505: { ! 506: gen_load_ir(ctx, ra, 0); ! 507: if (islit) ! 508: gen_set_sT1(ctx, lit); ! 509: else ! 510: gen_load_ir(ctx, rb, 1); ! 511: (*gen_arith_op)(); ! 512: gen_store_ir(ctx, rc, 0); ! 513: } ! 514: ! 515: static always_inline void gen_cmov (DisasContext *ctx, ! 516: void (*gen_test_op)(void), ! 517: int ra, int rb, int rc, ! 518: int islit, int8_t lit) ! 519: { ! 520: gen_load_ir(ctx, ra, 1); ! 521: if (islit) ! 522: gen_set_sT0(ctx, lit); ! 523: else ! 524: gen_load_ir(ctx, rb, 0); ! 525: (*gen_test_op)(); ! 526: gen_op_cmov_ir(rc); ! 527: } ! 528: ! 529: static always_inline void gen_farith2 (DisasContext *ctx, ! 530: void (*gen_arith_fop)(void), ! 531: int rb, int rc) ! 532: { ! 533: gen_load_fir(ctx, rb, 0); ! 534: (*gen_arith_fop)(); ! 535: gen_store_fir(ctx, rc, 0); ! 536: } ! 537: ! 538: static always_inline void gen_farith3 (DisasContext *ctx, ! 539: void (*gen_arith_fop)(void), ! 540: int ra, int rb, int rc) ! 541: { ! 542: gen_load_fir(ctx, ra, 0); ! 543: gen_load_fir(ctx, rb, 1); ! 544: (*gen_arith_fop)(); ! 545: gen_store_fir(ctx, rc, 0); ! 546: } ! 547: ! 548: static always_inline void gen_fcmov (DisasContext *ctx, ! 549: void (*gen_test_fop)(void), ! 550: int ra, int rb, int rc) ! 551: { ! 552: gen_load_fir(ctx, ra, 0); ! 553: gen_load_fir(ctx, rb, 1); ! 554: (*gen_test_fop)(); ! 555: gen_op_cmov_fir(rc); ! 556: } ! 557: ! 558: static always_inline void gen_fti (DisasContext *ctx, ! 559: void (*gen_move_fop)(void), ! 560: int ra, int rc) ! 561: { ! 562: gen_load_fir(ctx, rc, 0); ! 563: (*gen_move_fop)(); ! 564: gen_store_ir(ctx, ra, 0); ! 565: } ! 566: ! 567: static always_inline void gen_itf (DisasContext *ctx, ! 568: void (*gen_move_fop)(void), ! 569: int ra, int rc) ! 570: { ! 571: gen_load_ir(ctx, ra, 0); ! 572: (*gen_move_fop)(); ! 573: gen_store_fir(ctx, rc, 0); ! 574: } ! 575: ! 576: static always_inline void gen_s4addl (void) ! 577: { ! 578: gen_op_s4(); ! 579: gen_op_addl(); ! 580: } ! 581: ! 582: static always_inline void gen_s4subl (void) ! 583: { ! 584: gen_op_s4(); ! 585: gen_op_subl(); ! 586: } ! 587: ! 588: static always_inline void gen_s8addl (void) ! 589: { ! 590: gen_op_s8(); ! 591: gen_op_addl(); ! 592: } ! 593: ! 594: static always_inline void gen_s8subl (void) ! 595: { ! 596: gen_op_s8(); ! 597: gen_op_subl(); ! 598: } ! 599: ! 600: static always_inline void gen_s4addq (void) ! 601: { ! 602: gen_op_s4(); ! 603: gen_op_addq(); ! 604: } ! 605: ! 606: static always_inline void gen_s4subq (void) ! 607: { ! 608: gen_op_s4(); ! 609: gen_op_subq(); ! 610: } ! 611: ! 612: static always_inline void gen_s8addq (void) ! 613: { ! 614: gen_op_s8(); ! 615: gen_op_addq(); ! 616: } ! 617: ! 618: static always_inline void gen_s8subq (void) ! 619: { ! 620: gen_op_s8(); ! 621: gen_op_subq(); ! 622: } ! 623: ! 624: static always_inline void gen_amask (void) ! 625: { ! 626: gen_op_load_amask(); ! 627: gen_op_bic(); ! 628: } ! 629: ! 630: static always_inline int translate_one (DisasContext *ctx, uint32_t insn) ! 631: { ! 632: uint32_t palcode; ! 633: int32_t disp21, disp16, disp12; ! 634: uint16_t fn11, fn16; ! 635: uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit; ! 636: int8_t lit; ! 637: int ret; ! 638: ! 639: /* Decode all instruction fields */ ! 640: opc = insn >> 26; ! 641: ra = (insn >> 21) & 0x1F; ! 642: rb = (insn >> 16) & 0x1F; ! 643: rc = insn & 0x1F; ! 644: sbz = (insn >> 13) & 0x07; ! 645: islit = (insn >> 12) & 1; ! 646: lit = (insn >> 13) & 0xFF; ! 647: palcode = insn & 0x03FFFFFF; ! 648: disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11; ! 649: disp16 = (int16_t)(insn & 0x0000FFFF); ! 650: disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20; ! 651: fn16 = insn & 0x0000FFFF; ! 652: fn11 = (insn >> 5) & 0x000007FF; ! 653: fpfn = fn11 & 0x3F; ! 654: fn7 = (insn >> 5) & 0x0000007F; ! 655: fn2 = (insn >> 5) & 0x00000003; ! 656: ret = 0; ! 657: #if defined ALPHA_DEBUG_DISAS ! 658: if (logfile != NULL) { ! 659: fprintf(logfile, "opc %02x ra %d rb %d rc %d disp16 %04x\n", ! 660: opc, ra, rb, rc, disp16); ! 661: } ! 662: #endif ! 663: switch (opc) { ! 664: case 0x00: ! 665: /* CALL_PAL */ ! 666: if (palcode >= 0x80 && palcode < 0xC0) { ! 667: /* Unprivileged PAL call */ ! 668: gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x1F) << 6), 0); ! 669: #if !defined (CONFIG_USER_ONLY) ! 670: } else if (palcode < 0x40) { ! 671: /* Privileged PAL code */ ! 672: if (ctx->mem_idx & 1) ! 673: goto invalid_opc; ! 674: else ! 675: gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x1F) << 6), 0); ! 676: #endif ! 677: } else { ! 678: /* Invalid PAL call */ ! 679: goto invalid_opc; ! 680: } ! 681: ret = 3; ! 682: break; ! 683: case 0x01: ! 684: /* OPC01 */ ! 685: goto invalid_opc; ! 686: case 0x02: ! 687: /* OPC02 */ ! 688: goto invalid_opc; ! 689: case 0x03: ! 690: /* OPC03 */ ! 691: goto invalid_opc; ! 692: case 0x04: ! 693: /* OPC04 */ ! 694: goto invalid_opc; ! 695: case 0x05: ! 696: /* OPC05 */ ! 697: goto invalid_opc; ! 698: case 0x06: ! 699: /* OPC06 */ ! 700: goto invalid_opc; ! 701: case 0x07: ! 702: /* OPC07 */ ! 703: goto invalid_opc; ! 704: case 0x08: ! 705: /* LDA */ ! 706: gen_load_ir(ctx, rb, 0); ! 707: gen_set_sT1(ctx, disp16); ! 708: gen_op_addq(); ! 709: gen_store_ir(ctx, ra, 0); ! 710: break; ! 711: case 0x09: ! 712: /* LDAH */ ! 713: gen_load_ir(ctx, rb, 0); ! 714: gen_set_sT1(ctx, disp16 << 16); ! 715: gen_op_addq(); ! 716: gen_store_ir(ctx, ra, 0); ! 717: break; ! 718: case 0x0A: ! 719: /* LDBU */ ! 720: if (!(ctx->amask & AMASK_BWX)) ! 721: goto invalid_opc; ! 722: gen_load_mem(ctx, &gen_ldbu, ra, rb, disp16, 0); ! 723: break; ! 724: case 0x0B: ! 725: /* LDQ_U */ ! 726: gen_load_mem(ctx, &gen_ldq_u, ra, rb, disp16, 1); ! 727: break; ! 728: case 0x0C: ! 729: /* LDWU */ ! 730: if (!(ctx->amask & AMASK_BWX)) ! 731: goto invalid_opc; ! 732: gen_load_mem(ctx, &gen_ldwu, ra, rb, disp16, 0); ! 733: break; ! 734: case 0x0D: ! 735: /* STW */ ! 736: if (!(ctx->amask & AMASK_BWX)) ! 737: goto invalid_opc; ! 738: gen_store_mem(ctx, &gen_stw, ra, rb, disp16, 0); ! 739: break; ! 740: case 0x0E: ! 741: /* STB */ ! 742: if (!(ctx->amask & AMASK_BWX)) ! 743: goto invalid_opc; ! 744: gen_store_mem(ctx, &gen_stb, ra, rb, disp16, 0); ! 745: break; ! 746: case 0x0F: ! 747: /* STQ_U */ ! 748: gen_store_mem(ctx, &gen_stq_u, ra, rb, disp16, 1); ! 749: break; ! 750: case 0x10: ! 751: switch (fn7) { ! 752: case 0x00: ! 753: /* ADDL */ ! 754: gen_arith3(ctx, &gen_op_addl, ra, rb, rc, islit, lit); ! 755: break; ! 756: case 0x02: ! 757: /* S4ADDL */ ! 758: gen_arith3(ctx, &gen_s4addl, ra, rb, rc, islit, lit); ! 759: break; ! 760: case 0x09: ! 761: /* SUBL */ ! 762: gen_arith3(ctx, &gen_op_subl, ra, rb, rc, islit, lit); ! 763: break; ! 764: case 0x0B: ! 765: /* S4SUBL */ ! 766: gen_arith3(ctx, &gen_s4subl, ra, rb, rc, islit, lit); ! 767: break; ! 768: case 0x0F: ! 769: /* CMPBGE */ ! 770: gen_arith3(ctx, &gen_op_cmpbge, ra, rb, rc, islit, lit); ! 771: break; ! 772: case 0x12: ! 773: /* S8ADDL */ ! 774: gen_arith3(ctx, &gen_s8addl, ra, rb, rc, islit, lit); ! 775: break; ! 776: case 0x1B: ! 777: /* S8SUBL */ ! 778: gen_arith3(ctx, &gen_s8subl, ra, rb, rc, islit, lit); ! 779: break; ! 780: case 0x1D: ! 781: /* CMPULT */ ! 782: gen_arith3(ctx, &gen_op_cmpult, ra, rb, rc, islit, lit); ! 783: break; ! 784: case 0x20: ! 785: /* ADDQ */ ! 786: gen_arith3(ctx, &gen_op_addq, ra, rb, rc, islit, lit); ! 787: break; ! 788: case 0x22: ! 789: /* S4ADDQ */ ! 790: gen_arith3(ctx, &gen_s4addq, ra, rb, rc, islit, lit); ! 791: break; ! 792: case 0x29: ! 793: /* SUBQ */ ! 794: gen_arith3(ctx, &gen_op_subq, ra, rb, rc, islit, lit); ! 795: break; ! 796: case 0x2B: ! 797: /* S4SUBQ */ ! 798: gen_arith3(ctx, &gen_s4subq, ra, rb, rc, islit, lit); ! 799: break; ! 800: case 0x2D: ! 801: /* CMPEQ */ ! 802: gen_arith3(ctx, &gen_op_cmpeq, ra, rb, rc, islit, lit); ! 803: break; ! 804: case 0x32: ! 805: /* S8ADDQ */ ! 806: gen_arith3(ctx, &gen_s8addq, ra, rb, rc, islit, lit); ! 807: break; ! 808: case 0x3B: ! 809: /* S8SUBQ */ ! 810: gen_arith3(ctx, &gen_s8subq, ra, rb, rc, islit, lit); ! 811: break; ! 812: case 0x3D: ! 813: /* CMPULE */ ! 814: gen_arith3(ctx, &gen_op_cmpule, ra, rb, rc, islit, lit); ! 815: break; ! 816: case 0x40: ! 817: /* ADDL/V */ ! 818: gen_arith3(ctx, &gen_op_addlv, ra, rb, rc, islit, lit); ! 819: break; ! 820: case 0x49: ! 821: /* SUBL/V */ ! 822: gen_arith3(ctx, &gen_op_sublv, ra, rb, rc, islit, lit); ! 823: break; ! 824: case 0x4D: ! 825: /* CMPLT */ ! 826: gen_arith3(ctx, &gen_op_cmplt, ra, rb, rc, islit, lit); ! 827: break; ! 828: case 0x60: ! 829: /* ADDQ/V */ ! 830: gen_arith3(ctx, &gen_op_addqv, ra, rb, rc, islit, lit); ! 831: break; ! 832: case 0x69: ! 833: /* SUBQ/V */ ! 834: gen_arith3(ctx, &gen_op_subqv, ra, rb, rc, islit, lit); ! 835: break; ! 836: case 0x6D: ! 837: /* CMPLE */ ! 838: gen_arith3(ctx, &gen_op_cmple, ra, rb, rc, islit, lit); ! 839: break; ! 840: default: ! 841: goto invalid_opc; ! 842: } ! 843: break; ! 844: case 0x11: ! 845: switch (fn7) { ! 846: case 0x00: ! 847: /* AND */ ! 848: gen_arith3(ctx, &gen_op_and, ra, rb, rc, islit, lit); ! 849: break; ! 850: case 0x08: ! 851: /* BIC */ ! 852: gen_arith3(ctx, &gen_op_bic, ra, rb, rc, islit, lit); ! 853: break; ! 854: case 0x14: ! 855: /* CMOVLBS */ ! 856: gen_cmov(ctx, &gen_op_cmplbs, ra, rb, rc, islit, lit); ! 857: break; ! 858: case 0x16: ! 859: /* CMOVLBC */ ! 860: gen_cmov(ctx, &gen_op_cmplbc, ra, rb, rc, islit, lit); ! 861: break; ! 862: case 0x20: ! 863: /* BIS */ ! 864: if (ra == rb || ra == 31 || rb == 31) { ! 865: if (ra == 31 && rc == 31) { ! 866: /* NOP */ ! 867: gen_op_nop(); ! 868: } else { ! 869: /* MOV */ ! 870: gen_load_ir(ctx, rb, 0); ! 871: gen_store_ir(ctx, rc, 0); ! 872: } ! 873: } else { ! 874: gen_arith3(ctx, &gen_op_bis, ra, rb, rc, islit, lit); ! 875: } ! 876: break; ! 877: case 0x24: ! 878: /* CMOVEQ */ ! 879: gen_cmov(ctx, &gen_op_cmpeqz, ra, rb, rc, islit, lit); ! 880: break; ! 881: case 0x26: ! 882: /* CMOVNE */ ! 883: gen_cmov(ctx, &gen_op_cmpnez, ra, rb, rc, islit, lit); ! 884: break; ! 885: case 0x28: ! 886: /* ORNOT */ ! 887: gen_arith3(ctx, &gen_op_ornot, ra, rb, rc, islit, lit); ! 888: break; ! 889: case 0x40: ! 890: /* XOR */ ! 891: gen_arith3(ctx, &gen_op_xor, ra, rb, rc, islit, lit); ! 892: break; ! 893: case 0x44: ! 894: /* CMOVLT */ ! 895: gen_cmov(ctx, &gen_op_cmpltz, ra, rb, rc, islit, lit); ! 896: break; ! 897: case 0x46: ! 898: /* CMOVGE */ ! 899: gen_cmov(ctx, &gen_op_cmpgez, ra, rb, rc, islit, lit); ! 900: break; ! 901: case 0x48: ! 902: /* EQV */ ! 903: gen_arith3(ctx, &gen_op_eqv, ra, rb, rc, islit, lit); ! 904: break; ! 905: case 0x61: ! 906: /* AMASK */ ! 907: gen_arith2(ctx, &gen_amask, rb, rc, islit, lit); ! 908: break; ! 909: case 0x64: ! 910: /* CMOVLE */ ! 911: gen_cmov(ctx, &gen_op_cmplez, ra, rb, rc, islit, lit); ! 912: break; ! 913: case 0x66: ! 914: /* CMOVGT */ ! 915: gen_cmov(ctx, &gen_op_cmpgtz, ra, rb, rc, islit, lit); ! 916: break; ! 917: case 0x6C: ! 918: /* IMPLVER */ ! 919: gen_op_load_implver(); ! 920: gen_store_ir(ctx, rc, 0); ! 921: break; ! 922: default: ! 923: goto invalid_opc; ! 924: } ! 925: break; ! 926: case 0x12: ! 927: switch (fn7) { ! 928: case 0x02: ! 929: /* MSKBL */ ! 930: gen_arith3(ctx, &gen_op_mskbl, ra, rb, rc, islit, lit); ! 931: break; ! 932: case 0x06: ! 933: /* EXTBL */ ! 934: gen_arith3(ctx, &gen_op_extbl, ra, rb, rc, islit, lit); ! 935: break; ! 936: case 0x0B: ! 937: /* INSBL */ ! 938: gen_arith3(ctx, &gen_op_insbl, ra, rb, rc, islit, lit); ! 939: break; ! 940: case 0x12: ! 941: /* MSKWL */ ! 942: gen_arith3(ctx, &gen_op_mskwl, ra, rb, rc, islit, lit); ! 943: break; ! 944: case 0x16: ! 945: /* EXTWL */ ! 946: gen_arith3(ctx, &gen_op_extwl, ra, rb, rc, islit, lit); ! 947: break; ! 948: case 0x1B: ! 949: /* INSWL */ ! 950: gen_arith3(ctx, &gen_op_inswl, ra, rb, rc, islit, lit); ! 951: break; ! 952: case 0x22: ! 953: /* MSKLL */ ! 954: gen_arith3(ctx, &gen_op_mskll, ra, rb, rc, islit, lit); ! 955: break; ! 956: case 0x26: ! 957: /* EXTLL */ ! 958: gen_arith3(ctx, &gen_op_extll, ra, rb, rc, islit, lit); ! 959: break; ! 960: case 0x2B: ! 961: /* INSLL */ ! 962: gen_arith3(ctx, &gen_op_insll, ra, rb, rc, islit, lit); ! 963: break; ! 964: case 0x30: ! 965: /* ZAP */ ! 966: gen_arith3(ctx, &gen_op_zap, ra, rb, rc, islit, lit); ! 967: break; ! 968: case 0x31: ! 969: /* ZAPNOT */ ! 970: gen_arith3(ctx, &gen_op_zapnot, ra, rb, rc, islit, lit); ! 971: break; ! 972: case 0x32: ! 973: /* MSKQL */ ! 974: gen_arith3(ctx, &gen_op_mskql, ra, rb, rc, islit, lit); ! 975: break; ! 976: case 0x34: ! 977: /* SRL */ ! 978: gen_arith3(ctx, &gen_op_srl, ra, rb, rc, islit, lit); ! 979: break; ! 980: case 0x36: ! 981: /* EXTQL */ ! 982: gen_arith3(ctx, &gen_op_extql, ra, rb, rc, islit, lit); ! 983: break; ! 984: case 0x39: ! 985: /* SLL */ ! 986: gen_arith3(ctx, &gen_op_sll, ra, rb, rc, islit, lit); ! 987: break; ! 988: case 0x3B: ! 989: /* INSQL */ ! 990: gen_arith3(ctx, &gen_op_insql, ra, rb, rc, islit, lit); ! 991: break; ! 992: case 0x3C: ! 993: /* SRA */ ! 994: gen_arith3(ctx, &gen_op_sra, ra, rb, rc, islit, lit); ! 995: break; ! 996: case 0x52: ! 997: /* MSKWH */ ! 998: gen_arith3(ctx, &gen_op_mskwh, ra, rb, rc, islit, lit); ! 999: break; ! 1000: case 0x57: ! 1001: /* INSWH */ ! 1002: gen_arith3(ctx, &gen_op_inswh, ra, rb, rc, islit, lit); ! 1003: break; ! 1004: case 0x5A: ! 1005: /* EXTWH */ ! 1006: gen_arith3(ctx, &gen_op_extwh, ra, rb, rc, islit, lit); ! 1007: break; ! 1008: case 0x62: ! 1009: /* MSKLH */ ! 1010: gen_arith3(ctx, &gen_op_msklh, ra, rb, rc, islit, lit); ! 1011: break; ! 1012: case 0x67: ! 1013: /* INSLH */ ! 1014: gen_arith3(ctx, &gen_op_inslh, ra, rb, rc, islit, lit); ! 1015: break; ! 1016: case 0x6A: ! 1017: /* EXTLH */ ! 1018: gen_arith3(ctx, &gen_op_extlh, ra, rb, rc, islit, lit); ! 1019: break; ! 1020: case 0x72: ! 1021: /* MSKQH */ ! 1022: gen_arith3(ctx, &gen_op_mskqh, ra, rb, rc, islit, lit); ! 1023: break; ! 1024: case 0x77: ! 1025: /* INSQH */ ! 1026: gen_arith3(ctx, &gen_op_insqh, ra, rb, rc, islit, lit); ! 1027: break; ! 1028: case 0x7A: ! 1029: /* EXTQH */ ! 1030: gen_arith3(ctx, &gen_op_extqh, ra, rb, rc, islit, lit); ! 1031: break; ! 1032: default: ! 1033: goto invalid_opc; ! 1034: } ! 1035: break; ! 1036: case 0x13: ! 1037: switch (fn7) { ! 1038: case 0x00: ! 1039: /* MULL */ ! 1040: gen_arith3(ctx, &gen_op_mull, ra, rb, rc, islit, lit); ! 1041: break; ! 1042: case 0x20: ! 1043: /* MULQ */ ! 1044: gen_arith3(ctx, &gen_op_mulq, ra, rb, rc, islit, lit); ! 1045: break; ! 1046: case 0x30: ! 1047: /* UMULH */ ! 1048: gen_arith3(ctx, &gen_op_umulh, ra, rb, rc, islit, lit); ! 1049: break; ! 1050: case 0x40: ! 1051: /* MULL/V */ ! 1052: gen_arith3(ctx, &gen_op_mullv, ra, rb, rc, islit, lit); ! 1053: break; ! 1054: case 0x60: ! 1055: /* MULQ/V */ ! 1056: gen_arith3(ctx, &gen_op_mulqv, ra, rb, rc, islit, lit); ! 1057: break; ! 1058: default: ! 1059: goto invalid_opc; ! 1060: } ! 1061: break; ! 1062: case 0x14: ! 1063: switch (fpfn) { /* f11 & 0x3F */ ! 1064: case 0x04: ! 1065: /* ITOFS */ ! 1066: if (!(ctx->amask & AMASK_FIX)) ! 1067: goto invalid_opc; ! 1068: gen_itf(ctx, &gen_op_itofs, ra, rc); ! 1069: break; ! 1070: case 0x0A: ! 1071: /* SQRTF */ ! 1072: if (!(ctx->amask & AMASK_FIX)) ! 1073: goto invalid_opc; ! 1074: gen_farith2(ctx, &gen_op_sqrtf, rb, rc); ! 1075: break; ! 1076: case 0x0B: ! 1077: /* SQRTS */ ! 1078: if (!(ctx->amask & AMASK_FIX)) ! 1079: goto invalid_opc; ! 1080: gen_farith2(ctx, &gen_op_sqrts, rb, rc); ! 1081: break; ! 1082: case 0x14: ! 1083: /* ITOFF */ ! 1084: if (!(ctx->amask & AMASK_FIX)) ! 1085: goto invalid_opc; ! 1086: #if 0 // TODO ! 1087: gen_itf(ctx, &gen_op_itoff, ra, rc); ! 1088: #else ! 1089: goto invalid_opc; ! 1090: #endif ! 1091: break; ! 1092: case 0x24: ! 1093: /* ITOFT */ ! 1094: if (!(ctx->amask & AMASK_FIX)) ! 1095: goto invalid_opc; ! 1096: gen_itf(ctx, &gen_op_itoft, ra, rc); ! 1097: break; ! 1098: case 0x2A: ! 1099: /* SQRTG */ ! 1100: if (!(ctx->amask & AMASK_FIX)) ! 1101: goto invalid_opc; ! 1102: gen_farith2(ctx, &gen_op_sqrtg, rb, rc); ! 1103: break; ! 1104: case 0x02B: ! 1105: /* SQRTT */ ! 1106: if (!(ctx->amask & AMASK_FIX)) ! 1107: goto invalid_opc; ! 1108: gen_farith2(ctx, &gen_op_sqrtt, rb, rc); ! 1109: break; ! 1110: default: ! 1111: goto invalid_opc; ! 1112: } ! 1113: break; ! 1114: case 0x15: ! 1115: /* VAX floating point */ ! 1116: /* XXX: rounding mode and trap are ignored (!) */ ! 1117: switch (fpfn) { /* f11 & 0x3F */ ! 1118: case 0x00: ! 1119: /* ADDF */ ! 1120: gen_farith3(ctx, &gen_op_addf, ra, rb, rc); ! 1121: break; ! 1122: case 0x01: ! 1123: /* SUBF */ ! 1124: gen_farith3(ctx, &gen_op_subf, ra, rb, rc); ! 1125: break; ! 1126: case 0x02: ! 1127: /* MULF */ ! 1128: gen_farith3(ctx, &gen_op_mulf, ra, rb, rc); ! 1129: break; ! 1130: case 0x03: ! 1131: /* DIVF */ ! 1132: gen_farith3(ctx, &gen_op_divf, ra, rb, rc); ! 1133: break; ! 1134: case 0x1E: ! 1135: /* CVTDG */ ! 1136: #if 0 // TODO ! 1137: gen_farith2(ctx, &gen_op_cvtdg, rb, rc); ! 1138: #else ! 1139: goto invalid_opc; ! 1140: #endif ! 1141: break; ! 1142: case 0x20: ! 1143: /* ADDG */ ! 1144: gen_farith3(ctx, &gen_op_addg, ra, rb, rc); ! 1145: break; ! 1146: case 0x21: ! 1147: /* SUBG */ ! 1148: gen_farith3(ctx, &gen_op_subg, ra, rb, rc); ! 1149: break; ! 1150: case 0x22: ! 1151: /* MULG */ ! 1152: gen_farith3(ctx, &gen_op_mulg, ra, rb, rc); ! 1153: break; ! 1154: case 0x23: ! 1155: /* DIVG */ ! 1156: gen_farith3(ctx, &gen_op_divg, ra, rb, rc); ! 1157: break; ! 1158: case 0x25: ! 1159: /* CMPGEQ */ ! 1160: gen_farith3(ctx, &gen_op_cmpgeq, ra, rb, rc); ! 1161: break; ! 1162: case 0x26: ! 1163: /* CMPGLT */ ! 1164: gen_farith3(ctx, &gen_op_cmpglt, ra, rb, rc); ! 1165: break; ! 1166: case 0x27: ! 1167: /* CMPGLE */ ! 1168: gen_farith3(ctx, &gen_op_cmpgle, ra, rb, rc); ! 1169: break; ! 1170: case 0x2C: ! 1171: /* CVTGF */ ! 1172: gen_farith2(ctx, &gen_op_cvtgf, rb, rc); ! 1173: break; ! 1174: case 0x2D: ! 1175: /* CVTGD */ ! 1176: #if 0 // TODO ! 1177: gen_farith2(ctx, &gen_op_cvtgd, rb, rc); ! 1178: #else ! 1179: goto invalid_opc; ! 1180: #endif ! 1181: break; ! 1182: case 0x2F: ! 1183: /* CVTGQ */ ! 1184: gen_farith2(ctx, &gen_op_cvtgq, rb, rc); ! 1185: break; ! 1186: case 0x3C: ! 1187: /* CVTQF */ ! 1188: gen_farith2(ctx, &gen_op_cvtqf, rb, rc); ! 1189: break; ! 1190: case 0x3E: ! 1191: /* CVTQG */ ! 1192: gen_farith2(ctx, &gen_op_cvtqg, rb, rc); ! 1193: break; ! 1194: default: ! 1195: goto invalid_opc; ! 1196: } ! 1197: break; ! 1198: case 0x16: ! 1199: /* IEEE floating-point */ ! 1200: /* XXX: rounding mode and traps are ignored (!) */ ! 1201: switch (fpfn) { /* f11 & 0x3F */ ! 1202: case 0x00: ! 1203: /* ADDS */ ! 1204: gen_farith3(ctx, &gen_op_adds, ra, rb, rc); ! 1205: break; ! 1206: case 0x01: ! 1207: /* SUBS */ ! 1208: gen_farith3(ctx, &gen_op_subs, ra, rb, rc); ! 1209: break; ! 1210: case 0x02: ! 1211: /* MULS */ ! 1212: gen_farith3(ctx, &gen_op_muls, ra, rb, rc); ! 1213: break; ! 1214: case 0x03: ! 1215: /* DIVS */ ! 1216: gen_farith3(ctx, &gen_op_divs, ra, rb, rc); ! 1217: break; ! 1218: case 0x20: ! 1219: /* ADDT */ ! 1220: gen_farith3(ctx, &gen_op_addt, ra, rb, rc); ! 1221: break; ! 1222: case 0x21: ! 1223: /* SUBT */ ! 1224: gen_farith3(ctx, &gen_op_subt, ra, rb, rc); ! 1225: break; ! 1226: case 0x22: ! 1227: /* MULT */ ! 1228: gen_farith3(ctx, &gen_op_mult, ra, rb, rc); ! 1229: break; ! 1230: case 0x23: ! 1231: /* DIVT */ ! 1232: gen_farith3(ctx, &gen_op_divt, ra, rb, rc); ! 1233: break; ! 1234: case 0x24: ! 1235: /* CMPTUN */ ! 1236: gen_farith3(ctx, &gen_op_cmptun, ra, rb, rc); ! 1237: break; ! 1238: case 0x25: ! 1239: /* CMPTEQ */ ! 1240: gen_farith3(ctx, &gen_op_cmpteq, ra, rb, rc); ! 1241: break; ! 1242: case 0x26: ! 1243: /* CMPTLT */ ! 1244: gen_farith3(ctx, &gen_op_cmptlt, ra, rb, rc); ! 1245: break; ! 1246: case 0x27: ! 1247: /* CMPTLE */ ! 1248: gen_farith3(ctx, &gen_op_cmptle, ra, rb, rc); ! 1249: break; ! 1250: case 0x2C: ! 1251: /* XXX: incorrect */ ! 1252: if (fn11 == 0x2AC) { ! 1253: /* CVTST */ ! 1254: gen_farith2(ctx, &gen_op_cvtst, rb, rc); ! 1255: } else { ! 1256: /* CVTTS */ ! 1257: gen_farith2(ctx, &gen_op_cvtts, rb, rc); ! 1258: } ! 1259: break; ! 1260: case 0x2F: ! 1261: /* CVTTQ */ ! 1262: gen_farith2(ctx, &gen_op_cvttq, rb, rc); ! 1263: break; ! 1264: case 0x3C: ! 1265: /* CVTQS */ ! 1266: gen_farith2(ctx, &gen_op_cvtqs, rb, rc); ! 1267: break; ! 1268: case 0x3E: ! 1269: /* CVTQT */ ! 1270: gen_farith2(ctx, &gen_op_cvtqt, rb, rc); ! 1271: break; ! 1272: default: ! 1273: goto invalid_opc; ! 1274: } ! 1275: break; ! 1276: case 0x17: ! 1277: switch (fn11) { ! 1278: case 0x010: ! 1279: /* CVTLQ */ ! 1280: gen_farith2(ctx, &gen_op_cvtlq, rb, rc); ! 1281: break; ! 1282: case 0x020: ! 1283: /* CPYS */ ! 1284: if (ra == rb) { ! 1285: if (ra == 31 && rc == 31) { ! 1286: /* FNOP */ ! 1287: gen_op_nop(); ! 1288: } else { ! 1289: /* FMOV */ ! 1290: gen_load_fir(ctx, rb, 0); ! 1291: gen_store_fir(ctx, rc, 0); ! 1292: } ! 1293: } else { ! 1294: gen_farith3(ctx, &gen_op_cpys, ra, rb, rc); ! 1295: } ! 1296: break; ! 1297: case 0x021: ! 1298: /* CPYSN */ ! 1299: gen_farith2(ctx, &gen_op_cpysn, rb, rc); ! 1300: break; ! 1301: case 0x022: ! 1302: /* CPYSE */ ! 1303: gen_farith2(ctx, &gen_op_cpyse, rb, rc); ! 1304: break; ! 1305: case 0x024: ! 1306: /* MT_FPCR */ ! 1307: gen_load_fir(ctx, ra, 0); ! 1308: gen_op_store_fpcr(); ! 1309: break; ! 1310: case 0x025: ! 1311: /* MF_FPCR */ ! 1312: gen_op_load_fpcr(); ! 1313: gen_store_fir(ctx, ra, 0); ! 1314: break; ! 1315: case 0x02A: ! 1316: /* FCMOVEQ */ ! 1317: gen_fcmov(ctx, &gen_op_cmpfeq, ra, rb, rc); ! 1318: break; ! 1319: case 0x02B: ! 1320: /* FCMOVNE */ ! 1321: gen_fcmov(ctx, &gen_op_cmpfne, ra, rb, rc); ! 1322: break; ! 1323: case 0x02C: ! 1324: /* FCMOVLT */ ! 1325: gen_fcmov(ctx, &gen_op_cmpflt, ra, rb, rc); ! 1326: break; ! 1327: case 0x02D: ! 1328: /* FCMOVGE */ ! 1329: gen_fcmov(ctx, &gen_op_cmpfge, ra, rb, rc); ! 1330: break; ! 1331: case 0x02E: ! 1332: /* FCMOVLE */ ! 1333: gen_fcmov(ctx, &gen_op_cmpfle, ra, rb, rc); ! 1334: break; ! 1335: case 0x02F: ! 1336: /* FCMOVGT */ ! 1337: gen_fcmov(ctx, &gen_op_cmpfgt, ra, rb, rc); ! 1338: break; ! 1339: case 0x030: ! 1340: /* CVTQL */ ! 1341: gen_farith2(ctx, &gen_op_cvtql, rb, rc); ! 1342: break; ! 1343: case 0x130: ! 1344: /* CVTQL/V */ ! 1345: gen_farith2(ctx, &gen_op_cvtqlv, rb, rc); ! 1346: break; ! 1347: case 0x530: ! 1348: /* CVTQL/SV */ ! 1349: gen_farith2(ctx, &gen_op_cvtqlsv, rb, rc); ! 1350: break; ! 1351: default: ! 1352: goto invalid_opc; ! 1353: } ! 1354: break; ! 1355: case 0x18: ! 1356: switch ((uint16_t)disp16) { ! 1357: case 0x0000: ! 1358: /* TRAPB */ ! 1359: /* No-op. Just exit from the current tb */ ! 1360: ret = 2; ! 1361: break; ! 1362: case 0x0400: ! 1363: /* EXCB */ ! 1364: /* No-op. Just exit from the current tb */ ! 1365: ret = 2; ! 1366: break; ! 1367: case 0x4000: ! 1368: /* MB */ ! 1369: /* No-op */ ! 1370: break; ! 1371: case 0x4400: ! 1372: /* WMB */ ! 1373: /* No-op */ ! 1374: break; ! 1375: case 0x8000: ! 1376: /* FETCH */ ! 1377: /* No-op */ ! 1378: break; ! 1379: case 0xA000: ! 1380: /* FETCH_M */ ! 1381: /* No-op */ ! 1382: break; ! 1383: case 0xC000: ! 1384: /* RPCC */ ! 1385: gen_op_load_pcc(); ! 1386: gen_store_ir(ctx, ra, 0); ! 1387: break; ! 1388: case 0xE000: ! 1389: /* RC */ ! 1390: gen_op_load_irf(); ! 1391: gen_store_ir(ctx, ra, 0); ! 1392: gen_op_clear_irf(); ! 1393: break; ! 1394: case 0xE800: ! 1395: /* ECB */ ! 1396: /* XXX: TODO: evict tb cache at address rb */ ! 1397: #if 0 ! 1398: ret = 2; ! 1399: #else ! 1400: goto invalid_opc; ! 1401: #endif ! 1402: break; ! 1403: case 0xF000: ! 1404: /* RS */ ! 1405: gen_op_load_irf(); ! 1406: gen_store_ir(ctx, ra, 0); ! 1407: gen_op_set_irf(); ! 1408: break; ! 1409: case 0xF800: ! 1410: /* WH64 */ ! 1411: /* No-op */ ! 1412: break; ! 1413: default: ! 1414: goto invalid_opc; ! 1415: } ! 1416: break; ! 1417: case 0x19: ! 1418: /* HW_MFPR (PALcode) */ ! 1419: #if defined (CONFIG_USER_ONLY) ! 1420: goto invalid_opc; ! 1421: #else ! 1422: if (!ctx->pal_mode) ! 1423: goto invalid_opc; ! 1424: gen_op_mfpr(insn & 0xFF); ! 1425: gen_store_ir(ctx, ra, 0); ! 1426: break; ! 1427: #endif ! 1428: case 0x1A: ! 1429: gen_load_ir(ctx, rb, 0); ! 1430: if (ra != 31) { ! 1431: gen_set_uT1(ctx, ctx->pc); ! 1432: gen_store_ir(ctx, ra, 1); ! 1433: } ! 1434: gen_op_branch(); ! 1435: /* Those four jumps only differ by the branch prediction hint */ ! 1436: switch (fn2) { ! 1437: case 0x0: ! 1438: /* JMP */ ! 1439: break; ! 1440: case 0x1: ! 1441: /* JSR */ ! 1442: break; ! 1443: case 0x2: ! 1444: /* RET */ ! 1445: break; ! 1446: case 0x3: ! 1447: /* JSR_COROUTINE */ ! 1448: break; ! 1449: } ! 1450: ret = 1; ! 1451: break; ! 1452: case 0x1B: ! 1453: /* HW_LD (PALcode) */ ! 1454: #if defined (CONFIG_USER_ONLY) ! 1455: goto invalid_opc; ! 1456: #else ! 1457: if (!ctx->pal_mode) ! 1458: goto invalid_opc; ! 1459: gen_load_ir(ctx, rb, 0); ! 1460: gen_set_sT1(ctx, disp12); ! 1461: gen_op_addq(); ! 1462: switch ((insn >> 12) & 0xF) { ! 1463: case 0x0: ! 1464: /* Longword physical access */ ! 1465: gen_op_ldl_raw(); ! 1466: break; ! 1467: case 0x1: ! 1468: /* Quadword physical access */ ! 1469: gen_op_ldq_raw(); ! 1470: break; ! 1471: case 0x2: ! 1472: /* Longword physical access with lock */ ! 1473: gen_op_ldl_l_raw(); ! 1474: break; ! 1475: case 0x3: ! 1476: /* Quadword physical access with lock */ ! 1477: gen_op_ldq_l_raw(); ! 1478: break; ! 1479: case 0x4: ! 1480: /* Longword virtual PTE fetch */ ! 1481: gen_op_ldl_kernel(); ! 1482: break; ! 1483: case 0x5: ! 1484: /* Quadword virtual PTE fetch */ ! 1485: gen_op_ldq_kernel(); ! 1486: break; ! 1487: case 0x6: ! 1488: /* Invalid */ ! 1489: goto invalid_opc; ! 1490: case 0x7: ! 1491: /* Invalid */ ! 1492: goto invalid_opc; ! 1493: case 0x8: ! 1494: /* Longword virtual access */ ! 1495: gen_op_ld_phys_to_virt(); ! 1496: gen_op_ldl_raw(); ! 1497: break; ! 1498: case 0x9: ! 1499: /* Quadword virtual access */ ! 1500: gen_op_ld_phys_to_virt(); ! 1501: gen_op_ldq_raw(); ! 1502: break; ! 1503: case 0xA: ! 1504: /* Longword virtual access with protection check */ ! 1505: gen_ldl(ctx); ! 1506: break; ! 1507: case 0xB: ! 1508: /* Quadword virtual access with protection check */ ! 1509: gen_ldq(ctx); ! 1510: break; ! 1511: case 0xC: ! 1512: /* Longword virtual access with altenate access mode */ ! 1513: gen_op_set_alt_mode(); ! 1514: gen_op_ld_phys_to_virt(); ! 1515: gen_op_ldl_raw(); ! 1516: gen_op_restore_mode(); ! 1517: break; ! 1518: case 0xD: ! 1519: /* Quadword virtual access with altenate access mode */ ! 1520: gen_op_set_alt_mode(); ! 1521: gen_op_ld_phys_to_virt(); ! 1522: gen_op_ldq_raw(); ! 1523: gen_op_restore_mode(); ! 1524: break; ! 1525: case 0xE: ! 1526: /* Longword virtual access with alternate access mode and ! 1527: * protection checks ! 1528: */ ! 1529: gen_op_set_alt_mode(); ! 1530: gen_op_ldl_data(); ! 1531: gen_op_restore_mode(); ! 1532: break; ! 1533: case 0xF: ! 1534: /* Quadword virtual access with alternate access mode and ! 1535: * protection checks ! 1536: */ ! 1537: gen_op_set_alt_mode(); ! 1538: gen_op_ldq_data(); ! 1539: gen_op_restore_mode(); ! 1540: break; ! 1541: } ! 1542: gen_store_ir(ctx, ra, 1); ! 1543: break; ! 1544: #endif ! 1545: case 0x1C: ! 1546: switch (fn7) { ! 1547: case 0x00: ! 1548: /* SEXTB */ ! 1549: if (!(ctx->amask & AMASK_BWX)) ! 1550: goto invalid_opc; ! 1551: gen_arith2(ctx, &gen_op_sextb, rb, rc, islit, lit); ! 1552: break; ! 1553: case 0x01: ! 1554: /* SEXTW */ ! 1555: if (!(ctx->amask & AMASK_BWX)) ! 1556: goto invalid_opc; ! 1557: gen_arith2(ctx, &gen_op_sextw, rb, rc, islit, lit); ! 1558: break; ! 1559: case 0x30: ! 1560: /* CTPOP */ ! 1561: if (!(ctx->amask & AMASK_CIX)) ! 1562: goto invalid_opc; ! 1563: gen_arith2(ctx, &gen_op_ctpop, rb, rc, 0, 0); ! 1564: break; ! 1565: case 0x31: ! 1566: /* PERR */ ! 1567: if (!(ctx->amask & AMASK_MVI)) ! 1568: goto invalid_opc; ! 1569: /* XXX: TODO */ ! 1570: goto invalid_opc; ! 1571: break; ! 1572: case 0x32: ! 1573: /* CTLZ */ ! 1574: if (!(ctx->amask & AMASK_CIX)) ! 1575: goto invalid_opc; ! 1576: gen_arith2(ctx, &gen_op_ctlz, rb, rc, 0, 0); ! 1577: break; ! 1578: case 0x33: ! 1579: /* CTTZ */ ! 1580: if (!(ctx->amask & AMASK_CIX)) ! 1581: goto invalid_opc; ! 1582: gen_arith2(ctx, &gen_op_cttz, rb, rc, 0, 0); ! 1583: break; ! 1584: case 0x34: ! 1585: /* UNPKBW */ ! 1586: if (!(ctx->amask & AMASK_MVI)) ! 1587: goto invalid_opc; ! 1588: /* XXX: TODO */ ! 1589: goto invalid_opc; ! 1590: break; ! 1591: case 0x35: ! 1592: /* UNPKWL */ ! 1593: if (!(ctx->amask & AMASK_MVI)) ! 1594: goto invalid_opc; ! 1595: /* XXX: TODO */ ! 1596: goto invalid_opc; ! 1597: break; ! 1598: case 0x36: ! 1599: /* PKWB */ ! 1600: if (!(ctx->amask & AMASK_MVI)) ! 1601: goto invalid_opc; ! 1602: /* XXX: TODO */ ! 1603: goto invalid_opc; ! 1604: break; ! 1605: case 0x37: ! 1606: /* PKLB */ ! 1607: if (!(ctx->amask & AMASK_MVI)) ! 1608: goto invalid_opc; ! 1609: /* XXX: TODO */ ! 1610: goto invalid_opc; ! 1611: break; ! 1612: case 0x38: ! 1613: /* MINSB8 */ ! 1614: if (!(ctx->amask & AMASK_MVI)) ! 1615: goto invalid_opc; ! 1616: /* XXX: TODO */ ! 1617: goto invalid_opc; ! 1618: break; ! 1619: case 0x39: ! 1620: /* MINSW4 */ ! 1621: if (!(ctx->amask & AMASK_MVI)) ! 1622: goto invalid_opc; ! 1623: /* XXX: TODO */ ! 1624: goto invalid_opc; ! 1625: break; ! 1626: case 0x3A: ! 1627: /* MINUB8 */ ! 1628: if (!(ctx->amask & AMASK_MVI)) ! 1629: goto invalid_opc; ! 1630: /* XXX: TODO */ ! 1631: goto invalid_opc; ! 1632: break; ! 1633: case 0x3B: ! 1634: /* MINUW4 */ ! 1635: if (!(ctx->amask & AMASK_MVI)) ! 1636: goto invalid_opc; ! 1637: /* XXX: TODO */ ! 1638: goto invalid_opc; ! 1639: break; ! 1640: case 0x3C: ! 1641: /* MAXUB8 */ ! 1642: if (!(ctx->amask & AMASK_MVI)) ! 1643: goto invalid_opc; ! 1644: /* XXX: TODO */ ! 1645: goto invalid_opc; ! 1646: break; ! 1647: case 0x3D: ! 1648: /* MAXUW4 */ ! 1649: if (!(ctx->amask & AMASK_MVI)) ! 1650: goto invalid_opc; ! 1651: /* XXX: TODO */ ! 1652: goto invalid_opc; ! 1653: break; ! 1654: case 0x3E: ! 1655: /* MAXSB8 */ ! 1656: if (!(ctx->amask & AMASK_MVI)) ! 1657: goto invalid_opc; ! 1658: /* XXX: TODO */ ! 1659: goto invalid_opc; ! 1660: break; ! 1661: case 0x3F: ! 1662: /* MAXSW4 */ ! 1663: if (!(ctx->amask & AMASK_MVI)) ! 1664: goto invalid_opc; ! 1665: /* XXX: TODO */ ! 1666: goto invalid_opc; ! 1667: break; ! 1668: case 0x70: ! 1669: /* FTOIT */ ! 1670: if (!(ctx->amask & AMASK_FIX)) ! 1671: goto invalid_opc; ! 1672: gen_fti(ctx, &gen_op_ftoit, ra, rb); ! 1673: break; ! 1674: case 0x78: ! 1675: /* FTOIS */ ! 1676: if (!(ctx->amask & AMASK_FIX)) ! 1677: goto invalid_opc; ! 1678: gen_fti(ctx, &gen_op_ftois, ra, rb); ! 1679: break; ! 1680: default: ! 1681: goto invalid_opc; ! 1682: } ! 1683: break; ! 1684: case 0x1D: ! 1685: /* HW_MTPR (PALcode) */ ! 1686: #if defined (CONFIG_USER_ONLY) ! 1687: goto invalid_opc; ! 1688: #else ! 1689: if (!ctx->pal_mode) ! 1690: goto invalid_opc; ! 1691: gen_load_ir(ctx, ra, 0); ! 1692: gen_op_mtpr(insn & 0xFF); ! 1693: ret = 2; ! 1694: break; ! 1695: #endif ! 1696: case 0x1E: ! 1697: /* HW_REI (PALcode) */ ! 1698: #if defined (CONFIG_USER_ONLY) ! 1699: goto invalid_opc; ! 1700: #else ! 1701: if (!ctx->pal_mode) ! 1702: goto invalid_opc; ! 1703: if (rb == 31) { ! 1704: /* "Old" alpha */ ! 1705: gen_op_hw_rei(); ! 1706: } else { ! 1707: gen_load_ir(ctx, rb, 0); ! 1708: gen_set_uT1(ctx, (((int64_t)insn << 51) >> 51)); ! 1709: gen_op_addq(); ! 1710: gen_op_hw_ret(); ! 1711: } ! 1712: ret = 2; ! 1713: break; ! 1714: #endif ! 1715: case 0x1F: ! 1716: /* HW_ST (PALcode) */ ! 1717: #if defined (CONFIG_USER_ONLY) ! 1718: goto invalid_opc; ! 1719: #else ! 1720: if (!ctx->pal_mode) ! 1721: goto invalid_opc; ! 1722: gen_load_ir(ctx, rb, 0); ! 1723: gen_set_sT1(ctx, disp12); ! 1724: gen_op_addq(); ! 1725: gen_load_ir(ctx, ra, 1); ! 1726: switch ((insn >> 12) & 0xF) { ! 1727: case 0x0: ! 1728: /* Longword physical access */ ! 1729: gen_op_stl_raw(); ! 1730: break; ! 1731: case 0x1: ! 1732: /* Quadword physical access */ ! 1733: gen_op_stq_raw(); ! 1734: break; ! 1735: case 0x2: ! 1736: /* Longword physical access with lock */ ! 1737: gen_op_stl_c_raw(); ! 1738: break; ! 1739: case 0x3: ! 1740: /* Quadword physical access with lock */ ! 1741: gen_op_stq_c_raw(); ! 1742: break; ! 1743: case 0x4: ! 1744: /* Longword virtual access */ ! 1745: gen_op_st_phys_to_virt(); ! 1746: gen_op_stl_raw(); ! 1747: break; ! 1748: case 0x5: ! 1749: /* Quadword virtual access */ ! 1750: gen_op_st_phys_to_virt(); ! 1751: gen_op_stq_raw(); ! 1752: break; ! 1753: case 0x6: ! 1754: /* Invalid */ ! 1755: goto invalid_opc; ! 1756: case 0x7: ! 1757: /* Invalid */ ! 1758: goto invalid_opc; ! 1759: case 0x8: ! 1760: /* Invalid */ ! 1761: goto invalid_opc; ! 1762: case 0x9: ! 1763: /* Invalid */ ! 1764: goto invalid_opc; ! 1765: case 0xA: ! 1766: /* Invalid */ ! 1767: goto invalid_opc; ! 1768: case 0xB: ! 1769: /* Invalid */ ! 1770: goto invalid_opc; ! 1771: case 0xC: ! 1772: /* Longword virtual access with alternate access mode */ ! 1773: gen_op_set_alt_mode(); ! 1774: gen_op_st_phys_to_virt(); ! 1775: gen_op_ldl_raw(); ! 1776: gen_op_restore_mode(); ! 1777: break; ! 1778: case 0xD: ! 1779: /* Quadword virtual access with alternate access mode */ ! 1780: gen_op_set_alt_mode(); ! 1781: gen_op_st_phys_to_virt(); ! 1782: gen_op_ldq_raw(); ! 1783: gen_op_restore_mode(); ! 1784: break; ! 1785: case 0xE: ! 1786: /* Invalid */ ! 1787: goto invalid_opc; ! 1788: case 0xF: ! 1789: /* Invalid */ ! 1790: goto invalid_opc; ! 1791: } ! 1792: ret = 2; ! 1793: break; ! 1794: #endif ! 1795: case 0x20: ! 1796: /* LDF */ ! 1797: #if 0 // TODO ! 1798: gen_load_fmem(ctx, &gen_ldf, ra, rb, disp16); ! 1799: #else ! 1800: goto invalid_opc; ! 1801: #endif ! 1802: break; ! 1803: case 0x21: ! 1804: /* LDG */ ! 1805: #if 0 // TODO ! 1806: gen_load_fmem(ctx, &gen_ldg, ra, rb, disp16); ! 1807: #else ! 1808: goto invalid_opc; ! 1809: #endif ! 1810: break; ! 1811: case 0x22: ! 1812: /* LDS */ ! 1813: gen_load_fmem(ctx, &gen_lds, ra, rb, disp16); ! 1814: break; ! 1815: case 0x23: ! 1816: /* LDT */ ! 1817: gen_load_fmem(ctx, &gen_ldt, ra, rb, disp16); ! 1818: break; ! 1819: case 0x24: ! 1820: /* STF */ ! 1821: #if 0 // TODO ! 1822: gen_store_fmem(ctx, &gen_stf, ra, rb, disp16); ! 1823: #else ! 1824: goto invalid_opc; ! 1825: #endif ! 1826: break; ! 1827: case 0x25: ! 1828: /* STG */ ! 1829: #if 0 // TODO ! 1830: gen_store_fmem(ctx, &gen_stg, ra, rb, disp16); ! 1831: #else ! 1832: goto invalid_opc; ! 1833: #endif ! 1834: break; ! 1835: case 0x26: ! 1836: /* STS */ ! 1837: gen_store_fmem(ctx, &gen_sts, ra, rb, disp16); ! 1838: break; ! 1839: case 0x27: ! 1840: /* STT */ ! 1841: gen_store_fmem(ctx, &gen_stt, ra, rb, disp16); ! 1842: break; ! 1843: case 0x28: ! 1844: /* LDL */ ! 1845: gen_load_mem(ctx, &gen_ldl, ra, rb, disp16, 0); ! 1846: break; ! 1847: case 0x29: ! 1848: /* LDQ */ ! 1849: gen_load_mem(ctx, &gen_ldq, ra, rb, disp16, 0); ! 1850: break; ! 1851: case 0x2A: ! 1852: /* LDL_L */ ! 1853: gen_load_mem(ctx, &gen_ldl_l, ra, rb, disp16, 0); ! 1854: break; ! 1855: case 0x2B: ! 1856: /* LDQ_L */ ! 1857: gen_load_mem(ctx, &gen_ldq_l, ra, rb, disp16, 0); ! 1858: break; ! 1859: case 0x2C: ! 1860: /* STL */ ! 1861: gen_store_mem(ctx, &gen_stl, ra, rb, disp16, 0); ! 1862: break; ! 1863: case 0x2D: ! 1864: /* STQ */ ! 1865: gen_store_mem(ctx, &gen_stq, ra, rb, disp16, 0); ! 1866: break; ! 1867: case 0x2E: ! 1868: /* STL_C */ ! 1869: gen_store_mem(ctx, &gen_stl_c, ra, rb, disp16, 0); ! 1870: break; ! 1871: case 0x2F: ! 1872: /* STQ_C */ ! 1873: gen_store_mem(ctx, &gen_stq_c, ra, rb, disp16, 0); ! 1874: break; ! 1875: case 0x30: ! 1876: /* BR */ ! 1877: gen_set_uT0(ctx, ctx->pc); ! 1878: gen_store_ir(ctx, ra, 0); ! 1879: if (disp21 != 0) { ! 1880: gen_set_sT1(ctx, disp21 << 2); ! 1881: gen_op_addq(); ! 1882: } ! 1883: gen_op_branch(); ! 1884: ret = 1; ! 1885: break; ! 1886: case 0x31: ! 1887: /* FBEQ */ ! 1888: gen_fbcond(ctx, &gen_op_cmpfeq, ra, disp16); ! 1889: ret = 1; ! 1890: break; ! 1891: case 0x32: ! 1892: /* FBLT */ ! 1893: gen_fbcond(ctx, &gen_op_cmpflt, ra, disp16); ! 1894: ret = 1; ! 1895: break; ! 1896: case 0x33: ! 1897: /* FBLE */ ! 1898: gen_fbcond(ctx, &gen_op_cmpfle, ra, disp16); ! 1899: ret = 1; ! 1900: break; ! 1901: case 0x34: ! 1902: /* BSR */ ! 1903: gen_set_uT0(ctx, ctx->pc); ! 1904: gen_store_ir(ctx, ra, 0); ! 1905: if (disp21 != 0) { ! 1906: gen_set_sT1(ctx, disp21 << 2); ! 1907: gen_op_addq(); ! 1908: } ! 1909: gen_op_branch(); ! 1910: ret = 1; ! 1911: break; ! 1912: case 0x35: ! 1913: /* FBNE */ ! 1914: gen_fbcond(ctx, &gen_op_cmpfne, ra, disp16); ! 1915: ret = 1; ! 1916: break; ! 1917: case 0x36: ! 1918: /* FBGE */ ! 1919: gen_fbcond(ctx, &gen_op_cmpfge, ra, disp16); ! 1920: ret = 1; ! 1921: break; ! 1922: case 0x37: ! 1923: /* FBGT */ ! 1924: gen_fbcond(ctx, &gen_op_cmpfgt, ra, disp16); ! 1925: ret = 1; ! 1926: break; ! 1927: case 0x38: ! 1928: /* BLBC */ ! 1929: gen_bcond(ctx, &gen_op_cmplbc, ra, disp16); ! 1930: ret = 1; ! 1931: break; ! 1932: case 0x39: ! 1933: /* BEQ */ ! 1934: gen_bcond(ctx, &gen_op_cmpeqz, ra, disp16); ! 1935: ret = 1; ! 1936: break; ! 1937: case 0x3A: ! 1938: /* BLT */ ! 1939: gen_bcond(ctx, &gen_op_cmpltz, ra, disp16); ! 1940: ret = 1; ! 1941: break; ! 1942: case 0x3B: ! 1943: /* BLE */ ! 1944: gen_bcond(ctx, &gen_op_cmplez, ra, disp16); ! 1945: ret = 1; ! 1946: break; ! 1947: case 0x3C: ! 1948: /* BLBS */ ! 1949: gen_bcond(ctx, &gen_op_cmplbs, ra, disp16); ! 1950: ret = 1; ! 1951: break; ! 1952: case 0x3D: ! 1953: /* BNE */ ! 1954: gen_bcond(ctx, &gen_op_cmpnez, ra, disp16); ! 1955: ret = 1; ! 1956: break; ! 1957: case 0x3E: ! 1958: /* BGE */ ! 1959: gen_bcond(ctx, &gen_op_cmpgez, ra, disp16); ! 1960: ret = 1; ! 1961: break; ! 1962: case 0x3F: ! 1963: /* BGT */ ! 1964: gen_bcond(ctx, &gen_op_cmpgtz, ra, disp16); ! 1965: ret = 1; ! 1966: break; ! 1967: invalid_opc: ! 1968: gen_invalid(ctx); ! 1969: ret = 3; ! 1970: break; ! 1971: } ! 1972: ! 1973: return ret; ! 1974: } ! 1975: ! 1976: static always_inline int gen_intermediate_code_internal (CPUState *env, ! 1977: TranslationBlock *tb, ! 1978: int search_pc) ! 1979: { ! 1980: #if defined ALPHA_DEBUG_DISAS ! 1981: static int insn_count; ! 1982: #endif ! 1983: DisasContext ctx, *ctxp = &ctx; ! 1984: target_ulong pc_start; ! 1985: uint32_t insn; ! 1986: uint16_t *gen_opc_end; ! 1987: int j, lj = -1; ! 1988: int ret; ! 1989: ! 1990: pc_start = tb->pc; ! 1991: gen_opc_ptr = gen_opc_buf; ! 1992: gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; ! 1993: gen_opparam_ptr = gen_opparam_buf; ! 1994: nb_gen_labels = 0; ! 1995: ctx.pc = pc_start; ! 1996: ctx.amask = env->amask; ! 1997: #if defined (CONFIG_USER_ONLY) ! 1998: ctx.mem_idx = 0; ! 1999: #else ! 2000: ctx.mem_idx = ((env->ps >> 3) & 3); ! 2001: ctx.pal_mode = env->ipr[IPR_EXC_ADDR] & 1; ! 2002: #endif ! 2003: for (ret = 0; ret == 0;) { ! 2004: if (env->nb_breakpoints > 0) { ! 2005: for(j = 0; j < env->nb_breakpoints; j++) { ! 2006: if (env->breakpoints[j] == ctx.pc) { ! 2007: gen_excp(&ctx, EXCP_DEBUG, 0); ! 2008: break; ! 2009: } ! 2010: } ! 2011: } ! 2012: if (search_pc) { ! 2013: j = gen_opc_ptr - gen_opc_buf; ! 2014: if (lj < j) { ! 2015: lj++; ! 2016: while (lj < j) ! 2017: gen_opc_instr_start[lj++] = 0; ! 2018: gen_opc_pc[lj] = ctx.pc; ! 2019: gen_opc_instr_start[lj] = 1; ! 2020: } ! 2021: } ! 2022: #if defined ALPHA_DEBUG_DISAS ! 2023: insn_count++; ! 2024: if (logfile != NULL) { ! 2025: fprintf(logfile, "pc " TARGET_FMT_lx " mem_idx %d\n", ! 2026: ctx.pc, ctx.mem_idx); ! 2027: } ! 2028: #endif ! 2029: insn = ldl_code(ctx.pc); ! 2030: #if defined ALPHA_DEBUG_DISAS ! 2031: insn_count++; ! 2032: if (logfile != NULL) { ! 2033: fprintf(logfile, "opcode %08x %d\n", insn, insn_count); ! 2034: } ! 2035: #endif ! 2036: ctx.pc += 4; ! 2037: ret = translate_one(ctxp, insn); ! 2038: if (ret != 0) ! 2039: break; ! 2040: /* if we reach a page boundary or are single stepping, stop ! 2041: * generation ! 2042: */ ! 2043: if (((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) || ! 2044: (env->singlestep_enabled)) { ! 2045: break; ! 2046: } ! 2047: #if defined (DO_SINGLE_STEP) ! 2048: break; ! 2049: #endif ! 2050: } ! 2051: if (ret != 1 && ret != 3) { ! 2052: gen_update_pc(&ctx); ! 2053: } ! 2054: gen_op_reset_T0(); ! 2055: #if defined (DO_TB_FLUSH) ! 2056: gen_op_tb_flush(); ! 2057: #endif ! 2058: /* Generate the return instruction */ ! 2059: gen_op_exit_tb(); ! 2060: *gen_opc_ptr = INDEX_op_end; ! 2061: if (search_pc) { ! 2062: j = gen_opc_ptr - gen_opc_buf; ! 2063: lj++; ! 2064: while (lj <= j) ! 2065: gen_opc_instr_start[lj++] = 0; ! 2066: } else { ! 2067: tb->size = ctx.pc - pc_start; ! 2068: } ! 2069: #if defined ALPHA_DEBUG_DISAS ! 2070: if (loglevel & CPU_LOG_TB_CPU) { ! 2071: cpu_dump_state(env, logfile, fprintf, 0); ! 2072: } ! 2073: if (loglevel & CPU_LOG_TB_IN_ASM) { ! 2074: fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start)); ! 2075: target_disas(logfile, pc_start, ctx.pc - pc_start, 1); ! 2076: fprintf(logfile, "\n"); ! 2077: } ! 2078: if (loglevel & CPU_LOG_TB_OP) { ! 2079: fprintf(logfile, "OP:\n"); ! 2080: dump_ops(gen_opc_buf, gen_opparam_buf); ! 2081: fprintf(logfile, "\n"); ! 2082: } ! 2083: #endif ! 2084: ! 2085: return 0; ! 2086: } ! 2087: ! 2088: int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb) ! 2089: { ! 2090: return gen_intermediate_code_internal(env, tb, 0); ! 2091: } ! 2092: ! 2093: int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) ! 2094: { ! 2095: return gen_intermediate_code_internal(env, tb, 1); ! 2096: } ! 2097: ! 2098: CPUAlphaState * cpu_alpha_init (const char *cpu_model) ! 2099: { ! 2100: CPUAlphaState *env; ! 2101: uint64_t hwpcb; ! 2102: ! 2103: env = qemu_mallocz(sizeof(CPUAlphaState)); ! 2104: if (!env) ! 2105: return NULL; ! 2106: cpu_exec_init(env); ! 2107: tlb_flush(env, 1); ! 2108: /* XXX: should not be hardcoded */ ! 2109: env->implver = IMPLVER_2106x; ! 2110: env->ps = 0x1F00; ! 2111: #if defined (CONFIG_USER_ONLY) ! 2112: env->ps |= 1 << 3; ! 2113: #endif ! 2114: pal_init(env); ! 2115: /* Initialize IPR */ ! 2116: hwpcb = env->ipr[IPR_PCBB]; ! 2117: env->ipr[IPR_ASN] = 0; ! 2118: env->ipr[IPR_ASTEN] = 0; ! 2119: env->ipr[IPR_ASTSR] = 0; ! 2120: env->ipr[IPR_DATFX] = 0; ! 2121: /* XXX: fix this */ ! 2122: // env->ipr[IPR_ESP] = ldq_raw(hwpcb + 8); ! 2123: // env->ipr[IPR_KSP] = ldq_raw(hwpcb + 0); ! 2124: // env->ipr[IPR_SSP] = ldq_raw(hwpcb + 16); ! 2125: // env->ipr[IPR_USP] = ldq_raw(hwpcb + 24); ! 2126: env->ipr[IPR_FEN] = 0; ! 2127: env->ipr[IPR_IPL] = 31; ! 2128: env->ipr[IPR_MCES] = 0; ! 2129: env->ipr[IPR_PERFMON] = 0; /* Implementation specific */ ! 2130: // env->ipr[IPR_PTBR] = ldq_raw(hwpcb + 32); ! 2131: env->ipr[IPR_SISR] = 0; ! 2132: env->ipr[IPR_VIRBND] = -1ULL; ! 2133: ! 2134: return env; ! 2135: } ! 2136:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.