|
|
1.1 root 1: /*
2: * MIPS emulation micro-operations for qemu.
3: *
4: * Copyright (c) 2004-2005 Jocelyn Mayer
1.1.1.4 root 5: * Copyright (c) 2006 Marius Groeger (FPU operations)
1.1 root 6: *
7: * This library is free software; you can redistribute it and/or
8: * modify it under the terms of the GNU Lesser General Public
9: * License as published by the Free Software Foundation; either
10: * version 2 of the License, or (at your option) any later version.
11: *
12: * This library is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15: * Lesser General Public License for more details.
16: *
17: * You should have received a copy of the GNU Lesser General Public
18: * License along with this library; if not, write to the Free Software
19: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20: */
21:
22: #include "config.h"
23: #include "exec.h"
24:
25: #ifndef CALL_FROM_TB0
26: #define CALL_FROM_TB0(func) func();
27: #endif
28: #ifndef CALL_FROM_TB1
29: #define CALL_FROM_TB1(func, arg0) func(arg0);
30: #endif
31: #ifndef CALL_FROM_TB1_CONST16
32: #define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0);
33: #endif
34: #ifndef CALL_FROM_TB2
35: #define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1);
36: #endif
37: #ifndef CALL_FROM_TB2_CONST16
38: #define CALL_FROM_TB2_CONST16(func, arg0, arg1) \
39: CALL_FROM_TB2(func, arg0, arg1);
40: #endif
41: #ifndef CALL_FROM_TB3
42: #define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2);
43: #endif
44: #ifndef CALL_FROM_TB4
45: #define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \
46: func(arg0, arg1, arg2, arg3);
47: #endif
48:
49: #define REG 1
50: #include "op_template.c"
51: #undef REG
52: #define REG 2
53: #include "op_template.c"
54: #undef REG
55: #define REG 3
56: #include "op_template.c"
57: #undef REG
58: #define REG 4
59: #include "op_template.c"
60: #undef REG
61: #define REG 5
62: #include "op_template.c"
63: #undef REG
64: #define REG 6
65: #include "op_template.c"
66: #undef REG
67: #define REG 7
68: #include "op_template.c"
69: #undef REG
70: #define REG 8
71: #include "op_template.c"
72: #undef REG
73: #define REG 9
74: #include "op_template.c"
75: #undef REG
76: #define REG 10
77: #include "op_template.c"
78: #undef REG
79: #define REG 11
80: #include "op_template.c"
81: #undef REG
82: #define REG 12
83: #include "op_template.c"
84: #undef REG
85: #define REG 13
86: #include "op_template.c"
87: #undef REG
88: #define REG 14
89: #include "op_template.c"
90: #undef REG
91: #define REG 15
92: #include "op_template.c"
93: #undef REG
94: #define REG 16
95: #include "op_template.c"
96: #undef REG
97: #define REG 17
98: #include "op_template.c"
99: #undef REG
100: #define REG 18
101: #include "op_template.c"
102: #undef REG
103: #define REG 19
104: #include "op_template.c"
105: #undef REG
106: #define REG 20
107: #include "op_template.c"
108: #undef REG
109: #define REG 21
110: #include "op_template.c"
111: #undef REG
112: #define REG 22
113: #include "op_template.c"
114: #undef REG
115: #define REG 23
116: #include "op_template.c"
117: #undef REG
118: #define REG 24
119: #include "op_template.c"
120: #undef REG
121: #define REG 25
122: #include "op_template.c"
123: #undef REG
124: #define REG 26
125: #include "op_template.c"
126: #undef REG
127: #define REG 27
128: #include "op_template.c"
129: #undef REG
130: #define REG 28
131: #include "op_template.c"
132: #undef REG
133: #define REG 29
134: #include "op_template.c"
135: #undef REG
136: #define REG 30
137: #include "op_template.c"
138: #undef REG
139: #define REG 31
140: #include "op_template.c"
141: #undef REG
142:
1.1.1.5 ! root 143: #define TN
1.1 root 144: #include "op_template.c"
145: #undef TN
146:
1.1.1.4 root 147: #ifdef MIPS_USES_FPU
148:
149: #define SFREG 0
150: #define DFREG 0
151: #include "fop_template.c"
152: #undef SFREG
153: #undef DFREG
154: #define SFREG 1
155: #include "fop_template.c"
156: #undef SFREG
157: #define SFREG 2
158: #define DFREG 2
159: #include "fop_template.c"
160: #undef SFREG
161: #undef DFREG
162: #define SFREG 3
163: #include "fop_template.c"
164: #undef SFREG
165: #define SFREG 4
166: #define DFREG 4
167: #include "fop_template.c"
168: #undef SFREG
169: #undef DFREG
170: #define SFREG 5
171: #include "fop_template.c"
172: #undef SFREG
173: #define SFREG 6
174: #define DFREG 6
175: #include "fop_template.c"
176: #undef SFREG
177: #undef DFREG
178: #define SFREG 7
179: #include "fop_template.c"
180: #undef SFREG
181: #define SFREG 8
182: #define DFREG 8
183: #include "fop_template.c"
184: #undef SFREG
185: #undef DFREG
186: #define SFREG 9
187: #include "fop_template.c"
188: #undef SFREG
189: #define SFREG 10
190: #define DFREG 10
191: #include "fop_template.c"
192: #undef SFREG
193: #undef DFREG
194: #define SFREG 11
195: #include "fop_template.c"
196: #undef SFREG
197: #define SFREG 12
198: #define DFREG 12
199: #include "fop_template.c"
200: #undef SFREG
201: #undef DFREG
202: #define SFREG 13
203: #include "fop_template.c"
204: #undef SFREG
205: #define SFREG 14
206: #define DFREG 14
207: #include "fop_template.c"
208: #undef SFREG
209: #undef DFREG
210: #define SFREG 15
211: #include "fop_template.c"
212: #undef SFREG
213: #define SFREG 16
214: #define DFREG 16
215: #include "fop_template.c"
216: #undef SFREG
217: #undef DFREG
218: #define SFREG 17
219: #include "fop_template.c"
220: #undef SFREG
221: #define SFREG 18
222: #define DFREG 18
223: #include "fop_template.c"
224: #undef SFREG
225: #undef DFREG
226: #define SFREG 19
227: #include "fop_template.c"
228: #undef SFREG
229: #define SFREG 20
230: #define DFREG 20
231: #include "fop_template.c"
232: #undef SFREG
233: #undef DFREG
234: #define SFREG 21
235: #include "fop_template.c"
236: #undef SFREG
237: #define SFREG 22
238: #define DFREG 22
239: #include "fop_template.c"
240: #undef SFREG
241: #undef DFREG
242: #define SFREG 23
243: #include "fop_template.c"
244: #undef SFREG
245: #define SFREG 24
246: #define DFREG 24
247: #include "fop_template.c"
248: #undef SFREG
249: #undef DFREG
250: #define SFREG 25
251: #include "fop_template.c"
252: #undef SFREG
253: #define SFREG 26
254: #define DFREG 26
255: #include "fop_template.c"
256: #undef SFREG
257: #undef DFREG
258: #define SFREG 27
259: #include "fop_template.c"
260: #undef SFREG
261: #define SFREG 28
262: #define DFREG 28
263: #include "fop_template.c"
264: #undef SFREG
265: #undef DFREG
266: #define SFREG 29
267: #include "fop_template.c"
268: #undef SFREG
269: #define SFREG 30
270: #define DFREG 30
271: #include "fop_template.c"
272: #undef SFREG
273: #undef DFREG
274: #define SFREG 31
275: #include "fop_template.c"
276: #undef SFREG
277:
278: #define FTN
279: #include "fop_template.c"
280: #undef FTN
281:
282: #endif
283:
1.1 root 284: void op_dup_T0 (void)
285: {
286: T2 = T0;
287: RETURN();
288: }
289:
290: void op_load_HI (void)
291: {
292: T0 = env->HI;
293: RETURN();
294: }
295:
296: void op_store_HI (void)
297: {
298: env->HI = T0;
299: RETURN();
300: }
301:
302: void op_load_LO (void)
303: {
304: T0 = env->LO;
305: RETURN();
306: }
307:
308: void op_store_LO (void)
309: {
310: env->LO = T0;
311: RETURN();
312: }
313:
314: /* Load and store */
315: #define MEMSUFFIX _raw
316: #include "op_mem.c"
317: #undef MEMSUFFIX
318: #if !defined(CONFIG_USER_ONLY)
319: #define MEMSUFFIX _user
320: #include "op_mem.c"
321: #undef MEMSUFFIX
322:
323: #define MEMSUFFIX _kernel
324: #include "op_mem.c"
325: #undef MEMSUFFIX
326: #endif
327:
328: /* Arithmetic */
329: void op_add (void)
330: {
1.1.1.5 ! root 331: T0 = (int32_t)((int32_t)T0 + (int32_t)T1);
1.1 root 332: RETURN();
333: }
334:
335: void op_addo (void)
336: {
337: target_ulong tmp;
338:
1.1.1.5 ! root 339: tmp = (int32_t)T0;
! 340: T0 = (int32_t)T0 + (int32_t)T1;
! 341: if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
! 342: /* operands of same sign, result different sign */
! 343: CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
! 344: }
! 345: T0 = (int32_t)T0;
! 346: RETURN();
! 347: }
! 348:
! 349: void op_sub (void)
! 350: {
! 351: T0 = (int32_t)((int32_t)T0 - (int32_t)T1);
! 352: RETURN();
! 353: }
! 354:
! 355: void op_subo (void)
! 356: {
! 357: target_ulong tmp;
! 358:
! 359: tmp = (int32_t)T0;
! 360: T0 = (int32_t)T0 - (int32_t)T1;
! 361: if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
! 362: /* operands of different sign, first operand and result different sign */
! 363: CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
! 364: }
! 365: T0 = (int32_t)T0;
! 366: RETURN();
! 367: }
! 368:
! 369: void op_mul (void)
! 370: {
! 371: T0 = (int32_t)((int32_t)T0 * (int32_t)T1);
! 372: RETURN();
! 373: }
! 374:
! 375: void op_div (void)
! 376: {
! 377: if (T1 != 0) {
! 378: env->LO = (int32_t)((int32_t)T0 / (int32_t)T1);
! 379: env->HI = (int32_t)((int32_t)T0 % (int32_t)T1);
! 380: }
! 381: RETURN();
! 382: }
! 383:
! 384: void op_divu (void)
! 385: {
! 386: if (T1 != 0) {
! 387: env->LO = (int32_t)((uint32_t)T0 / (uint32_t)T1);
! 388: env->HI = (int32_t)((uint32_t)T0 % (uint32_t)T1);
! 389: }
! 390: RETURN();
! 391: }
! 392:
! 393: #ifdef MIPS_HAS_MIPS64
! 394: /* Arithmetic */
! 395: void op_dadd (void)
! 396: {
! 397: T0 += T1;
! 398: RETURN();
! 399: }
! 400:
! 401: void op_daddo (void)
! 402: {
! 403: target_long tmp;
! 404:
1.1 root 405: tmp = T0;
406: T0 += T1;
1.1.1.5 ! root 407: if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
! 408: /* operands of same sign, result different sign */
! 409: CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
! 410: }
! 411: RETURN();
! 412: }
! 413:
! 414: void op_dsub (void)
! 415: {
! 416: T0 -= T1;
! 417: RETURN();
! 418: }
! 419:
! 420: void op_dsubo (void)
! 421: {
! 422: target_long tmp;
! 423:
! 424: tmp = T0;
! 425: T0 = (int64_t)T0 - (int64_t)T1;
! 426: if (((tmp ^ T1) & (tmp ^ T0)) >> 63) {
! 427: /* operands of different sign, first operand and result different sign */
1.1.1.2 root 428: CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
1.1 root 429: }
430: RETURN();
431: }
432:
1.1.1.5 ! root 433: void op_dmul (void)
! 434: {
! 435: T0 = (int64_t)T0 * (int64_t)T1;
! 436: RETURN();
! 437: }
! 438:
! 439: #if TARGET_LONG_BITS > HOST_LONG_BITS
! 440: /* Those might call libgcc functions. */
! 441: void op_ddiv (void)
! 442: {
! 443: do_ddiv();
! 444: RETURN();
! 445: }
! 446:
! 447: void op_ddivu (void)
! 448: {
! 449: do_ddivu();
! 450: RETURN();
! 451: }
! 452: #else
! 453: void op_ddiv (void)
! 454: {
! 455: if (T1 != 0) {
! 456: env->LO = (int64_t)T0 / (int64_t)T1;
! 457: env->HI = (int64_t)T0 % (int64_t)T1;
! 458: }
! 459: RETURN();
! 460: }
! 461:
! 462: void op_ddivu (void)
! 463: {
! 464: if (T1 != 0) {
! 465: env->LO = T0 / T1;
! 466: env->HI = T0 % T1;
! 467: }
! 468: RETURN();
! 469: }
! 470: #endif
! 471: #endif /* MIPS_HAS_MIPS64 */
! 472:
! 473: /* Logical */
! 474: void op_and (void)
! 475: {
! 476: T0 &= T1;
! 477: RETURN();
! 478: }
! 479:
! 480: void op_nor (void)
! 481: {
! 482: T0 = ~(T0 | T1);
! 483: RETURN();
! 484: }
! 485:
! 486: void op_or (void)
! 487: {
! 488: T0 |= T1;
! 489: RETURN();
! 490: }
! 491:
! 492: void op_xor (void)
! 493: {
! 494: T0 ^= T1;
! 495: RETURN();
! 496: }
! 497:
! 498: void op_sll (void)
! 499: {
! 500: T0 = (int32_t)((uint32_t)T0 << (uint32_t)T1);
! 501: RETURN();
! 502: }
! 503:
! 504: void op_sra (void)
! 505: {
! 506: T0 = (int32_t)((int32_t)T0 >> (uint32_t)T1);
! 507: RETURN();
! 508: }
! 509:
! 510: void op_srl (void)
! 511: {
! 512: T0 = (int32_t)((uint32_t)T0 >> (uint32_t)T1);
! 513: RETURN();
! 514: }
! 515:
! 516: void op_rotr (void)
! 517: {
! 518: target_ulong tmp;
! 519:
! 520: if (T1) {
! 521: tmp = (int32_t)((uint32_t)T0 << (0x20 - (uint32_t)T1));
! 522: T0 = (int32_t)((uint32_t)T0 >> (uint32_t)T1) | tmp;
! 523: } else
! 524: T0 = T1;
! 525: RETURN();
! 526: }
! 527:
! 528: void op_sllv (void)
! 529: {
! 530: T0 = (int32_t)((uint32_t)T1 << ((uint32_t)T0 & 0x1F));
! 531: RETURN();
! 532: }
! 533:
! 534: void op_srav (void)
! 535: {
! 536: T0 = (int32_t)((int32_t)T1 >> (T0 & 0x1F));
! 537: RETURN();
! 538: }
! 539:
! 540: void op_srlv (void)
! 541: {
! 542: T0 = (int32_t)((uint32_t)T1 >> (T0 & 0x1F));
! 543: RETURN();
! 544: }
! 545:
! 546: void op_rotrv (void)
! 547: {
! 548: target_ulong tmp;
! 549:
! 550: T0 &= 0x1F;
! 551: if (T0) {
! 552: tmp = (int32_t)((uint32_t)T1 << (0x20 - T0));
! 553: T0 = (int32_t)((uint32_t)T1 >> T0) | tmp;
! 554: } else
! 555: T0 = T1;
! 556: RETURN();
! 557: }
! 558:
! 559: void op_clo (void)
! 560: {
! 561: int n;
! 562:
! 563: if (T0 == ~((target_ulong)0)) {
! 564: T0 = 32;
! 565: } else {
! 566: for (n = 0; n < 32; n++) {
! 567: if (!(T0 & (1 << 31)))
! 568: break;
! 569: T0 = T0 << 1;
! 570: }
! 571: T0 = n;
! 572: }
! 573: RETURN();
! 574: }
! 575:
! 576: void op_clz (void)
! 577: {
! 578: int n;
! 579:
! 580: if (T0 == 0) {
! 581: T0 = 32;
! 582: } else {
! 583: for (n = 0; n < 32; n++) {
! 584: if (T0 & (1 << 31))
! 585: break;
! 586: T0 = T0 << 1;
! 587: }
! 588: T0 = n;
! 589: }
! 590: RETURN();
! 591: }
! 592:
! 593: #ifdef MIPS_HAS_MIPS64
! 594:
! 595: #if TARGET_LONG_BITS > HOST_LONG_BITS
! 596: /* Those might call libgcc functions. */
! 597: void op_dsll (void)
! 598: {
! 599: CALL_FROM_TB0(do_dsll);
! 600: RETURN();
! 601: }
! 602:
! 603: void op_dsll32 (void)
! 604: {
! 605: CALL_FROM_TB0(do_dsll32);
! 606: RETURN();
! 607: }
! 608:
! 609: void op_dsra (void)
! 610: {
! 611: CALL_FROM_TB0(do_dsra);
! 612: RETURN();
! 613: }
! 614:
! 615: void op_dsra32 (void)
! 616: {
! 617: CALL_FROM_TB0(do_dsra32);
! 618: RETURN();
! 619: }
! 620:
! 621: void op_dsrl (void)
! 622: {
! 623: CALL_FROM_TB0(do_dsrl);
! 624: RETURN();
! 625: }
! 626:
! 627: void op_dsrl32 (void)
! 628: {
! 629: CALL_FROM_TB0(do_dsrl32);
! 630: RETURN();
! 631: }
! 632:
! 633: void op_drotr (void)
! 634: {
! 635: CALL_FROM_TB0(do_drotr);
! 636: RETURN();
! 637: }
! 638:
! 639: void op_drotr32 (void)
! 640: {
! 641: CALL_FROM_TB0(do_drotr32);
! 642: RETURN();
! 643: }
! 644:
! 645: void op_dsllv (void)
! 646: {
! 647: CALL_FROM_TB0(do_dsllv);
! 648: RETURN();
! 649: }
! 650:
! 651: void op_dsrav (void)
! 652: {
! 653: CALL_FROM_TB0(do_dsrav);
! 654: RETURN();
! 655: }
! 656:
! 657: void op_dsrlv (void)
! 658: {
! 659: CALL_FROM_TB0(do_dsrlv);
! 660: RETURN();
! 661: }
! 662:
! 663: void op_drotrv (void)
! 664: {
! 665: CALL_FROM_TB0(do_drotrv);
! 666: RETURN();
! 667: }
! 668:
! 669: #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
! 670:
! 671: void op_dsll (void)
! 672: {
! 673: T0 = T0 << T1;
! 674: RETURN();
! 675: }
! 676:
! 677: void op_dsll32 (void)
! 678: {
! 679: T0 = T0 << (T1 + 32);
! 680: RETURN();
! 681: }
! 682:
! 683: void op_dsra (void)
! 684: {
! 685: T0 = (int64_t)T0 >> T1;
! 686: RETURN();
! 687: }
! 688:
! 689: void op_dsra32 (void)
! 690: {
! 691: T0 = (int64_t)T0 >> (T1 + 32);
! 692: RETURN();
! 693: }
! 694:
! 695: void op_dsrl (void)
! 696: {
! 697: T0 = T0 >> T1;
! 698: RETURN();
! 699: }
! 700:
! 701: void op_dsrl32 (void)
! 702: {
! 703: T0 = T0 >> (T1 + 32);
! 704: RETURN();
! 705: }
! 706:
! 707: void op_drotr (void)
! 708: {
! 709: target_ulong tmp;
! 710:
! 711: if (T1) {
! 712: tmp = T0 << (0x40 - T1);
! 713: T0 = (T0 >> T1) | tmp;
! 714: } else
! 715: T0 = T1;
! 716: RETURN();
! 717: }
! 718:
! 719: void op_drotr32 (void)
! 720: {
! 721: target_ulong tmp;
! 722:
! 723: if (T1) {
! 724: tmp = T0 << (0x40 - (32 + T1));
! 725: T0 = (T0 >> (32 + T1)) | tmp;
! 726: } else
! 727: T0 = T1;
! 728: RETURN();
! 729: }
! 730:
! 731: void op_dsllv (void)
! 732: {
! 733: T0 = T1 << (T0 & 0x3F);
! 734: RETURN();
! 735: }
! 736:
! 737: void op_dsrav (void)
! 738: {
! 739: T0 = (int64_t)T1 >> (T0 & 0x3F);
! 740: RETURN();
! 741: }
! 742:
! 743: void op_dsrlv (void)
! 744: {
! 745: T0 = T1 >> (T0 & 0x3F);
! 746: RETURN();
! 747: }
! 748:
! 749: void op_drotrv (void)
! 750: {
! 751: target_ulong tmp;
! 752:
! 753: T0 &= 0x3F;
! 754: if (T0) {
! 755: tmp = T1 << (0x40 - T0);
! 756: T0 = (T1 >> T0) | tmp;
! 757: } else
! 758: T0 = T1;
! 759: RETURN();
! 760: }
! 761: #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
! 762:
! 763: void op_dclo (void)
! 764: {
! 765: int n;
! 766:
! 767: if (T0 == ~((target_ulong)0)) {
! 768: T0 = 64;
! 769: } else {
! 770: for (n = 0; n < 64; n++) {
! 771: if (!(T0 & (1ULL << 63)))
! 772: break;
! 773: T0 = T0 << 1;
! 774: }
! 775: T0 = n;
! 776: }
! 777: RETURN();
! 778: }
! 779:
! 780: void op_dclz (void)
! 781: {
! 782: int n;
! 783:
! 784: if (T0 == 0) {
! 785: T0 = 64;
! 786: } else {
! 787: for (n = 0; n < 64; n++) {
! 788: if (T0 & (1ULL << 63))
! 789: break;
! 790: T0 = T0 << 1;
! 791: }
! 792: T0 = n;
! 793: }
! 794: RETURN();
! 795: }
! 796: #endif
! 797:
! 798: /* 64 bits arithmetic */
! 799: #if TARGET_LONG_BITS > HOST_LONG_BITS
! 800: void op_mult (void)
! 801: {
! 802: CALL_FROM_TB0(do_mult);
! 803: RETURN();
! 804: }
! 805:
! 806: void op_multu (void)
! 807: {
! 808: CALL_FROM_TB0(do_multu);
! 809: RETURN();
! 810: }
! 811:
! 812: void op_madd (void)
! 813: {
! 814: CALL_FROM_TB0(do_madd);
! 815: RETURN();
! 816: }
! 817:
! 818: void op_maddu (void)
! 819: {
! 820: CALL_FROM_TB0(do_maddu);
! 821: RETURN();
! 822: }
! 823:
! 824: void op_msub (void)
! 825: {
! 826: CALL_FROM_TB0(do_msub);
! 827: RETURN();
! 828: }
! 829:
! 830: void op_msubu (void)
! 831: {
! 832: CALL_FROM_TB0(do_msubu);
! 833: RETURN();
! 834: }
! 835:
! 836: #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
! 837:
! 838: static inline uint64_t get_HILO (void)
! 839: {
! 840: return ((uint64_t)env->HI << 32) | ((uint64_t)(uint32_t)env->LO);
! 841: }
! 842:
! 843: static inline void set_HILO (uint64_t HILO)
! 844: {
! 845: env->LO = (int32_t)(HILO & 0xFFFFFFFF);
! 846: env->HI = (int32_t)(HILO >> 32);
! 847: }
! 848:
! 849: void op_mult (void)
! 850: {
! 851: set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
! 852: RETURN();
! 853: }
! 854:
! 855: void op_multu (void)
! 856: {
! 857: set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
! 858: RETURN();
! 859: }
! 860:
! 861: void op_madd (void)
! 862: {
! 863: int64_t tmp;
! 864:
! 865: tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
! 866: set_HILO((int64_t)get_HILO() + tmp);
! 867: RETURN();
! 868: }
! 869:
! 870: void op_maddu (void)
! 871: {
! 872: uint64_t tmp;
! 873:
! 874: tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
! 875: set_HILO(get_HILO() + tmp);
! 876: RETURN();
! 877: }
! 878:
! 879: void op_msub (void)
! 880: {
! 881: int64_t tmp;
! 882:
! 883: tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
! 884: set_HILO((int64_t)get_HILO() - tmp);
! 885: RETURN();
! 886: }
! 887:
! 888: void op_msubu (void)
! 889: {
! 890: uint64_t tmp;
! 891:
! 892: tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
! 893: set_HILO(get_HILO() - tmp);
! 894: RETURN();
! 895: }
! 896: #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
! 897:
! 898: #ifdef MIPS_HAS_MIPS64
! 899: void op_dmult (void)
! 900: {
! 901: CALL_FROM_TB0(do_dmult);
! 902: RETURN();
! 903: }
! 904:
! 905: void op_dmultu (void)
! 906: {
! 907: CALL_FROM_TB0(do_dmultu);
! 908: RETURN();
! 909: }
! 910: #endif
! 911:
! 912: /* Conditional moves */
! 913: void op_movn (void)
! 914: {
! 915: if (T1 != 0)
! 916: env->gpr[PARAM1] = T0;
! 917: RETURN();
! 918: }
! 919:
! 920: void op_movz (void)
! 921: {
! 922: if (T1 == 0)
! 923: env->gpr[PARAM1] = T0;
! 924: RETURN();
! 925: }
! 926:
! 927: #ifdef MIPS_USES_FPU
! 928: void op_movf (void)
! 929: {
! 930: if (!(env->fcr31 & PARAM1))
! 931: env->gpr[PARAM2] = env->gpr[PARAM3];
! 932: RETURN();
! 933: }
! 934:
! 935: void op_movt (void)
! 936: {
! 937: if (env->fcr31 & PARAM1)
! 938: env->gpr[PARAM2] = env->gpr[PARAM3];
! 939: RETURN();
! 940: }
! 941: #endif
! 942:
! 943: /* Tests */
! 944: #define OP_COND(name, cond) \
! 945: void glue(op_, name) (void) \
! 946: { \
! 947: if (cond) { \
! 948: T0 = 1; \
! 949: } else { \
! 950: T0 = 0; \
! 951: } \
! 952: RETURN(); \
! 953: }
! 954:
! 955: OP_COND(eq, T0 == T1);
! 956: OP_COND(ne, T0 != T1);
! 957: OP_COND(ge, (int32_t)T0 >= (int32_t)T1);
! 958: OP_COND(geu, T0 >= T1);
! 959: OP_COND(lt, (int32_t)T0 < (int32_t)T1);
! 960: OP_COND(ltu, T0 < T1);
! 961: OP_COND(gez, (int32_t)T0 >= 0);
! 962: OP_COND(gtz, (int32_t)T0 > 0);
! 963: OP_COND(lez, (int32_t)T0 <= 0);
! 964: OP_COND(ltz, (int32_t)T0 < 0);
! 965:
! 966: /* Branches */
! 967: //#undef USE_DIRECT_JUMP
! 968:
! 969: void OPPROTO op_goto_tb0(void)
! 970: {
! 971: GOTO_TB(op_goto_tb0, PARAM1, 0);
! 972: RETURN();
! 973: }
! 974:
! 975: void OPPROTO op_goto_tb1(void)
! 976: {
! 977: GOTO_TB(op_goto_tb1, PARAM1, 1);
! 978: RETURN();
! 979: }
! 980:
! 981: /* Branch to register */
! 982: void op_save_breg_target (void)
! 983: {
! 984: env->btarget = T2;
! 985: RETURN();
! 986: }
! 987:
! 988: void op_restore_breg_target (void)
! 989: {
! 990: T2 = env->btarget;
! 991: RETURN();
! 992: }
! 993:
! 994: void op_breg (void)
! 995: {
! 996: env->PC = T2;
! 997: RETURN();
! 998: }
! 999:
! 1000: void op_save_btarget (void)
! 1001: {
! 1002: env->btarget = PARAM1;
! 1003: RETURN();
! 1004: }
! 1005:
! 1006: /* Conditional branch */
! 1007: void op_set_bcond (void)
! 1008: {
! 1009: T2 = T0;
! 1010: RETURN();
! 1011: }
! 1012:
! 1013: void op_save_bcond (void)
! 1014: {
! 1015: env->bcond = T2;
! 1016: RETURN();
! 1017: }
! 1018:
! 1019: void op_restore_bcond (void)
! 1020: {
! 1021: T2 = env->bcond;
! 1022: RETURN();
! 1023: }
! 1024:
! 1025: void op_jnz_T2 (void)
! 1026: {
! 1027: if (T2)
! 1028: GOTO_LABEL_PARAM(1);
! 1029: RETURN();
! 1030: }
! 1031:
! 1032: /* CP0 functions */
! 1033: void op_mfc0_index (void)
! 1034: {
! 1035: T0 = env->CP0_Index;
! 1036: RETURN();
! 1037: }
! 1038:
! 1039: void op_mfc0_random (void)
! 1040: {
! 1041: CALL_FROM_TB0(do_mfc0_random);
! 1042: RETURN();
! 1043: }
! 1044:
! 1045: void op_mfc0_entrylo0 (void)
! 1046: {
! 1047: T0 = (int32_t)env->CP0_EntryLo0;
! 1048: RETURN();
! 1049: }
! 1050:
! 1051: void op_mfc0_entrylo1 (void)
! 1052: {
! 1053: T0 = (int32_t)env->CP0_EntryLo1;
! 1054: RETURN();
! 1055: }
! 1056:
! 1057: void op_mfc0_context (void)
! 1058: {
! 1059: T0 = (int32_t)env->CP0_Context;
! 1060: RETURN();
! 1061: }
! 1062:
! 1063: void op_mfc0_pagemask (void)
! 1064: {
! 1065: T0 = env->CP0_PageMask;
! 1066: RETURN();
! 1067: }
! 1068:
! 1069: void op_mfc0_pagegrain (void)
! 1070: {
! 1071: T0 = env->CP0_PageGrain;
! 1072: RETURN();
! 1073: }
! 1074:
! 1075: void op_mfc0_wired (void)
! 1076: {
! 1077: T0 = env->CP0_Wired;
! 1078: RETURN();
! 1079: }
! 1080:
! 1081: void op_mfc0_hwrena (void)
! 1082: {
! 1083: T0 = env->CP0_HWREna;
! 1084: RETURN();
! 1085: }
! 1086:
! 1087: void op_mfc0_badvaddr (void)
! 1088: {
! 1089: T0 = (int32_t)env->CP0_BadVAddr;
! 1090: RETURN();
! 1091: }
! 1092:
! 1093: void op_mfc0_count (void)
! 1094: {
! 1095: CALL_FROM_TB0(do_mfc0_count);
! 1096: RETURN();
! 1097: }
! 1098:
! 1099: void op_mfc0_entryhi (void)
! 1100: {
! 1101: T0 = (int32_t)env->CP0_EntryHi;
! 1102: RETURN();
! 1103: }
! 1104:
! 1105: void op_mfc0_compare (void)
! 1106: {
! 1107: T0 = env->CP0_Compare;
! 1108: RETURN();
! 1109: }
! 1110:
! 1111: void op_mfc0_status (void)
! 1112: {
! 1113: T0 = env->CP0_Status;
! 1114: if (env->hflags & MIPS_HFLAG_UM)
! 1115: T0 |= (1 << CP0St_UM);
! 1116: if (env->hflags & MIPS_HFLAG_ERL)
! 1117: T0 |= (1 << CP0St_ERL);
! 1118: if (env->hflags & MIPS_HFLAG_EXL)
! 1119: T0 |= (1 << CP0St_EXL);
! 1120: RETURN();
! 1121: }
! 1122:
! 1123: void op_mfc0_intctl (void)
! 1124: {
! 1125: T0 = env->CP0_IntCtl;
! 1126: RETURN();
! 1127: }
! 1128:
! 1129: void op_mfc0_srsctl (void)
! 1130: {
! 1131: T0 = env->CP0_SRSCtl;
! 1132: RETURN();
! 1133: }
! 1134:
! 1135: void op_mfc0_srsmap (void)
! 1136: {
! 1137: T0 = env->CP0_SRSMap;
! 1138: RETURN();
! 1139: }
! 1140:
! 1141: void op_mfc0_cause (void)
! 1142: {
! 1143: T0 = env->CP0_Cause;
! 1144: RETURN();
! 1145: }
! 1146:
! 1147: void op_mfc0_epc (void)
! 1148: {
! 1149: T0 = (int32_t)env->CP0_EPC;
! 1150: RETURN();
! 1151: }
! 1152:
! 1153: void op_mfc0_prid (void)
! 1154: {
! 1155: T0 = env->CP0_PRid;
! 1156: RETURN();
! 1157: }
! 1158:
! 1159: void op_mfc0_ebase (void)
! 1160: {
! 1161: T0 = env->CP0_EBase;
! 1162: RETURN();
! 1163: }
! 1164:
! 1165: void op_mfc0_config0 (void)
! 1166: {
! 1167: T0 = env->CP0_Config0;
! 1168: RETURN();
! 1169: }
! 1170:
! 1171: void op_mfc0_config1 (void)
! 1172: {
! 1173: T0 = env->CP0_Config1;
! 1174: RETURN();
! 1175: }
! 1176:
! 1177: void op_mfc0_config2 (void)
! 1178: {
! 1179: T0 = env->CP0_Config2;
! 1180: RETURN();
! 1181: }
! 1182:
! 1183: void op_mfc0_config3 (void)
! 1184: {
! 1185: T0 = env->CP0_Config3;
! 1186: RETURN();
! 1187: }
! 1188:
! 1189: void op_mfc0_lladdr (void)
! 1190: {
! 1191: T0 = (int32_t)env->CP0_LLAddr >> 4;
! 1192: RETURN();
! 1193: }
! 1194:
! 1195: void op_mfc0_watchlo0 (void)
! 1196: {
! 1197: T0 = (int32_t)env->CP0_WatchLo;
! 1198: RETURN();
! 1199: }
! 1200:
! 1201: void op_mfc0_watchhi0 (void)
! 1202: {
! 1203: T0 = env->CP0_WatchHi;
! 1204: RETURN();
! 1205: }
! 1206:
! 1207: void op_mfc0_xcontext (void)
! 1208: {
! 1209: T0 = (int32_t)env->CP0_XContext;
! 1210: RETURN();
! 1211: }
! 1212:
! 1213: void op_mfc0_framemask (void)
! 1214: {
! 1215: T0 = env->CP0_Framemask;
! 1216: RETURN();
! 1217: }
! 1218:
! 1219: void op_mfc0_debug (void)
! 1220: {
! 1221: T0 = env->CP0_Debug;
! 1222: if (env->hflags & MIPS_HFLAG_DM)
! 1223: T0 |= 1 << CP0DB_DM;
! 1224: RETURN();
! 1225: }
! 1226:
! 1227: void op_mfc0_depc (void)
! 1228: {
! 1229: T0 = (int32_t)env->CP0_DEPC;
! 1230: RETURN();
! 1231: }
! 1232:
! 1233: void op_mfc0_performance0 (void)
! 1234: {
! 1235: T0 = env->CP0_Performance0;
! 1236: RETURN();
! 1237: }
! 1238:
! 1239: void op_mfc0_taglo (void)
! 1240: {
! 1241: T0 = env->CP0_TagLo;
! 1242: RETURN();
! 1243: }
! 1244:
! 1245: void op_mfc0_datalo (void)
! 1246: {
! 1247: T0 = env->CP0_DataLo;
! 1248: RETURN();
! 1249: }
! 1250:
! 1251: void op_mfc0_taghi (void)
! 1252: {
! 1253: T0 = env->CP0_TagHi;
! 1254: RETURN();
! 1255: }
! 1256:
! 1257: void op_mfc0_datahi (void)
! 1258: {
! 1259: T0 = env->CP0_DataHi;
! 1260: RETURN();
! 1261: }
! 1262:
! 1263: void op_mfc0_errorepc (void)
! 1264: {
! 1265: T0 = (int32_t)env->CP0_ErrorEPC;
! 1266: RETURN();
! 1267: }
! 1268:
! 1269: void op_mfc0_desave (void)
! 1270: {
! 1271: T0 = env->CP0_DESAVE;
! 1272: RETURN();
! 1273: }
! 1274:
! 1275: void op_mtc0_index (void)
! 1276: {
! 1277: env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (MIPS_TLB_NB - 1));
! 1278: RETURN();
! 1279: }
! 1280:
! 1281: void op_mtc0_entrylo0 (void)
! 1282: {
! 1283: /* Large physaddr not implemented */
! 1284: /* 1k pages not implemented */
! 1285: env->CP0_EntryLo0 = (int32_t)T0 & 0x3FFFFFFF;
! 1286: RETURN();
! 1287: }
! 1288:
! 1289: void op_mtc0_entrylo1 (void)
! 1290: {
! 1291: /* Large physaddr not implemented */
! 1292: /* 1k pages not implemented */
! 1293: env->CP0_EntryLo1 = (int32_t)T0 & 0x3FFFFFFF;
! 1294: RETURN();
! 1295: }
! 1296:
! 1297: void op_mtc0_context (void)
! 1298: {
! 1299: env->CP0_Context = (env->CP0_Context & ~0x007FFFFF) | (T0 & 0x007FFFF0);
! 1300: RETURN();
! 1301: }
! 1302:
! 1303: void op_mtc0_pagemask (void)
1.1 root 1304: {
1.1.1.5 ! root 1305: /* 1k pages not implemented */
! 1306: env->CP0_PageMask = T0 & 0x1FFFE000;
1.1 root 1307: RETURN();
1308: }
1309:
1.1.1.5 ! root 1310: void op_mtc0_pagegrain (void)
1.1 root 1311: {
1.1.1.5 ! root 1312: /* SmartMIPS not implemented */
! 1313: /* Large physaddr not implemented */
! 1314: /* 1k pages not implemented */
! 1315: env->CP0_PageGrain = 0;
1.1 root 1316: RETURN();
1317: }
1318:
1.1.1.5 ! root 1319: void op_mtc0_wired (void)
1.1 root 1320: {
1.1.1.5 ! root 1321: env->CP0_Wired = T0 & (MIPS_TLB_NB - 1);
1.1 root 1322: RETURN();
1323: }
1324:
1.1.1.5 ! root 1325: void op_mtc0_hwrena (void)
1.1 root 1326: {
1.1.1.5 ! root 1327: env->CP0_HWREna = T0 & 0x0000000F;
1.1 root 1328: RETURN();
1329: }
1330:
1.1.1.5 ! root 1331: void op_mtc0_count (void)
1.1 root 1332: {
1.1.1.5 ! root 1333: CALL_FROM_TB2(cpu_mips_store_count, env, T0);
1.1 root 1334: RETURN();
1335: }
1336:
1.1.1.5 ! root 1337: void op_mtc0_entryhi (void)
1.1 root 1338: {
1.1.1.5 ! root 1339: target_ulong old, val;
! 1340:
! 1341: /* 1k pages not implemented */
! 1342: /* Ignore MIPS64 TLB for now */
! 1343: val = (int32_t)T0 & 0xFFFFE0FF;
! 1344: old = env->CP0_EntryHi;
! 1345: env->CP0_EntryHi = val;
! 1346: /* If the ASID changes, flush qemu's TLB. */
! 1347: if ((old & 0xFF) != (val & 0xFF))
! 1348: CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1.1 root 1349: RETURN();
1350: }
1351:
1.1.1.5 ! root 1352: void op_mtc0_compare (void)
1.1 root 1353: {
1.1.1.5 ! root 1354: CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1.1 root 1355: RETURN();
1356: }
1357:
1.1.1.5 ! root 1358: void op_mtc0_status (void)
1.1 root 1359: {
1.1.1.5 ! root 1360: uint32_t val, old;
! 1361:
! 1362: val = (int32_t)T0 & 0xFA78FF01;
! 1363: old = env->CP0_Status;
! 1364: if (T0 & (1 << CP0St_UM))
! 1365: env->hflags |= MIPS_HFLAG_UM;
! 1366: else
! 1367: env->hflags &= ~MIPS_HFLAG_UM;
! 1368: if (T0 & (1 << CP0St_ERL))
! 1369: env->hflags |= MIPS_HFLAG_ERL;
! 1370: else
! 1371: env->hflags &= ~MIPS_HFLAG_ERL;
! 1372: if (T0 & (1 << CP0St_EXL))
! 1373: env->hflags |= MIPS_HFLAG_EXL;
! 1374: else
! 1375: env->hflags &= ~MIPS_HFLAG_EXL;
! 1376: env->CP0_Status = val;
! 1377: if (loglevel & CPU_LOG_TB_IN_ASM)
! 1378: CALL_FROM_TB2(do_mtc0_status_debug, old, val);
! 1379: CALL_FROM_TB1(cpu_mips_update_irq, env);
1.1 root 1380: RETURN();
1381: }
1382:
1.1.1.5 ! root 1383: void op_mtc0_intctl (void)
1.1 root 1384: {
1.1.1.5 ! root 1385: /* vectored interrupts not implemented */
! 1386: env->CP0_IntCtl = 0;
1.1 root 1387: RETURN();
1388: }
1389:
1.1.1.5 ! root 1390: void op_mtc0_srsctl (void)
1.1 root 1391: {
1.1.1.5 ! root 1392: /* shadow registers not implemented */
! 1393: env->CP0_SRSCtl = 0;
1.1 root 1394: RETURN();
1395: }
1396:
1.1.1.5 ! root 1397: void op_mtc0_srsmap (void)
1.1 root 1398: {
1.1.1.5 ! root 1399: /* shadow registers not implemented */
! 1400: env->CP0_SRSMap = 0;
1.1 root 1401: RETURN();
1402: }
1403:
1.1.1.5 ! root 1404: void op_mtc0_cause (void)
1.1 root 1405: {
1.1.1.5 ! root 1406: env->CP0_Cause = (env->CP0_Cause & 0xB000F87C) | (T0 & 0x00C00300);
! 1407:
! 1408: /* Handle the software interrupt as an hardware one, as they
! 1409: are very similar */
! 1410: if (T0 & CP0Ca_IP_mask) {
! 1411: CALL_FROM_TB1(cpu_mips_update_irq, env);
! 1412: }
1.1 root 1413: RETURN();
1414: }
1415:
1.1.1.5 ! root 1416: void op_mtc0_epc (void)
1.1 root 1417: {
1.1.1.5 ! root 1418: env->CP0_EPC = (int32_t)T0;
1.1 root 1419: RETURN();
1420: }
1421:
1.1.1.5 ! root 1422: void op_mtc0_ebase (void)
1.1 root 1423: {
1.1.1.5 ! root 1424: /* vectored interrupts not implemented */
! 1425: /* Multi-CPU not implemented */
! 1426: env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
1.1 root 1427: RETURN();
1428: }
1429:
1.1.1.5 ! root 1430: void op_mtc0_config0 (void)
1.1 root 1431: {
1.1.1.5 ! root 1432: #if defined(MIPS_USES_R4K_TLB)
! 1433: /* Fixed mapping MMU not implemented */
! 1434: env->CP0_Config0 = (env->CP0_Config0 & 0x8017FF88) | (T0 & 0x00000001);
! 1435: #else
! 1436: env->CP0_Config0 = (env->CP0_Config0 & 0xFE17FF88) | (T0 & 0x00000001);
! 1437: #endif
1.1 root 1438: RETURN();
1439: }
1440:
1.1.1.5 ! root 1441: void op_mtc0_config2 (void)
1.1 root 1442: {
1.1.1.5 ! root 1443: /* tertiary/secondary caches not implemented */
! 1444: env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
1.1 root 1445: RETURN();
1446: }
1447:
1.1.1.5 ! root 1448: void op_mtc0_watchlo0 (void)
1.1 root 1449: {
1.1.1.5 ! root 1450: env->CP0_WatchLo = (int32_t)T0;
1.1 root 1451: RETURN();
1452: }
1453:
1.1.1.5 ! root 1454: void op_mtc0_watchhi0 (void)
1.1 root 1455: {
1.1.1.5 ! root 1456: env->CP0_WatchHi = T0 & 0x40FF0FF8;
! 1457: RETURN();
1.1 root 1458: }
1459:
1.1.1.5 ! root 1460: void op_mtc0_xcontext (void)
1.1 root 1461: {
1.1.1.5 ! root 1462: env->CP0_XContext = (int32_t)T0; /* XXX */
! 1463: RETURN();
1.1 root 1464: }
1465:
1.1.1.5 ! root 1466: void op_mtc0_framemask (void)
1.1 root 1467: {
1.1.1.5 ! root 1468: env->CP0_Framemask = T0; /* XXX */
1.1 root 1469: RETURN();
1470: }
1471:
1.1.1.5 ! root 1472: void op_mtc0_debug (void)
1.1 root 1473: {
1.1.1.5 ! root 1474: env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
! 1475: if (T0 & (1 << CP0DB_DM))
! 1476: env->hflags |= MIPS_HFLAG_DM;
! 1477: else
! 1478: env->hflags &= ~MIPS_HFLAG_DM;
1.1 root 1479: RETURN();
1480: }
1481:
1.1.1.5 ! root 1482: void op_mtc0_depc (void)
1.1 root 1483: {
1.1.1.5 ! root 1484: env->CP0_DEPC = (int32_t)T0;
1.1 root 1485: RETURN();
1486: }
1487:
1.1.1.5 ! root 1488: void op_mtc0_performance0 (void)
1.1 root 1489: {
1.1.1.5 ! root 1490: env->CP0_Performance0 = T0; /* XXX */
1.1 root 1491: RETURN();
1492: }
1493:
1.1.1.5 ! root 1494: void op_mtc0_taglo (void)
1.1 root 1495: {
1.1.1.5 ! root 1496: env->CP0_TagLo = T0 & 0xFFFFFCF6;
1.1 root 1497: RETURN();
1498: }
1499:
1.1.1.5 ! root 1500: void op_mtc0_datalo (void)
1.1 root 1501: {
1.1.1.5 ! root 1502: env->CP0_DataLo = T0; /* XXX */
1.1 root 1503: RETURN();
1504: }
1.1.1.5 ! root 1505:
! 1506: void op_mtc0_taghi (void)
1.1 root 1507: {
1.1.1.5 ! root 1508: env->CP0_TagHi = T0; /* XXX */
1.1 root 1509: RETURN();
1510: }
1511:
1.1.1.5 ! root 1512: void op_mtc0_datahi (void)
1.1 root 1513: {
1.1.1.5 ! root 1514: env->CP0_DataHi = T0; /* XXX */
1.1 root 1515: RETURN();
1516: }
1517:
1.1.1.5 ! root 1518: void op_mtc0_errorepc (void)
1.1 root 1519: {
1.1.1.5 ! root 1520: env->CP0_ErrorEPC = (int32_t)T0;
1.1 root 1521: RETURN();
1522: }
1523:
1.1.1.5 ! root 1524: void op_mtc0_desave (void)
1.1 root 1525: {
1.1.1.5 ! root 1526: env->CP0_DESAVE = T0;
1.1 root 1527: RETURN();
1528: }
1529:
1.1.1.5 ! root 1530: void op_dmfc0_entrylo0 (void)
1.1 root 1531: {
1.1.1.5 ! root 1532: T0 = env->CP0_EntryLo0;
1.1 root 1533: RETURN();
1534: }
1535:
1.1.1.5 ! root 1536: void op_dmfc0_entrylo1 (void)
1.1 root 1537: {
1.1.1.5 ! root 1538: T0 = env->CP0_EntryLo1;
1.1 root 1539: RETURN();
1540: }
1541:
1.1.1.5 ! root 1542: void op_dmfc0_context (void)
1.1 root 1543: {
1.1.1.5 ! root 1544: T0 = env->CP0_Context;
1.1 root 1545: RETURN();
1546: }
1547:
1.1.1.5 ! root 1548: void op_dmfc0_badvaddr (void)
1.1 root 1549: {
1.1.1.5 ! root 1550: T0 = env->CP0_BadVAddr;
1.1 root 1551: RETURN();
1552: }
1553:
1.1.1.5 ! root 1554: void op_dmfc0_entryhi (void)
! 1555: {
! 1556: T0 = env->CP0_EntryHi;
! 1557: RETURN();
1.1 root 1558: }
1559:
1.1.1.5 ! root 1560: void op_dmfc0_epc (void)
! 1561: {
! 1562: T0 = env->CP0_EPC;
! 1563: RETURN();
! 1564: }
1.1 root 1565:
1.1.1.5 ! root 1566: void op_dmfc0_lladdr (void)
! 1567: {
! 1568: T0 = env->CP0_LLAddr >> 4;
! 1569: RETURN();
! 1570: }
1.1.1.2 root 1571:
1.1.1.5 ! root 1572: void op_dmfc0_watchlo0 (void)
1.1.1.2 root 1573: {
1.1.1.5 ! root 1574: T0 = env->CP0_WatchLo;
! 1575: RETURN();
1.1.1.2 root 1576: }
1577:
1.1.1.5 ! root 1578: void op_dmfc0_xcontext (void)
1.1.1.2 root 1579: {
1.1.1.5 ! root 1580: T0 = env->CP0_XContext;
! 1581: RETURN();
1.1.1.2 root 1582: }
1.1 root 1583:
1.1.1.5 ! root 1584: void op_dmfc0_depc (void)
1.1 root 1585: {
1.1.1.5 ! root 1586: T0 = env->CP0_DEPC;
! 1587: RETURN();
1.1 root 1588: }
1589:
1.1.1.5 ! root 1590: void op_dmfc0_errorepc (void)
1.1 root 1591: {
1.1.1.5 ! root 1592: T0 = env->CP0_ErrorEPC;
! 1593: RETURN();
1.1 root 1594: }
1595:
1.1.1.5 ! root 1596: void op_dmtc0_entrylo0 (void)
1.1 root 1597: {
1.1.1.5 ! root 1598: /* Large physaddr not implemented */
! 1599: /* 1k pages not implemented */
! 1600: env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
1.1 root 1601: RETURN();
1602: }
1603:
1.1.1.5 ! root 1604: void op_dmtc0_entrylo1 (void)
1.1 root 1605: {
1.1.1.5 ! root 1606: /* Large physaddr not implemented */
! 1607: /* 1k pages not implemented */
! 1608: env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
1.1 root 1609: RETURN();
1610: }
1611:
1.1.1.5 ! root 1612: void op_dmtc0_context (void)
1.1 root 1613: {
1.1.1.5 ! root 1614: env->CP0_Context = (env->CP0_Context & ~0x007FFFFF) | (T0 & 0x007FFFF0);
1.1 root 1615: RETURN();
1616: }
1617:
1.1.1.5 ! root 1618: void op_dmtc0_epc (void)
1.1 root 1619: {
1.1.1.5 ! root 1620: env->CP0_EPC = T0;
1.1 root 1621: RETURN();
1622: }
1623:
1.1.1.5 ! root 1624: void op_dmtc0_watchlo0 (void)
1.1 root 1625: {
1.1.1.5 ! root 1626: env->CP0_WatchLo = T0;
1.1 root 1627: RETURN();
1628: }
1629:
1.1.1.5 ! root 1630: void op_dmtc0_xcontext (void)
1.1 root 1631: {
1.1.1.5 ! root 1632: env->CP0_XContext = T0; /* XXX */
1.1 root 1633: RETURN();
1634: }
1635:
1.1.1.5 ! root 1636: void op_dmtc0_depc (void)
1.1 root 1637: {
1.1.1.5 ! root 1638: env->CP0_DEPC = T0;
1.1 root 1639: RETURN();
1640: }
1641:
1.1.1.5 ! root 1642: void op_dmtc0_errorepc (void)
1.1 root 1643: {
1.1.1.5 ! root 1644: env->CP0_ErrorEPC = T0;
1.1 root 1645: RETURN();
1646: }
1647:
1.1.1.4 root 1648: #ifdef MIPS_USES_FPU
1649:
1650: #if 0
1651: # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
1652: #else
1653: # define DEBUG_FPU_STATE() do { } while(0)
1654: #endif
1655:
1656: void op_cp1_enabled(void)
1657: {
1658: if (!(env->CP0_Status & (1 << CP0St_CU1))) {
1659: CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1);
1660: }
1661: RETURN();
1662: }
1663:
1664: /* CP1 functions */
1665: void op_cfc1 (void)
1666: {
1667: if (T1 == 0) {
1668: T0 = env->fcr0;
1669: }
1670: else {
1671: /* fetch fcr31, masking unused bits */
1672: T0 = env->fcr31 & 0x0183FFFF;
1673: }
1674: DEBUG_FPU_STATE();
1675: RETURN();
1676: }
1677:
1678: /* convert MIPS rounding mode in FCR31 to IEEE library */
1679: unsigned int ieee_rm[] = {
1680: float_round_nearest_even,
1681: float_round_to_zero,
1682: float_round_up,
1683: float_round_down
1684: };
1685:
1686: #define RESTORE_ROUNDING_MODE \
1687: set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)
1688:
1689: void op_ctc1 (void)
1690: {
1691: if (T1 == 0) {
1692: /* XXX should this throw an exception?
1693: * don't write to FCR0.
1694: * env->fcr0 = T0;
1695: */
1696: }
1697: else {
1698: /* store new fcr31, masking unused bits */
1699: env->fcr31 = T0 & 0x0183FFFF;
1700:
1701: /* set rounding mode */
1702: RESTORE_ROUNDING_MODE;
1703:
1704: #ifndef CONFIG_SOFTFLOAT
1705: /* no floating point exception for native float */
1706: SET_FP_ENABLE(env->fcr31, 0);
1707: #endif
1708: }
1709: DEBUG_FPU_STATE();
1710: RETURN();
1711: }
1712:
1713: void op_mfc1 (void)
1714: {
1715: T0 = WT0;
1716: DEBUG_FPU_STATE();
1717: RETURN();
1718: }
1719:
1720: void op_mtc1 (void)
1721: {
1722: WT0 = T0;
1723: DEBUG_FPU_STATE();
1724: RETURN();
1725: }
1726:
1727: /* Float support.
1728: Single precition routines have a "s" suffix, double precision a
1729: "d" suffix. */
1730:
1731: #define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
1732:
1.1.1.5 ! root 1733: FLOAT_OP(cvtd, s)
! 1734: {
! 1735: FDT2 = float32_to_float64(WT0, &env->fp_status);
! 1736: DEBUG_FPU_STATE();
! 1737: RETURN();
! 1738: }
1.1.1.4 root 1739: FLOAT_OP(cvtd, w)
1740: {
1741: FDT2 = int32_to_float64(WT0, &env->fp_status);
1742: DEBUG_FPU_STATE();
1743: RETURN();
1744: }
1.1.1.5 ! root 1745: FLOAT_OP(cvts, d)
! 1746: {
! 1747: FST2 = float64_to_float32(FDT0, &env->fp_status);
! 1748: DEBUG_FPU_STATE();
! 1749: RETURN();
! 1750: }
1.1.1.4 root 1751: FLOAT_OP(cvts, w)
1752: {
1753: FST2 = int32_to_float32(WT0, &env->fp_status);
1754: DEBUG_FPU_STATE();
1755: RETURN();
1756: }
1757: FLOAT_OP(cvtw, s)
1758: {
1759: WT2 = float32_to_int32(FST0, &env->fp_status);
1760: DEBUG_FPU_STATE();
1761: RETURN();
1762: }
1763: FLOAT_OP(cvtw, d)
1764: {
1765: WT2 = float64_to_int32(FDT0, &env->fp_status);
1766: DEBUG_FPU_STATE();
1767: RETURN();
1768: }
1769:
1770: FLOAT_OP(roundw, d)
1771: {
1772: set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1773: WT2 = float64_round_to_int(FDT0, &env->fp_status);
1774: RESTORE_ROUNDING_MODE;
1775:
1776: DEBUG_FPU_STATE();
1777: RETURN();
1778: }
1779: FLOAT_OP(roundw, s)
1780: {
1781: set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
1782: WT2 = float32_round_to_int(FST0, &env->fp_status);
1783: RESTORE_ROUNDING_MODE;
1784: DEBUG_FPU_STATE();
1785: RETURN();
1786: }
1787:
1788: FLOAT_OP(truncw, d)
1789: {
1790: WT2 = float64_to_int32_round_to_zero(FDT0, &env->fp_status);
1791: DEBUG_FPU_STATE();
1792: RETURN();
1793: }
1794: FLOAT_OP(truncw, s)
1795: {
1796: WT2 = float32_to_int32_round_to_zero(FST0, &env->fp_status);
1797: DEBUG_FPU_STATE();
1798: RETURN();
1799: }
1800:
1801: FLOAT_OP(ceilw, d)
1802: {
1803: set_float_rounding_mode(float_round_up, &env->fp_status);
1804: WT2 = float64_round_to_int(FDT0, &env->fp_status);
1805: RESTORE_ROUNDING_MODE;
1806:
1807: DEBUG_FPU_STATE();
1808: RETURN();
1809: }
1810: FLOAT_OP(ceilw, s)
1811: {
1812: set_float_rounding_mode(float_round_up, &env->fp_status);
1813: WT2 = float32_round_to_int(FST0, &env->fp_status);
1814: RESTORE_ROUNDING_MODE;
1815: DEBUG_FPU_STATE();
1816: RETURN();
1817: }
1818:
1819: FLOAT_OP(floorw, d)
1820: {
1821: set_float_rounding_mode(float_round_down, &env->fp_status);
1822: WT2 = float64_round_to_int(FDT0, &env->fp_status);
1823: RESTORE_ROUNDING_MODE;
1824:
1825: DEBUG_FPU_STATE();
1826: RETURN();
1827: }
1828: FLOAT_OP(floorw, s)
1829: {
1830: set_float_rounding_mode(float_round_down, &env->fp_status);
1831: WT2 = float32_round_to_int(FST0, &env->fp_status);
1832: RESTORE_ROUNDING_MODE;
1833: DEBUG_FPU_STATE();
1834: RETURN();
1835: }
1836:
1837: /* binary operations */
1838: #define FLOAT_BINOP(name) \
1839: FLOAT_OP(name, d) \
1840: { \
1841: FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status); \
1842: DEBUG_FPU_STATE(); \
1843: } \
1844: FLOAT_OP(name, s) \
1845: { \
1846: FST2 = float32_ ## name (FST0, FST1, &env->fp_status); \
1847: DEBUG_FPU_STATE(); \
1848: }
1849: FLOAT_BINOP(add)
1850: FLOAT_BINOP(sub)
1851: FLOAT_BINOP(mul)
1852: FLOAT_BINOP(div)
1853: #undef FLOAT_BINOP
1854:
1855: /* unary operations, modifying fp status */
1856: #define FLOAT_UNOP(name) \
1857: FLOAT_OP(name, d) \
1858: { \
1859: FDT2 = float64_ ## name(FDT0, &env->fp_status); \
1860: DEBUG_FPU_STATE(); \
1861: } \
1862: FLOAT_OP(name, s) \
1863: { \
1864: FST2 = float32_ ## name(FST0, &env->fp_status); \
1865: DEBUG_FPU_STATE(); \
1866: }
1867: FLOAT_UNOP(sqrt)
1868: #undef FLOAT_UNOP
1869:
1870: /* unary operations, not modifying fp status */
1871: #define FLOAT_UNOP(name) \
1872: FLOAT_OP(name, d) \
1873: { \
1874: FDT2 = float64_ ## name(FDT0); \
1875: DEBUG_FPU_STATE(); \
1876: } \
1877: FLOAT_OP(name, s) \
1878: { \
1879: FST2 = float32_ ## name(FST0); \
1880: DEBUG_FPU_STATE(); \
1881: }
1882: FLOAT_UNOP(abs)
1883: FLOAT_UNOP(chs)
1884: #undef FLOAT_UNOP
1885:
1886: FLOAT_OP(mov, d)
1887: {
1888: FDT2 = FDT0;
1889: DEBUG_FPU_STATE();
1890: RETURN();
1891: }
1892: FLOAT_OP(mov, s)
1893: {
1894: FST2 = FST0;
1895: DEBUG_FPU_STATE();
1896: RETURN();
1897: }
1898:
1899: #ifdef CONFIG_SOFTFLOAT
1900: #define clear_invalid() do { \
1901: int flags = get_float_exception_flags(&env->fp_status); \
1902: flags &= ~float_flag_invalid; \
1903: set_float_exception_flags(flags, &env->fp_status); \
1904: } while(0)
1905: #else
1906: #define clear_invalid() do { } while(0)
1907: #endif
1908:
1909: extern void dump_fpu_s(CPUState *env);
1910:
1911: #define FOP_COND(fmt, op, sig, cond) \
1912: void op_cmp_ ## fmt ## _ ## op (void) \
1913: { \
1914: if (cond) \
1915: SET_FP_COND(env->fcr31); \
1916: else \
1917: CLEAR_FP_COND(env->fcr31); \
1918: if (!sig) \
1919: clear_invalid(); \
1920: /*CALL_FROM_TB1(dump_fpu_s, env);*/ \
1921: DEBUG_FPU_STATE(); \
1922: RETURN(); \
1923: }
1924:
1.1.1.5 ! root 1925: int float64_is_unordered(float64 a, float64 b STATUS_PARAM)
1.1.1.4 root 1926: {
1927: if (float64_is_nan(a) || float64_is_nan(b)) {
1928: float_raise(float_flag_invalid, status);
1929: return 1;
1930: }
1931: else {
1932: return 0;
1933: }
1934: }
1935:
1936: FOP_COND(d, f, 0, 0)
1937: FOP_COND(d, un, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status))
1938: FOP_COND(d, eq, 0, float64_eq(FDT0, FDT1, &env->fp_status))
1939: FOP_COND(d, ueq, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
1940: FOP_COND(d, olt, 0, float64_lt(FDT0, FDT1, &env->fp_status))
1941: FOP_COND(d, ult, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
1942: FOP_COND(d, ole, 0, float64_le(FDT0, FDT1, &env->fp_status))
1943: FOP_COND(d, ule, 0, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
1944: /* NOTE: the comma operator will make "cond" to eval to false,
1945: * but float*_is_unordered() is still called
1946: */
1947: FOP_COND(d, sf, 1, (float64_is_unordered(FDT0, FDT1, &env->fp_status), 0))
1948: FOP_COND(d, ngle,1, float64_is_unordered(FDT1, FDT0, &env->fp_status))
1949: FOP_COND(d, seq, 1, float64_eq(FDT0, FDT1, &env->fp_status))
1950: FOP_COND(d, ngl, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_eq(FDT0, FDT1, &env->fp_status))
1951: FOP_COND(d, lt, 1, float64_lt(FDT0, FDT1, &env->fp_status))
1952: FOP_COND(d, nge, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_lt(FDT0, FDT1, &env->fp_status))
1953: FOP_COND(d, le, 1, float64_le(FDT0, FDT1, &env->fp_status))
1954: FOP_COND(d, ngt, 1, float64_is_unordered(FDT1, FDT0, &env->fp_status) || float64_le(FDT0, FDT1, &env->fp_status))
1955:
1956: flag float32_is_unordered(float32 a, float32 b STATUS_PARAM)
1957: {
1958: extern flag float32_is_nan( float32 a );
1959: if (float32_is_nan(a) || float32_is_nan(b)) {
1960: float_raise(float_flag_invalid, status);
1961: return 1;
1962: }
1963: else {
1964: return 0;
1965: }
1966: }
1967:
1968: /* NOTE: the comma operator will make "cond" to eval to false,
1969: * but float*_is_unordered() is still called
1970: */
1971: FOP_COND(s, f, 0, 0)
1972: FOP_COND(s, un, 0, float32_is_unordered(FST1, FST0, &env->fp_status))
1973: FOP_COND(s, eq, 0, float32_eq(FST0, FST1, &env->fp_status))
1974: FOP_COND(s, ueq, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
1975: FOP_COND(s, olt, 0, float32_lt(FST0, FST1, &env->fp_status))
1976: FOP_COND(s, ult, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
1977: FOP_COND(s, ole, 0, float32_le(FST0, FST1, &env->fp_status))
1978: FOP_COND(s, ule, 0, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
1979: /* NOTE: the comma operator will make "cond" to eval to false,
1980: * but float*_is_unordered() is still called
1981: */
1982: FOP_COND(s, sf, 1, (float32_is_unordered(FST0, FST1, &env->fp_status), 0))
1983: FOP_COND(s, ngle,1, float32_is_unordered(FST1, FST0, &env->fp_status))
1984: FOP_COND(s, seq, 1, float32_eq(FST0, FST1, &env->fp_status))
1985: FOP_COND(s, ngl, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_eq(FST0, FST1, &env->fp_status))
1986: FOP_COND(s, lt, 1, float32_lt(FST0, FST1, &env->fp_status))
1987: FOP_COND(s, nge, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_lt(FST0, FST1, &env->fp_status))
1988: FOP_COND(s, le, 1, float32_le(FST0, FST1, &env->fp_status))
1989: FOP_COND(s, ngt, 1, float32_is_unordered(FST1, FST0, &env->fp_status) || float32_le(FST0, FST1, &env->fp_status))
1990:
1991: void op_bc1f (void)
1992: {
1993: T0 = ! IS_FP_COND_SET(env->fcr31);
1994: DEBUG_FPU_STATE();
1995: RETURN();
1996: }
1997:
1998: void op_bc1t (void)
1999: {
2000: T0 = IS_FP_COND_SET(env->fcr31);
2001: DEBUG_FPU_STATE();
2002: RETURN();
2003: }
2004: #endif /* MIPS_USES_FPU */
2005:
1.1 root 2006: #if defined(MIPS_USES_R4K_TLB)
2007: void op_tlbwi (void)
2008: {
2009: CALL_FROM_TB0(do_tlbwi);
2010: RETURN();
2011: }
2012:
2013: void op_tlbwr (void)
2014: {
2015: CALL_FROM_TB0(do_tlbwr);
2016: RETURN();
2017: }
2018:
2019: void op_tlbp (void)
2020: {
2021: CALL_FROM_TB0(do_tlbp);
2022: RETURN();
2023: }
2024:
2025: void op_tlbr (void)
2026: {
2027: CALL_FROM_TB0(do_tlbr);
2028: RETURN();
2029: }
2030: #endif
2031:
2032: /* Specials */
2033: void op_pmon (void)
2034: {
2035: CALL_FROM_TB1(do_pmon, PARAM1);
1.1.1.5 ! root 2036: RETURN();
! 2037: }
! 2038:
! 2039: void op_di (void)
! 2040: {
! 2041: T0 = env->CP0_Status;
! 2042: env->CP0_Status = T0 & ~(1 << CP0St_IE);
! 2043: CALL_FROM_TB1(cpu_mips_update_irq, env);
! 2044: RETURN();
! 2045: }
! 2046:
! 2047: void op_ei (void)
! 2048: {
! 2049: T0 = env->CP0_Status;
! 2050: env->CP0_Status = T0 | (1 << CP0St_IE);
! 2051: CALL_FROM_TB1(cpu_mips_update_irq, env);
! 2052: RETURN();
1.1 root 2053: }
2054:
2055: void op_trap (void)
2056: {
2057: if (T0) {
1.1.1.2 root 2058: CALL_FROM_TB1(do_raise_exception_direct, EXCP_TRAP);
1.1 root 2059: }
2060: RETURN();
2061: }
2062:
1.1.1.2 root 2063: void op_debug (void)
2064: {
1.1.1.5 ! root 2065: CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
! 2066: RETURN();
1.1.1.2 root 2067: }
2068:
1.1 root 2069: void op_set_lladdr (void)
2070: {
2071: env->CP0_LLAddr = T2;
1.1.1.5 ! root 2072: RETURN();
1.1 root 2073: }
2074:
2075: void debug_eret (void);
2076: void op_eret (void)
2077: {
2078: CALL_FROM_TB0(debug_eret);
2079: if (env->hflags & MIPS_HFLAG_ERL) {
2080: env->PC = env->CP0_ErrorEPC;
2081: env->hflags &= ~MIPS_HFLAG_ERL;
1.1.1.4 root 2082: env->CP0_Status &= ~(1 << CP0St_ERL);
1.1 root 2083: } else {
2084: env->PC = env->CP0_EPC;
2085: env->hflags &= ~MIPS_HFLAG_EXL;
1.1.1.4 root 2086: env->CP0_Status &= ~(1 << CP0St_EXL);
1.1 root 2087: }
2088: env->CP0_LLAddr = 1;
1.1.1.5 ! root 2089: RETURN();
1.1 root 2090: }
2091:
2092: void op_deret (void)
2093: {
2094: CALL_FROM_TB0(debug_eret);
2095: env->PC = env->CP0_DEPC;
1.1.1.5 ! root 2096: RETURN();
! 2097: }
! 2098:
! 2099: void op_rdhwr_cpunum(void)
! 2100: {
! 2101: if (env->CP0_HWREna & (1 << 0))
! 2102: T0 = env->CP0_EBase & 0x2ff;
! 2103: else
! 2104: CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
! 2105: RETURN();
! 2106: }
! 2107:
! 2108: void op_rdhwr_synci_step(void)
! 2109: {
! 2110: if (env->CP0_HWREna & (1 << 1))
! 2111: T0 = env->SYNCI_Step;
! 2112: else
! 2113: CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
! 2114: RETURN();
! 2115: }
! 2116:
! 2117: void op_rdhwr_cc(void)
! 2118: {
! 2119: if (env->CP0_HWREna & (1 << 2))
! 2120: T0 = env->CP0_Count;
! 2121: else
! 2122: CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
! 2123: RETURN();
! 2124: }
! 2125:
! 2126: void op_rdhwr_ccres(void)
! 2127: {
! 2128: if (env->CP0_HWREna & (1 << 3))
! 2129: T0 = env->CCRes;
! 2130: else
! 2131: CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
! 2132: RETURN();
1.1 root 2133: }
2134:
2135: void op_save_state (void)
2136: {
2137: env->hflags = PARAM1;
2138: RETURN();
2139: }
2140:
2141: void op_save_pc (void)
2142: {
2143: env->PC = PARAM1;
2144: RETURN();
2145: }
2146:
2147: void op_raise_exception (void)
2148: {
2149: CALL_FROM_TB1(do_raise_exception, PARAM1);
2150: RETURN();
2151: }
2152:
2153: void op_raise_exception_err (void)
2154: {
2155: CALL_FROM_TB2(do_raise_exception_err, PARAM1, PARAM2);
2156: RETURN();
2157: }
2158:
2159: void op_exit_tb (void)
2160: {
2161: EXIT_TB();
1.1.1.5 ! root 2162: RETURN();
1.1 root 2163: }
2164:
1.1.1.2 root 2165: void op_wait (void)
2166: {
2167: env->halted = 1;
2168: CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
1.1.1.5 ! root 2169: RETURN();
! 2170: }
! 2171:
! 2172: /* Bitfield operations. */
! 2173: void op_ext(void)
! 2174: {
! 2175: unsigned int pos = PARAM1;
! 2176: unsigned int size = PARAM2;
! 2177:
! 2178: T0 = ((uint32_t)T1 >> pos) & ((1 << size) - 1);
! 2179: RETURN();
! 2180: }
! 2181:
! 2182: void op_ins(void)
! 2183: {
! 2184: unsigned int pos = PARAM1;
! 2185: unsigned int size = PARAM2;
! 2186: target_ulong mask = ((1 << size) - 1) << pos;
! 2187:
! 2188: T0 = (T2 & ~mask) | (((uint32_t)T1 << pos) & mask);
! 2189: RETURN();
! 2190: }
! 2191:
! 2192: void op_wsbh(void)
! 2193: {
! 2194: T0 = ((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF);
! 2195: RETURN();
! 2196: }
! 2197:
! 2198: #ifdef MIPS_HAS_MIPS64
! 2199: void op_dext(void)
! 2200: {
! 2201: unsigned int pos = PARAM1;
! 2202: unsigned int size = PARAM2;
! 2203:
! 2204: T0 = (T1 >> pos) & ((1 << size) - 1);
! 2205: RETURN();
! 2206: }
! 2207:
! 2208: void op_dins(void)
! 2209: {
! 2210: unsigned int pos = PARAM1;
! 2211: unsigned int size = PARAM2;
! 2212: target_ulong mask = ((1 << size) - 1) << pos;
! 2213:
! 2214: T0 = (T2 & ~mask) | ((T1 << pos) & mask);
! 2215: RETURN();
! 2216: }
! 2217:
! 2218: void op_dsbh(void)
! 2219: {
! 2220: T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
! 2221: RETURN();
! 2222: }
! 2223:
! 2224: void op_dshd(void)
! 2225: {
! 2226: T0 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
! 2227: RETURN();
! 2228: }
! 2229: #endif
! 2230:
! 2231: void op_seb(void)
! 2232: {
! 2233: T0 = ((T1 & 0xFF) ^ 0x80) - 0x80;
! 2234: RETURN();
! 2235: }
! 2236:
! 2237: void op_seh(void)
! 2238: {
! 2239: T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000;
! 2240: RETURN();
1.1.1.2 root 2241: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.