|
|
1.1 ! root 1: /* ! 2: * CRIS emulation micro-operations for qemu. ! 3: * ! 4: * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB. ! 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: #include "exec.h" ! 21: #include "host-utils.h" ! 22: ! 23: #define REGNAME r0 ! 24: #define REG (env->regs[0]) ! 25: #include "op_template.h" ! 26: ! 27: #define REGNAME r1 ! 28: #define REG (env->regs[1]) ! 29: #include "op_template.h" ! 30: ! 31: #define REGNAME r2 ! 32: #define REG (env->regs[2]) ! 33: #include "op_template.h" ! 34: ! 35: #define REGNAME r3 ! 36: #define REG (env->regs[3]) ! 37: #include "op_template.h" ! 38: ! 39: #define REGNAME r4 ! 40: #define REG (env->regs[4]) ! 41: #include "op_template.h" ! 42: ! 43: #define REGNAME r5 ! 44: #define REG (env->regs[5]) ! 45: #include "op_template.h" ! 46: ! 47: #define REGNAME r6 ! 48: #define REG (env->regs[6]) ! 49: #include "op_template.h" ! 50: ! 51: #define REGNAME r7 ! 52: #define REG (env->regs[7]) ! 53: #include "op_template.h" ! 54: ! 55: #define REGNAME r8 ! 56: #define REG (env->regs[8]) ! 57: #include "op_template.h" ! 58: ! 59: #define REGNAME r9 ! 60: #define REG (env->regs[9]) ! 61: #include "op_template.h" ! 62: ! 63: #define REGNAME r10 ! 64: #define REG (env->regs[10]) ! 65: #include "op_template.h" ! 66: ! 67: #define REGNAME r11 ! 68: #define REG (env->regs[11]) ! 69: #include "op_template.h" ! 70: ! 71: #define REGNAME r12 ! 72: #define REG (env->regs[12]) ! 73: #include "op_template.h" ! 74: ! 75: #define REGNAME r13 ! 76: #define REG (env->regs[13]) ! 77: #include "op_template.h" ! 78: ! 79: #define REGNAME r14 ! 80: #define REG (env->regs[14]) ! 81: #include "op_template.h" ! 82: ! 83: #define REGNAME r15 ! 84: #define REG (env->regs[15]) ! 85: #include "op_template.h" ! 86: ! 87: ! 88: #define REGNAME p0 ! 89: #define REG (env->pregs[0]) ! 90: #include "op_template.h" ! 91: ! 92: #define REGNAME p1 ! 93: #define REG (env->pregs[1]) ! 94: #include "op_template.h" ! 95: ! 96: #define REGNAME p2 ! 97: #define REG (env->pregs[2]) ! 98: #include "op_template.h" ! 99: ! 100: #define REGNAME p3 ! 101: #define REG (env->pregs[3]) ! 102: #include "op_template.h" ! 103: ! 104: #define REGNAME p4 ! 105: #define REG (env->pregs[4]) ! 106: #include "op_template.h" ! 107: ! 108: #define REGNAME p5 ! 109: #define REG (env->pregs[5]) ! 110: #include "op_template.h" ! 111: ! 112: #define REGNAME p6 ! 113: #define REG (env->pregs[6]) ! 114: #include "op_template.h" ! 115: ! 116: #define REGNAME p7 ! 117: #define REG (env->pregs[7]) ! 118: #include "op_template.h" ! 119: ! 120: #define REGNAME p8 ! 121: #define REG (env->pregs[8]) ! 122: #include "op_template.h" ! 123: ! 124: #define REGNAME p9 ! 125: #define REG (env->pregs[9]) ! 126: #include "op_template.h" ! 127: ! 128: #define REGNAME p10 ! 129: #define REG (env->pregs[10]) ! 130: #include "op_template.h" ! 131: ! 132: #define REGNAME p11 ! 133: #define REG (env->pregs[11]) ! 134: #include "op_template.h" ! 135: ! 136: #define REGNAME p12 ! 137: #define REG (env->pregs[12]) ! 138: #include "op_template.h" ! 139: ! 140: #define REGNAME p13 ! 141: #define REG (env->pregs[13]) ! 142: #include "op_template.h" ! 143: ! 144: #define REGNAME p14 ! 145: #define REG (env->pregs[14]) ! 146: #include "op_template.h" ! 147: ! 148: #define REGNAME p15 ! 149: #define REG (env->pregs[15]) ! 150: #include "op_template.h" ! 151: ! 152: /* Microcode. */ ! 153: ! 154: void OPPROTO op_exit_tb (void) ! 155: { ! 156: EXIT_TB(); ! 157: } ! 158: ! 159: void OPPROTO op_goto_tb0 (void) ! 160: { ! 161: GOTO_TB(op_goto_tb0, PARAM1, 0); ! 162: RETURN(); ! 163: } ! 164: ! 165: void OPPROTO op_goto_tb1 (void) ! 166: { ! 167: GOTO_TB(op_goto_tb1, PARAM1, 1); ! 168: RETURN(); ! 169: } ! 170: ! 171: void OPPROTO op_break_im(void) ! 172: { ! 173: env->trapnr = PARAM1; ! 174: env->exception_index = EXCP_BREAK; ! 175: cpu_loop_exit(); ! 176: } ! 177: ! 178: void OPPROTO op_debug(void) ! 179: { ! 180: env->exception_index = EXCP_DEBUG; ! 181: cpu_loop_exit(); ! 182: } ! 183: ! 184: void OPPROTO op_exec_insn(void) ! 185: { ! 186: env->stats.exec_insns++; ! 187: RETURN(); ! 188: } ! 189: void OPPROTO op_exec_load(void) ! 190: { ! 191: env->stats.exec_loads++; ! 192: RETURN(); ! 193: } ! 194: void OPPROTO op_exec_store(void) ! 195: { ! 196: env->stats.exec_stores++; ! 197: RETURN(); ! 198: } ! 199: ! 200: void OPPROTO op_ccs_lshift (void) ! 201: { ! 202: uint32_t ccs; ! 203: ! 204: /* Apply the ccs shift. */ ! 205: ccs = env->pregs[SR_CCS]; ! 206: ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2); ! 207: env->pregs[SR_CCS] = ccs; ! 208: } ! 209: void OPPROTO op_ccs_rshift (void) ! 210: { ! 211: uint32_t ccs; ! 212: ! 213: /* Apply the ccs shift. */ ! 214: ccs = env->pregs[SR_CCS]; ! 215: ccs = (ccs & 0xc0000000) | (ccs >> 10); ! 216: env->pregs[SR_CCS] = ccs; ! 217: } ! 218: ! 219: void OPPROTO op_setf (void) ! 220: { ! 221: env->pregs[SR_CCS] |= PARAM1; ! 222: RETURN(); ! 223: } ! 224: ! 225: void OPPROTO op_clrf (void) ! 226: { ! 227: env->pregs[SR_CCS] &= ~PARAM1; ! 228: RETURN(); ! 229: } ! 230: ! 231: void OPPROTO op_movl_debug1_T0 (void) ! 232: { ! 233: env->debug1 = T0; ! 234: RETURN(); ! 235: } ! 236: ! 237: void OPPROTO op_movl_debug2_T0 (void) ! 238: { ! 239: env->debug2 = T0; ! 240: RETURN(); ! 241: } ! 242: ! 243: void OPPROTO op_movl_debug3_T0 (void) ! 244: { ! 245: env->debug3 = T0; ! 246: RETURN(); ! 247: } ! 248: void OPPROTO op_movl_debug1_T1 (void) ! 249: { ! 250: env->debug1 = T1; ! 251: RETURN(); ! 252: } ! 253: ! 254: void OPPROTO op_movl_debug2_T1 (void) ! 255: { ! 256: env->debug2 = T1; ! 257: RETURN(); ! 258: } ! 259: ! 260: void OPPROTO op_movl_debug3_T1 (void) ! 261: { ! 262: env->debug3 = T1; ! 263: RETURN(); ! 264: } ! 265: void OPPROTO op_movl_debug3_im (void) ! 266: { ! 267: env->debug3 = PARAM1; ! 268: RETURN(); ! 269: } ! 270: void OPPROTO op_movl_T0_flags (void) ! 271: { ! 272: T0 = env->pregs[SR_CCS]; ! 273: RETURN(); ! 274: } ! 275: void OPPROTO op_movl_flags_T0 (void) ! 276: { ! 277: env->pregs[SR_CCS] = T0; ! 278: RETURN(); ! 279: } ! 280: ! 281: void OPPROTO op_movl_sreg_T0 (void) ! 282: { ! 283: env->sregs[env->pregs[SR_SRS]][PARAM1] = T0; ! 284: RETURN(); ! 285: } ! 286: ! 287: void OPPROTO op_movl_tlb_lo_T0 (void) ! 288: { ! 289: int srs; ! 290: srs = env->pregs[SR_SRS]; ! 291: if (srs == 1 || srs == 2) ! 292: { ! 293: int set; ! 294: int idx; ! 295: uint32_t lo, hi; ! 296: ! 297: idx = set = env->sregs[SFR_RW_MM_TLB_SEL]; ! 298: set >>= 4; ! 299: set &= 3; ! 300: ! 301: idx &= 31; ! 302: /* We've just made a write to tlb_lo. */ ! 303: lo = env->sregs[SFR_RW_MM_TLB_LO]; ! 304: hi = env->sregs[SFR_RW_MM_TLB_HI]; ! 305: env->tlbsets[srs - 1][set][idx].lo = lo; ! 306: env->tlbsets[srs - 1][set][idx].hi = hi; ! 307: } ! 308: ! 309: RETURN(); ! 310: } ! 311: ! 312: void OPPROTO op_movl_T0_sreg (void) ! 313: { ! 314: T0 = env->sregs[env->pregs[SR_SRS]][PARAM1]; ! 315: RETURN(); ! 316: } ! 317: ! 318: void OPPROTO op_update_cc (void) ! 319: { ! 320: env->cc_op = PARAM1; ! 321: env->cc_dest = PARAM2; ! 322: env->cc_src = PARAM3; ! 323: RETURN(); ! 324: } ! 325: ! 326: void OPPROTO op_update_cc_op (void) ! 327: { ! 328: env->cc_op = PARAM1; ! 329: RETURN(); ! 330: } ! 331: ! 332: void OPPROTO op_update_cc_mask (void) ! 333: { ! 334: env->cc_mask = PARAM1; ! 335: RETURN(); ! 336: } ! 337: ! 338: void OPPROTO op_update_cc_dest_T0 (void) ! 339: { ! 340: env->cc_dest = T0; ! 341: RETURN(); ! 342: } ! 343: ! 344: void OPPROTO op_update_cc_result_T0 (void) ! 345: { ! 346: env->cc_result = T0; ! 347: RETURN(); ! 348: } ! 349: ! 350: void OPPROTO op_update_cc_size_im (void) ! 351: { ! 352: env->cc_size = PARAM1; ! 353: RETURN(); ! 354: } ! 355: ! 356: void OPPROTO op_update_cc_src_T1 (void) ! 357: { ! 358: env->cc_src = T1; ! 359: RETURN(); ! 360: } ! 361: void OPPROTO op_update_cc_x (void) ! 362: { ! 363: env->cc_x_live = PARAM1; ! 364: env->cc_x = PARAM2; ! 365: RETURN(); ! 366: } ! 367: ! 368: /* FIXME: is this allowed? */ ! 369: extern inline void evaluate_flags_writeback(uint32_t flags) ! 370: { ! 371: int x; ! 372: ! 373: /* Extended arithmetics, leave the z flag alone. */ ! 374: env->debug3 = env->pregs[SR_CCS]; ! 375: ! 376: if (env->cc_x_live) ! 377: x = env->cc_x; ! 378: else ! 379: x = env->pregs[SR_CCS] & X_FLAG; ! 380: ! 381: if ((x || env->cc_op == CC_OP_ADDC) ! 382: && flags & Z_FLAG) ! 383: env->cc_mask &= ~Z_FLAG; ! 384: ! 385: /* all insn clear the x-flag except setf or clrf. */ ! 386: env->pregs[SR_CCS] &= ~(env->cc_mask | X_FLAG); ! 387: flags &= env->cc_mask; ! 388: env->pregs[SR_CCS] |= flags; ! 389: RETURN(); ! 390: } ! 391: ! 392: void OPPROTO op_evaluate_flags_muls(void) ! 393: { ! 394: uint32_t src; ! 395: uint32_t dst; ! 396: uint32_t res; ! 397: uint32_t flags = 0; ! 398: /* were gonna have to redo the muls. */ ! 399: int64_t tmp, t0 ,t1; ! 400: int32_t mof; ! 401: int dneg; ! 402: ! 403: src = env->cc_src; ! 404: dst = env->cc_dest; ! 405: res = env->cc_result; ! 406: ! 407: ! 408: /* cast into signed values to make GCC sign extend. */ ! 409: t0 = (int32_t)src; ! 410: t1 = (int32_t)dst; ! 411: dneg = ((int32_t)res) < 0; ! 412: ! 413: tmp = t0 * t1; ! 414: mof = tmp >> 32; ! 415: if (tmp == 0) ! 416: flags |= Z_FLAG; ! 417: else if (tmp < 0) ! 418: flags |= N_FLAG; ! 419: if ((dneg && mof != -1) ! 420: || (!dneg && mof != 0)) ! 421: flags |= V_FLAG; ! 422: evaluate_flags_writeback(flags); ! 423: RETURN(); ! 424: } ! 425: ! 426: void OPPROTO op_evaluate_flags_mulu(void) ! 427: { ! 428: uint32_t src; ! 429: uint32_t dst; ! 430: uint32_t res; ! 431: uint32_t flags = 0; ! 432: /* were gonna have to redo the muls. */ ! 433: uint64_t tmp, t0 ,t1; ! 434: uint32_t mof; ! 435: ! 436: src = env->cc_src; ! 437: dst = env->cc_dest; ! 438: res = env->cc_result; ! 439: ! 440: ! 441: /* cast into signed values to make GCC sign extend. */ ! 442: t0 = src; ! 443: t1 = dst; ! 444: ! 445: tmp = t0 * t1; ! 446: mof = tmp >> 32; ! 447: if (tmp == 0) ! 448: flags |= Z_FLAG; ! 449: else if (tmp >> 63) ! 450: flags |= N_FLAG; ! 451: if (mof) ! 452: flags |= V_FLAG; ! 453: ! 454: evaluate_flags_writeback(flags); ! 455: RETURN(); ! 456: } ! 457: ! 458: void OPPROTO op_evaluate_flags_mcp(void) ! 459: { ! 460: uint32_t src; ! 461: uint32_t dst; ! 462: uint32_t res; ! 463: uint32_t flags = 0; ! 464: ! 465: src = env->cc_src; ! 466: dst = env->cc_dest; ! 467: res = env->cc_result; ! 468: ! 469: if ((res & 0x80000000L) != 0L) ! 470: { ! 471: flags |= N_FLAG; ! 472: if (((src & 0x80000000L) == 0L) ! 473: && ((dst & 0x80000000L) == 0L)) ! 474: { ! 475: flags |= V_FLAG; ! 476: } ! 477: else if (((src & 0x80000000L) != 0L) && ! 478: ((dst & 0x80000000L) != 0L)) ! 479: { ! 480: flags |= R_FLAG; ! 481: } ! 482: } ! 483: else ! 484: { ! 485: if (res == 0L) ! 486: flags |= Z_FLAG; ! 487: if (((src & 0x80000000L) != 0L) ! 488: && ((dst & 0x80000000L) != 0L)) ! 489: flags |= V_FLAG; ! 490: if ((dst & 0x80000000L) != 0L ! 491: || (src & 0x80000000L) != 0L) ! 492: flags |= R_FLAG; ! 493: } ! 494: ! 495: evaluate_flags_writeback(flags); ! 496: RETURN(); ! 497: } ! 498: ! 499: void OPPROTO op_evaluate_flags_alu_4(void) ! 500: { ! 501: uint32_t src; ! 502: uint32_t dst; ! 503: uint32_t res; ! 504: uint32_t flags = 0; ! 505: ! 506: src = env->cc_src; ! 507: dst = env->cc_dest; ! 508: res = env->cc_result; ! 509: ! 510: if ((res & 0x80000000L) != 0L) ! 511: { ! 512: flags |= N_FLAG; ! 513: if (((src & 0x80000000L) == 0L) ! 514: && ((dst & 0x80000000L) == 0L)) ! 515: { ! 516: flags |= V_FLAG; ! 517: } ! 518: else if (((src & 0x80000000L) != 0L) && ! 519: ((dst & 0x80000000L) != 0L)) ! 520: { ! 521: flags |= C_FLAG; ! 522: } ! 523: } ! 524: else ! 525: { ! 526: if (res == 0L) ! 527: flags |= Z_FLAG; ! 528: if (((src & 0x80000000L) != 0L) ! 529: && ((dst & 0x80000000L) != 0L)) ! 530: flags |= V_FLAG; ! 531: if ((dst & 0x80000000L) != 0L ! 532: || (src & 0x80000000L) != 0L) ! 533: flags |= C_FLAG; ! 534: } ! 535: ! 536: if (env->cc_op == CC_OP_SUB ! 537: || env->cc_op == CC_OP_CMP) { ! 538: flags ^= C_FLAG; ! 539: } ! 540: evaluate_flags_writeback(flags); ! 541: RETURN(); ! 542: } ! 543: ! 544: void OPPROTO op_evaluate_flags_move_4 (void) ! 545: { ! 546: uint32_t src; ! 547: uint32_t res; ! 548: uint32_t flags = 0; ! 549: ! 550: src = env->cc_src; ! 551: res = env->cc_result; ! 552: ! 553: if ((int32_t)res < 0) ! 554: flags |= N_FLAG; ! 555: else if (res == 0L) ! 556: flags |= Z_FLAG; ! 557: ! 558: evaluate_flags_writeback(flags); ! 559: RETURN(); ! 560: } ! 561: void OPPROTO op_evaluate_flags_move_2 (void) ! 562: { ! 563: uint32_t src; ! 564: uint32_t flags = 0; ! 565: uint16_t res; ! 566: ! 567: src = env->cc_src; ! 568: res = env->cc_result; ! 569: ! 570: if ((int16_t)res < 0L) ! 571: flags |= N_FLAG; ! 572: else if (res == 0) ! 573: flags |= Z_FLAG; ! 574: ! 575: evaluate_flags_writeback(flags); ! 576: RETURN(); ! 577: } ! 578: ! 579: /* TODO: This is expensive. We could split things up and only evaluate part of ! 580: CCR on a need to know basis. For now, we simply re-evaluate everything. */ ! 581: void OPPROTO op_evaluate_flags (void) ! 582: { ! 583: uint32_t src; ! 584: uint32_t dst; ! 585: uint32_t res; ! 586: uint32_t flags = 0; ! 587: ! 588: src = env->cc_src; ! 589: dst = env->cc_dest; ! 590: res = env->cc_result; ! 591: ! 592: ! 593: /* Now, evaluate the flags. This stuff is based on ! 594: Per Zander's CRISv10 simulator. */ ! 595: switch (env->cc_size) ! 596: { ! 597: case 1: ! 598: if ((res & 0x80L) != 0L) ! 599: { ! 600: flags |= N_FLAG; ! 601: if (((src & 0x80L) == 0L) ! 602: && ((dst & 0x80L) == 0L)) ! 603: { ! 604: flags |= V_FLAG; ! 605: } ! 606: else if (((src & 0x80L) != 0L) ! 607: && ((dst & 0x80L) != 0L)) ! 608: { ! 609: flags |= C_FLAG; ! 610: } ! 611: } ! 612: else ! 613: { ! 614: if ((res & 0xFFL) == 0L) ! 615: { ! 616: flags |= Z_FLAG; ! 617: } ! 618: if (((src & 0x80L) != 0L) ! 619: && ((dst & 0x80L) != 0L)) ! 620: { ! 621: flags |= V_FLAG; ! 622: } ! 623: if ((dst & 0x80L) != 0L ! 624: || (src & 0x80L) != 0L) ! 625: { ! 626: flags |= C_FLAG; ! 627: } ! 628: } ! 629: break; ! 630: case 2: ! 631: if ((res & 0x8000L) != 0L) ! 632: { ! 633: flags |= N_FLAG; ! 634: if (((src & 0x8000L) == 0L) ! 635: && ((dst & 0x8000L) == 0L)) ! 636: { ! 637: flags |= V_FLAG; ! 638: } ! 639: else if (((src & 0x8000L) != 0L) ! 640: && ((dst & 0x8000L) != 0L)) ! 641: { ! 642: flags |= C_FLAG; ! 643: } ! 644: } ! 645: else ! 646: { ! 647: if ((res & 0xFFFFL) == 0L) ! 648: { ! 649: flags |= Z_FLAG; ! 650: } ! 651: if (((src & 0x8000L) != 0L) ! 652: && ((dst & 0x8000L) != 0L)) ! 653: { ! 654: flags |= V_FLAG; ! 655: } ! 656: if ((dst & 0x8000L) != 0L ! 657: || (src & 0x8000L) != 0L) ! 658: { ! 659: flags |= C_FLAG; ! 660: } ! 661: } ! 662: break; ! 663: case 4: ! 664: if ((res & 0x80000000L) != 0L) ! 665: { ! 666: flags |= N_FLAG; ! 667: if (((src & 0x80000000L) == 0L) ! 668: && ((dst & 0x80000000L) == 0L)) ! 669: { ! 670: flags |= V_FLAG; ! 671: } ! 672: else if (((src & 0x80000000L) != 0L) && ! 673: ((dst & 0x80000000L) != 0L)) ! 674: { ! 675: flags |= C_FLAG; ! 676: } ! 677: } ! 678: else ! 679: { ! 680: if (res == 0L) ! 681: flags |= Z_FLAG; ! 682: if (((src & 0x80000000L) != 0L) ! 683: && ((dst & 0x80000000L) != 0L)) ! 684: flags |= V_FLAG; ! 685: if ((dst & 0x80000000L) != 0L ! 686: || (src & 0x80000000L) != 0L) ! 687: flags |= C_FLAG; ! 688: } ! 689: break; ! 690: default: ! 691: break; ! 692: } ! 693: ! 694: if (env->cc_op == CC_OP_SUB ! 695: || env->cc_op == CC_OP_CMP) { ! 696: flags ^= C_FLAG; ! 697: } ! 698: evaluate_flags_writeback(flags); ! 699: RETURN(); ! 700: } ! 701: ! 702: void OPPROTO op_extb_T0_T0 (void) ! 703: { ! 704: T0 = ((int8_t)T0); ! 705: RETURN(); ! 706: } ! 707: void OPPROTO op_extb_T1_T0 (void) ! 708: { ! 709: T1 = ((int8_t)T0); ! 710: RETURN(); ! 711: } ! 712: void OPPROTO op_extb_T1_T1 (void) ! 713: { ! 714: T1 = ((int8_t)T1); ! 715: RETURN(); ! 716: } ! 717: void OPPROTO op_zextb_T0_T0 (void) ! 718: { ! 719: T0 = ((uint8_t)T0); ! 720: RETURN(); ! 721: } ! 722: void OPPROTO op_zextb_T1_T0 (void) ! 723: { ! 724: T1 = ((uint8_t)T0); ! 725: RETURN(); ! 726: } ! 727: void OPPROTO op_zextb_T1_T1 (void) ! 728: { ! 729: T1 = ((uint8_t)T1); ! 730: RETURN(); ! 731: } ! 732: void OPPROTO op_extw_T0_T0 (void) ! 733: { ! 734: T0 = ((int16_t)T0); ! 735: RETURN(); ! 736: } ! 737: void OPPROTO op_extw_T1_T0 (void) ! 738: { ! 739: T1 = ((int16_t)T0); ! 740: RETURN(); ! 741: } ! 742: void OPPROTO op_extw_T1_T1 (void) ! 743: { ! 744: T1 = ((int16_t)T1); ! 745: RETURN(); ! 746: } ! 747: ! 748: void OPPROTO op_zextw_T0_T0 (void) ! 749: { ! 750: T0 = ((uint16_t)T0); ! 751: RETURN(); ! 752: } ! 753: void OPPROTO op_zextw_T1_T0 (void) ! 754: { ! 755: T1 = ((uint16_t)T0); ! 756: RETURN(); ! 757: } ! 758: ! 759: void OPPROTO op_zextw_T1_T1 (void) ! 760: { ! 761: T1 = ((uint16_t)T1); ! 762: RETURN(); ! 763: } ! 764: ! 765: void OPPROTO op_movl_T0_im (void) ! 766: { ! 767: T0 = PARAM1; ! 768: RETURN(); ! 769: } ! 770: void OPPROTO op_movl_T1_im (void) ! 771: { ! 772: T1 = PARAM1; ! 773: RETURN(); ! 774: } ! 775: ! 776: void OPPROTO op_addl_T0_im (void) ! 777: { ! 778: T0 += PARAM1; ! 779: RETURN(); ! 780: } ! 781: ! 782: void OPPROTO op_addl_T1_im (void) ! 783: { ! 784: T1 += PARAM1; ! 785: RETURN(); ! 786: ! 787: } ! 788: void OPPROTO op_subl_T0_im (void) ! 789: { ! 790: T0 -= PARAM1; ! 791: RETURN(); ! 792: } ! 793: ! 794: void OPPROTO op_addxl_T0_C (void) ! 795: { ! 796: if (env->pregs[SR_CCS] & X_FLAG) ! 797: T0 += !!(env->pregs[SR_CCS] & C_FLAG); ! 798: RETURN(); ! 799: } ! 800: void OPPROTO op_subxl_T0_C (void) ! 801: { ! 802: if (env->pregs[SR_CCS] & X_FLAG) ! 803: T0 -= !!(env->pregs[SR_CCS] & C_FLAG); ! 804: RETURN(); ! 805: } ! 806: void OPPROTO op_addl_T0_C (void) ! 807: { ! 808: T0 += !!(env->pregs[SR_CCS] & C_FLAG); ! 809: RETURN(); ! 810: } ! 811: void OPPROTO op_addl_T0_R (void) ! 812: { ! 813: T0 += !!(env->pregs[SR_CCS] & R_FLAG); ! 814: RETURN(); ! 815: } ! 816: ! 817: void OPPROTO op_clr_R (void) ! 818: { ! 819: env->pregs[SR_CCS] &= ~R_FLAG; ! 820: RETURN(); ! 821: } ! 822: ! 823: ! 824: void OPPROTO op_andl_T0_im (void) ! 825: { ! 826: T0 &= PARAM1; ! 827: RETURN(); ! 828: } ! 829: ! 830: void OPPROTO op_andl_T1_im (void) ! 831: { ! 832: T1 &= PARAM1; ! 833: RETURN(); ! 834: } ! 835: ! 836: void OPPROTO op_movl_T0_T1 (void) ! 837: { ! 838: T0 = T1; ! 839: RETURN(); ! 840: } ! 841: ! 842: void OPPROTO op_swp_T0_T1 (void) ! 843: { ! 844: T0 ^= T1; ! 845: T1 ^= T0; ! 846: T0 ^= T1; ! 847: RETURN(); ! 848: } ! 849: ! 850: void OPPROTO op_movl_T1_T0 (void) ! 851: { ! 852: T1 = T0; ! 853: RETURN(); ! 854: } ! 855: ! 856: void OPPROTO op_movl_pc_T0 (void) ! 857: { ! 858: env->pc = T0; ! 859: RETURN(); ! 860: } ! 861: ! 862: void OPPROTO op_movl_T0_0 (void) ! 863: { ! 864: T0 = 0; ! 865: RETURN(); ! 866: } ! 867: ! 868: void OPPROTO op_addl_T0_T1 (void) ! 869: { ! 870: T0 += T1; ! 871: RETURN(); ! 872: } ! 873: ! 874: void OPPROTO op_subl_T0_T1 (void) ! 875: { ! 876: T0 -= T1; ! 877: RETURN(); ! 878: } ! 879: ! 880: void OPPROTO op_absl_T1_T1 (void) ! 881: { ! 882: int32_t st = T1; ! 883: ! 884: T1 = st < 0 ? -st : st; ! 885: RETURN(); ! 886: } ! 887: ! 888: void OPPROTO op_muls_T0_T1 (void) ! 889: { ! 890: int64_t tmp, t0 ,t1; ! 891: ! 892: /* cast into signed values to make GCC sign extend these babies. */ ! 893: t0 = (int32_t)T0; ! 894: t1 = (int32_t)T1; ! 895: ! 896: tmp = t0 * t1; ! 897: T0 = tmp & 0xffffffff; ! 898: env->pregs[REG_MOF] = tmp >> 32; ! 899: RETURN(); ! 900: } ! 901: ! 902: void OPPROTO op_mulu_T0_T1 (void) ! 903: { ! 904: uint64_t tmp, t0 ,t1; ! 905: t0 = T0; ! 906: t1 = T1; ! 907: ! 908: tmp = t0 * t1; ! 909: T0 = tmp & 0xffffffff; ! 910: env->pregs[REG_MOF] = tmp >> 32; ! 911: RETURN(); ! 912: } ! 913: ! 914: void OPPROTO op_dstep_T0_T1 (void) ! 915: { ! 916: T0 <<= 1; ! 917: if (T0 >= T1) ! 918: T0 -= T1; ! 919: RETURN(); ! 920: } ! 921: ! 922: void OPPROTO op_orl_T0_T1 (void) ! 923: { ! 924: T0 |= T1; ! 925: RETURN(); ! 926: } ! 927: ! 928: void OPPROTO op_andl_T0_T1 (void) ! 929: { ! 930: T0 &= T1; ! 931: RETURN(); ! 932: } ! 933: ! 934: void OPPROTO op_xorl_T0_T1 (void) ! 935: { ! 936: T0 ^= T1; ! 937: RETURN(); ! 938: } ! 939: ! 940: void OPPROTO op_lsll_T0_T1 (void) ! 941: { ! 942: int s = T1; ! 943: if (s > 31) ! 944: T0 = 0; ! 945: else ! 946: T0 <<= s; ! 947: RETURN(); ! 948: } ! 949: ! 950: void OPPROTO op_lsll_T0_im (void) ! 951: { ! 952: T0 <<= PARAM1; ! 953: RETURN(); ! 954: } ! 955: ! 956: void OPPROTO op_lsrl_T0_T1 (void) ! 957: { ! 958: int s = T1; ! 959: if (s > 31) ! 960: T0 = 0; ! 961: else ! 962: T0 >>= s; ! 963: RETURN(); ! 964: } ! 965: ! 966: /* Rely on GCC emitting an arithmetic shift for signed right shifts. */ ! 967: void OPPROTO op_asrl_T0_T1 (void) ! 968: { ! 969: int s = T1; ! 970: if (s > 31) ! 971: T0 = T0 & 0x80000000 ? -1 : 0; ! 972: else ! 973: T0 = (int32_t)T0 >> s; ! 974: RETURN(); ! 975: } ! 976: ! 977: void OPPROTO op_btst_T0_T1 (void) ! 978: { ! 979: /* FIXME: clean this up. */ ! 980: ! 981: /* des ref: ! 982: The N flag is set according to the selected bit in the dest reg. ! 983: The Z flag is set if the selected bit and all bits to the right are ! 984: zero. ! 985: The destination reg is not affected.*/ ! 986: unsigned int fz, sbit, bset, mask, masked_t0; ! 987: ! 988: sbit = T1 & 31; ! 989: bset = !!(T0 & (1 << sbit)); ! 990: mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1; ! 991: masked_t0 = T0 & mask; ! 992: fz = !(masked_t0 | bset); ! 993: /* Set the N and Z flags accordingly. */ ! 994: T0 = (bset << 3) | (fz << 2); ! 995: RETURN(); ! 996: } ! 997: ! 998: void OPPROTO op_bound_T0_T1 (void) ! 999: { ! 1000: if (T0 > T1) ! 1001: T0 = T1; ! 1002: RETURN(); ! 1003: } ! 1004: ! 1005: void OPPROTO op_lz_T0_T1 (void) ! 1006: { ! 1007: T0 = clz32(T1); ! 1008: RETURN(); ! 1009: } ! 1010: ! 1011: void OPPROTO op_negl_T0_T1 (void) ! 1012: { ! 1013: T0 = -T1; ! 1014: RETURN(); ! 1015: } ! 1016: ! 1017: void OPPROTO op_negl_T1_T1 (void) ! 1018: { ! 1019: T1 = -T1; ! 1020: RETURN(); ! 1021: } ! 1022: ! 1023: void OPPROTO op_not_T0_T0 (void) ! 1024: { ! 1025: T0 = ~(T0); ! 1026: RETURN(); ! 1027: } ! 1028: void OPPROTO op_not_T1_T1 (void) ! 1029: { ! 1030: T1 = ~(T1); ! 1031: RETURN(); ! 1032: } ! 1033: ! 1034: void OPPROTO op_swapw_T0_T0 (void) ! 1035: { ! 1036: T0 = (T0 << 16) | ((T0 >> 16)); ! 1037: RETURN(); ! 1038: } ! 1039: ! 1040: void OPPROTO op_swapb_T0_T0 (void) ! 1041: { ! 1042: T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff); ! 1043: RETURN(); ! 1044: } ! 1045: ! 1046: void OPPROTO op_swapr_T0_T0 (void) ! 1047: { ! 1048: T0 = (((T0 << 7) & 0x80808080) | ! 1049: ((T0 << 5) & 0x40404040) | ! 1050: ((T0 << 3) & 0x20202020) | ! 1051: ((T0 << 1) & 0x10101010) | ! 1052: ((T0 >> 1) & 0x08080808) | ! 1053: ((T0 >> 3) & 0x04040404) | ! 1054: ((T0 >> 5) & 0x02020202) | ! 1055: ((T0 >> 7) & 0x01010101)); ! 1056: RETURN(); ! 1057: } ! 1058: ! 1059: void OPPROTO op_tst_cc_eq (void) { ! 1060: uint32_t flags = env->pregs[SR_CCS]; ! 1061: int z_set; ! 1062: ! 1063: z_set = !!(flags & Z_FLAG); ! 1064: T0 = z_set; ! 1065: RETURN(); ! 1066: } ! 1067: ! 1068: void OPPROTO op_tst_cc_eq_fast (void) { ! 1069: T0 = !(env->cc_result); ! 1070: RETURN(); ! 1071: } ! 1072: ! 1073: void OPPROTO op_tst_cc_ne (void) { ! 1074: uint32_t flags = env->pregs[SR_CCS]; ! 1075: int z_set; ! 1076: ! 1077: z_set = !!(flags & Z_FLAG); ! 1078: T0 = !z_set; ! 1079: RETURN(); ! 1080: } ! 1081: void OPPROTO op_tst_cc_ne_fast (void) { ! 1082: T0 = !!(env->cc_result); ! 1083: RETURN(); ! 1084: } ! 1085: ! 1086: void OPPROTO op_tst_cc_cc (void) { ! 1087: uint32_t flags = env->pregs[SR_CCS]; ! 1088: int c_set; ! 1089: ! 1090: c_set = !!(flags & C_FLAG); ! 1091: T0 = !c_set; ! 1092: RETURN(); ! 1093: } ! 1094: void OPPROTO op_tst_cc_cs (void) { ! 1095: uint32_t flags = env->pregs[SR_CCS]; ! 1096: int c_set; ! 1097: ! 1098: c_set = !!(flags & C_FLAG); ! 1099: T0 = c_set; ! 1100: RETURN(); ! 1101: } ! 1102: ! 1103: void OPPROTO op_tst_cc_vc (void) { ! 1104: uint32_t flags = env->pregs[SR_CCS]; ! 1105: int v_set; ! 1106: ! 1107: v_set = !!(flags & V_FLAG); ! 1108: T0 = !v_set; ! 1109: RETURN(); ! 1110: } ! 1111: void OPPROTO op_tst_cc_vs (void) { ! 1112: uint32_t flags = env->pregs[SR_CCS]; ! 1113: int v_set; ! 1114: ! 1115: v_set = !!(flags & V_FLAG); ! 1116: T0 = v_set; ! 1117: RETURN(); ! 1118: } ! 1119: void OPPROTO op_tst_cc_pl (void) { ! 1120: uint32_t flags = env->pregs[SR_CCS]; ! 1121: int n_set; ! 1122: ! 1123: n_set = !!(flags & N_FLAG); ! 1124: T0 = !n_set; ! 1125: RETURN(); ! 1126: } ! 1127: void OPPROTO op_tst_cc_pl_fast (void) { ! 1128: T0 = ((int32_t)env->cc_result) >= 0; ! 1129: RETURN(); ! 1130: } ! 1131: ! 1132: void OPPROTO op_tst_cc_mi (void) { ! 1133: uint32_t flags = env->pregs[SR_CCS]; ! 1134: int n_set; ! 1135: ! 1136: n_set = !!(flags & N_FLAG); ! 1137: T0 = n_set; ! 1138: RETURN(); ! 1139: } ! 1140: void OPPROTO op_tst_cc_mi_fast (void) { ! 1141: T0 = ((int32_t)env->cc_result) < 0; ! 1142: RETURN(); ! 1143: } ! 1144: ! 1145: void OPPROTO op_tst_cc_ls (void) { ! 1146: uint32_t flags = env->pregs[SR_CCS]; ! 1147: int c_set; ! 1148: int z_set; ! 1149: ! 1150: c_set = !!(flags & C_FLAG); ! 1151: z_set = !!(flags & Z_FLAG); ! 1152: T0 = c_set || z_set; ! 1153: RETURN(); ! 1154: } ! 1155: void OPPROTO op_tst_cc_hi (void) { ! 1156: uint32_t flags = env->pregs[SR_CCS]; ! 1157: int z_set; ! 1158: int c_set; ! 1159: ! 1160: z_set = !!(flags & Z_FLAG); ! 1161: c_set = !!(flags & C_FLAG); ! 1162: T0 = !c_set && !z_set; ! 1163: RETURN(); ! 1164: ! 1165: } ! 1166: ! 1167: void OPPROTO op_tst_cc_ge (void) { ! 1168: uint32_t flags = env->pregs[SR_CCS]; ! 1169: int n_set; ! 1170: int v_set; ! 1171: ! 1172: n_set = !!(flags & N_FLAG); ! 1173: v_set = !!(flags & V_FLAG); ! 1174: T0 = (n_set && v_set) || (!n_set && !v_set); ! 1175: RETURN(); ! 1176: } ! 1177: ! 1178: void OPPROTO op_tst_cc_ge_fast (void) { ! 1179: T0 = ((int32_t)env->cc_src < (int32_t)env->cc_dest); ! 1180: RETURN(); ! 1181: } ! 1182: ! 1183: void OPPROTO op_tst_cc_lt (void) { ! 1184: uint32_t flags = env->pregs[SR_CCS]; ! 1185: int n_set; ! 1186: int v_set; ! 1187: ! 1188: n_set = !!(flags & N_FLAG); ! 1189: v_set = !!(flags & V_FLAG); ! 1190: T0 = (n_set && !v_set) || (!n_set && v_set); ! 1191: RETURN(); ! 1192: } ! 1193: ! 1194: void OPPROTO op_tst_cc_gt (void) { ! 1195: uint32_t flags = env->pregs[SR_CCS]; ! 1196: int n_set; ! 1197: int v_set; ! 1198: int z_set; ! 1199: ! 1200: n_set = !!(flags & N_FLAG); ! 1201: v_set = !!(flags & V_FLAG); ! 1202: z_set = !!(flags & Z_FLAG); ! 1203: T0 = (n_set && v_set && !z_set) ! 1204: || (!n_set && !v_set && !z_set); ! 1205: RETURN(); ! 1206: } ! 1207: ! 1208: void OPPROTO op_tst_cc_le (void) { ! 1209: uint32_t flags = env->pregs[SR_CCS]; ! 1210: int n_set; ! 1211: int v_set; ! 1212: int z_set; ! 1213: ! 1214: n_set = !!(flags & N_FLAG); ! 1215: v_set = !!(flags & V_FLAG); ! 1216: z_set = !!(flags & Z_FLAG); ! 1217: T0 = z_set || (n_set && !v_set) || (!n_set && v_set); ! 1218: RETURN(); ! 1219: } ! 1220: ! 1221: void OPPROTO op_tst_cc_p (void) { ! 1222: uint32_t flags = env->pregs[SR_CCS]; ! 1223: int p_set; ! 1224: ! 1225: p_set = !!(flags & P_FLAG); ! 1226: T0 = p_set; ! 1227: RETURN(); ! 1228: } ! 1229: ! 1230: /* Evaluate the if the branch should be taken or not. Needs to be done in ! 1231: the original sequence. The acutal branch is rescheduled to right after the ! 1232: delay-slot. */ ! 1233: void OPPROTO op_evaluate_bcc (void) ! 1234: { ! 1235: env->btaken = T0; ! 1236: RETURN(); ! 1237: } ! 1238: ! 1239: /* this one is used on every alu op, optimize it!. */ ! 1240: void OPPROTO op_goto_if_not_x (void) ! 1241: { ! 1242: if (env->pregs[SR_CCS] & X_FLAG) ! 1243: GOTO_LABEL_PARAM(1); ! 1244: RETURN(); ! 1245: } ! 1246: ! 1247: void OPPROTO op_cc_jmp (void) ! 1248: { ! 1249: if (env->btaken) ! 1250: env->pc = PARAM1; ! 1251: else ! 1252: env->pc = PARAM2; ! 1253: RETURN(); ! 1254: } ! 1255: ! 1256: void OPPROTO op_cc_ngoto (void) ! 1257: { ! 1258: if (!env->btaken) ! 1259: GOTO_LABEL_PARAM(1); ! 1260: RETURN(); ! 1261: } ! 1262: ! 1263: void OPPROTO op_movl_btarget_T0 (void) ! 1264: { ! 1265: env->btarget = T0; ! 1266: RETURN(); ! 1267: } ! 1268: ! 1269: void OPPROTO op_jmp (void) ! 1270: { ! 1271: env->pc = env->btarget; ! 1272: RETURN(); ! 1273: } ! 1274: ! 1275: /* Load and store */ ! 1276: #define MEMSUFFIX _raw ! 1277: #include "op_mem.c" ! 1278: #undef MEMSUFFIX ! 1279: #if !defined(CONFIG_USER_ONLY) ! 1280: #define MEMSUFFIX _user ! 1281: #include "op_mem.c" ! 1282: #undef MEMSUFFIX ! 1283: ! 1284: #define MEMSUFFIX _kernel ! 1285: #include "op_mem.c" ! 1286: #undef MEMSUFFIX ! 1287: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.