|
|
1.1 root 1: /*
2: * MIPS emulation micro-operations for qemu.
1.1.1.6 ! root 3: *
1.1 root 4: * Copyright (c) 2004-2005 Jocelyn Mayer
1.1.1.4 root 5: * Copyright (c) 2006 Marius Groeger (FPU operations)
1.1.1.6 ! root 6: * Copyright (c) 2007 Thiemo Seufer (64-bit FPU support)
1.1 root 7: *
8: * This library is free software; you can redistribute it and/or
9: * modify it under the terms of the GNU Lesser General Public
10: * License as published by the Free Software Foundation; either
11: * version 2 of the License, or (at your option) any later version.
12: *
13: * This library is distributed in the hope that it will be useful,
14: * but WITHOUT ANY WARRANTY; without even the implied warranty of
15: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16: * Lesser General Public License for more details.
17: *
18: * You should have received a copy of the GNU Lesser General Public
19: * License along with this library; if not, write to the Free Software
20: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21: */
22:
23: #include "config.h"
24: #include "exec.h"
1.1.1.6 ! root 25: #include "host-utils.h"
1.1 root 26:
27: #ifndef CALL_FROM_TB0
1.1.1.6 ! root 28: #define CALL_FROM_TB0(func) func()
1.1 root 29: #endif
30: #ifndef CALL_FROM_TB1
1.1.1.6 ! root 31: #define CALL_FROM_TB1(func, arg0) func(arg0)
1.1 root 32: #endif
33: #ifndef CALL_FROM_TB1_CONST16
1.1.1.6 ! root 34: #define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0)
1.1 root 35: #endif
36: #ifndef CALL_FROM_TB2
1.1.1.6 ! root 37: #define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1)
1.1 root 38: #endif
39: #ifndef CALL_FROM_TB2_CONST16
40: #define CALL_FROM_TB2_CONST16(func, arg0, arg1) \
1.1.1.6 ! root 41: CALL_FROM_TB2(func, arg0, arg1)
1.1 root 42: #endif
43: #ifndef CALL_FROM_TB3
1.1.1.6 ! root 44: #define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2)
1.1 root 45: #endif
46: #ifndef CALL_FROM_TB4
47: #define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \
1.1.1.6 ! root 48: func(arg0, arg1, arg2, arg3)
1.1 root 49: #endif
50:
51: #define REG 1
52: #include "op_template.c"
53: #undef REG
54: #define REG 2
55: #include "op_template.c"
56: #undef REG
57: #define REG 3
58: #include "op_template.c"
59: #undef REG
60: #define REG 4
61: #include "op_template.c"
62: #undef REG
63: #define REG 5
64: #include "op_template.c"
65: #undef REG
66: #define REG 6
67: #include "op_template.c"
68: #undef REG
69: #define REG 7
70: #include "op_template.c"
71: #undef REG
72: #define REG 8
73: #include "op_template.c"
74: #undef REG
75: #define REG 9
76: #include "op_template.c"
77: #undef REG
78: #define REG 10
79: #include "op_template.c"
80: #undef REG
81: #define REG 11
82: #include "op_template.c"
83: #undef REG
84: #define REG 12
85: #include "op_template.c"
86: #undef REG
87: #define REG 13
88: #include "op_template.c"
89: #undef REG
90: #define REG 14
91: #include "op_template.c"
92: #undef REG
93: #define REG 15
94: #include "op_template.c"
95: #undef REG
96: #define REG 16
97: #include "op_template.c"
98: #undef REG
99: #define REG 17
100: #include "op_template.c"
101: #undef REG
102: #define REG 18
103: #include "op_template.c"
104: #undef REG
105: #define REG 19
106: #include "op_template.c"
107: #undef REG
108: #define REG 20
109: #include "op_template.c"
110: #undef REG
111: #define REG 21
112: #include "op_template.c"
113: #undef REG
114: #define REG 22
115: #include "op_template.c"
116: #undef REG
117: #define REG 23
118: #include "op_template.c"
119: #undef REG
120: #define REG 24
121: #include "op_template.c"
122: #undef REG
123: #define REG 25
124: #include "op_template.c"
125: #undef REG
126: #define REG 26
127: #include "op_template.c"
128: #undef REG
129: #define REG 27
130: #include "op_template.c"
131: #undef REG
132: #define REG 28
133: #include "op_template.c"
134: #undef REG
135: #define REG 29
136: #include "op_template.c"
137: #undef REG
138: #define REG 30
139: #include "op_template.c"
140: #undef REG
141: #define REG 31
142: #include "op_template.c"
143: #undef REG
144:
1.1.1.5 root 145: #define TN
1.1 root 146: #include "op_template.c"
147: #undef TN
148:
1.1.1.6 ! root 149: #define FREG 0
1.1.1.4 root 150: #include "fop_template.c"
1.1.1.6 ! root 151: #undef FREG
! 152: #define FREG 1
1.1.1.4 root 153: #include "fop_template.c"
1.1.1.6 ! root 154: #undef FREG
! 155: #define FREG 2
1.1.1.4 root 156: #include "fop_template.c"
1.1.1.6 ! root 157: #undef FREG
! 158: #define FREG 3
1.1.1.4 root 159: #include "fop_template.c"
1.1.1.6 ! root 160: #undef FREG
! 161: #define FREG 4
1.1.1.4 root 162: #include "fop_template.c"
1.1.1.6 ! root 163: #undef FREG
! 164: #define FREG 5
1.1.1.4 root 165: #include "fop_template.c"
1.1.1.6 ! root 166: #undef FREG
! 167: #define FREG 6
1.1.1.4 root 168: #include "fop_template.c"
1.1.1.6 ! root 169: #undef FREG
! 170: #define FREG 7
1.1.1.4 root 171: #include "fop_template.c"
1.1.1.6 ! root 172: #undef FREG
! 173: #define FREG 8
1.1.1.4 root 174: #include "fop_template.c"
1.1.1.6 ! root 175: #undef FREG
! 176: #define FREG 9
1.1.1.4 root 177: #include "fop_template.c"
1.1.1.6 ! root 178: #undef FREG
! 179: #define FREG 10
1.1.1.4 root 180: #include "fop_template.c"
1.1.1.6 ! root 181: #undef FREG
! 182: #define FREG 11
1.1.1.4 root 183: #include "fop_template.c"
1.1.1.6 ! root 184: #undef FREG
! 185: #define FREG 12
1.1.1.4 root 186: #include "fop_template.c"
1.1.1.6 ! root 187: #undef FREG
! 188: #define FREG 13
1.1.1.4 root 189: #include "fop_template.c"
1.1.1.6 ! root 190: #undef FREG
! 191: #define FREG 14
1.1.1.4 root 192: #include "fop_template.c"
1.1.1.6 ! root 193: #undef FREG
! 194: #define FREG 15
1.1.1.4 root 195: #include "fop_template.c"
1.1.1.6 ! root 196: #undef FREG
! 197: #define FREG 16
1.1.1.4 root 198: #include "fop_template.c"
1.1.1.6 ! root 199: #undef FREG
! 200: #define FREG 17
1.1.1.4 root 201: #include "fop_template.c"
1.1.1.6 ! root 202: #undef FREG
! 203: #define FREG 18
1.1.1.4 root 204: #include "fop_template.c"
1.1.1.6 ! root 205: #undef FREG
! 206: #define FREG 19
1.1.1.4 root 207: #include "fop_template.c"
1.1.1.6 ! root 208: #undef FREG
! 209: #define FREG 20
1.1.1.4 root 210: #include "fop_template.c"
1.1.1.6 ! root 211: #undef FREG
! 212: #define FREG 21
1.1.1.4 root 213: #include "fop_template.c"
1.1.1.6 ! root 214: #undef FREG
! 215: #define FREG 22
1.1.1.4 root 216: #include "fop_template.c"
1.1.1.6 ! root 217: #undef FREG
! 218: #define FREG 23
1.1.1.4 root 219: #include "fop_template.c"
1.1.1.6 ! root 220: #undef FREG
! 221: #define FREG 24
1.1.1.4 root 222: #include "fop_template.c"
1.1.1.6 ! root 223: #undef FREG
! 224: #define FREG 25
1.1.1.4 root 225: #include "fop_template.c"
1.1.1.6 ! root 226: #undef FREG
! 227: #define FREG 26
1.1.1.4 root 228: #include "fop_template.c"
1.1.1.6 ! root 229: #undef FREG
! 230: #define FREG 27
1.1.1.4 root 231: #include "fop_template.c"
1.1.1.6 ! root 232: #undef FREG
! 233: #define FREG 28
1.1.1.4 root 234: #include "fop_template.c"
1.1.1.6 ! root 235: #undef FREG
! 236: #define FREG 29
1.1.1.4 root 237: #include "fop_template.c"
1.1.1.6 ! root 238: #undef FREG
! 239: #define FREG 30
1.1.1.4 root 240: #include "fop_template.c"
1.1.1.6 ! root 241: #undef FREG
! 242: #define FREG 31
1.1.1.4 root 243: #include "fop_template.c"
1.1.1.6 ! root 244: #undef FREG
1.1.1.4 root 245:
246: #define FTN
247: #include "fop_template.c"
248: #undef FTN
249:
1.1 root 250: void op_dup_T0 (void)
251: {
252: T2 = T0;
1.1.1.6 ! root 253: FORCE_RET();
1.1 root 254: }
255:
256: void op_load_HI (void)
257: {
1.1.1.6 ! root 258: T0 = env->HI[PARAM1][env->current_tc];
! 259: FORCE_RET();
1.1 root 260: }
261:
262: void op_store_HI (void)
263: {
1.1.1.6 ! root 264: env->HI[PARAM1][env->current_tc] = T0;
! 265: FORCE_RET();
1.1 root 266: }
267:
268: void op_load_LO (void)
269: {
1.1.1.6 ! root 270: T0 = env->LO[PARAM1][env->current_tc];
! 271: FORCE_RET();
1.1 root 272: }
273:
274: void op_store_LO (void)
275: {
1.1.1.6 ! root 276: env->LO[PARAM1][env->current_tc] = T0;
! 277: FORCE_RET();
1.1 root 278: }
279:
280: /* Load and store */
281: #define MEMSUFFIX _raw
282: #include "op_mem.c"
283: #undef MEMSUFFIX
284: #if !defined(CONFIG_USER_ONLY)
285: #define MEMSUFFIX _user
286: #include "op_mem.c"
287: #undef MEMSUFFIX
288:
1.1.1.6 ! root 289: #define MEMSUFFIX _super
! 290: #include "op_mem.c"
! 291: #undef MEMSUFFIX
! 292:
1.1 root 293: #define MEMSUFFIX _kernel
294: #include "op_mem.c"
295: #undef MEMSUFFIX
296: #endif
297:
1.1.1.6 ! root 298: /* Addresses computation */
! 299: void op_addr_add (void)
! 300: {
! 301: /* For compatibility with 32-bit code, data reference in user mode
! 302: with Status_UX = 0 should be casted to 32-bit and sign extended.
! 303: See the MIPS64 PRA manual, section 4.10. */
! 304: #if defined(TARGET_MIPS64)
! 305: if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
! 306: !(env->CP0_Status & (1 << CP0St_UX)))
! 307: T0 = (int64_t)(int32_t)(T0 + T1);
! 308: else
! 309: #endif
! 310: T0 += T1;
! 311: FORCE_RET();
! 312: }
! 313:
1.1 root 314: /* Arithmetic */
315: void op_add (void)
316: {
1.1.1.5 root 317: T0 = (int32_t)((int32_t)T0 + (int32_t)T1);
1.1.1.6 ! root 318: FORCE_RET();
1.1 root 319: }
320:
321: void op_addo (void)
322: {
323: target_ulong tmp;
324:
1.1.1.5 root 325: tmp = (int32_t)T0;
326: T0 = (int32_t)T0 + (int32_t)T1;
327: if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
328: /* operands of same sign, result different sign */
1.1.1.6 ! root 329: CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
1.1.1.5 root 330: }
331: T0 = (int32_t)T0;
1.1.1.6 ! root 332: FORCE_RET();
1.1.1.5 root 333: }
334:
335: void op_sub (void)
336: {
337: T0 = (int32_t)((int32_t)T0 - (int32_t)T1);
1.1.1.6 ! root 338: FORCE_RET();
1.1.1.5 root 339: }
340:
341: void op_subo (void)
342: {
343: target_ulong tmp;
344:
345: tmp = (int32_t)T0;
346: T0 = (int32_t)T0 - (int32_t)T1;
347: if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
348: /* operands of different sign, first operand and result different sign */
1.1.1.6 ! root 349: CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
1.1.1.5 root 350: }
351: T0 = (int32_t)T0;
1.1.1.6 ! root 352: FORCE_RET();
1.1.1.5 root 353: }
354:
355: void op_mul (void)
356: {
357: T0 = (int32_t)((int32_t)T0 * (int32_t)T1);
1.1.1.6 ! root 358: FORCE_RET();
1.1.1.5 root 359: }
360:
1.1.1.6 ! root 361: #if HOST_LONG_BITS < 64
! 362: void op_div (void)
! 363: {
! 364: CALL_FROM_TB0(do_div);
! 365: FORCE_RET();
! 366: }
! 367: #else
1.1.1.5 root 368: void op_div (void)
369: {
370: if (T1 != 0) {
1.1.1.6 ! root 371: env->LO[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
! 372: env->HI[0][env->current_tc] = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
1.1.1.5 root 373: }
1.1.1.6 ! root 374: FORCE_RET();
1.1.1.5 root 375: }
1.1.1.6 ! root 376: #endif
1.1.1.5 root 377:
378: void op_divu (void)
379: {
380: if (T1 != 0) {
1.1.1.6 ! root 381: env->LO[0][env->current_tc] = (int32_t)((uint32_t)T0 / (uint32_t)T1);
! 382: env->HI[0][env->current_tc] = (int32_t)((uint32_t)T0 % (uint32_t)T1);
1.1.1.5 root 383: }
1.1.1.6 ! root 384: FORCE_RET();
1.1.1.5 root 385: }
386:
1.1.1.6 ! root 387: #if defined(TARGET_MIPS64)
1.1.1.5 root 388: /* Arithmetic */
389: void op_dadd (void)
390: {
391: T0 += T1;
1.1.1.6 ! root 392: FORCE_RET();
1.1.1.5 root 393: }
394:
395: void op_daddo (void)
396: {
397: target_long tmp;
398:
1.1 root 399: tmp = T0;
400: T0 += T1;
1.1.1.5 root 401: if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
402: /* operands of same sign, result different sign */
1.1.1.6 ! root 403: CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
1.1.1.5 root 404: }
1.1.1.6 ! root 405: FORCE_RET();
1.1.1.5 root 406: }
407:
408: void op_dsub (void)
409: {
410: T0 -= T1;
1.1.1.6 ! root 411: FORCE_RET();
1.1.1.5 root 412: }
413:
414: void op_dsubo (void)
415: {
416: target_long tmp;
417:
418: tmp = T0;
419: T0 = (int64_t)T0 - (int64_t)T1;
420: if (((tmp ^ T1) & (tmp ^ T0)) >> 63) {
421: /* operands of different sign, first operand and result different sign */
1.1.1.6 ! root 422: CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
1.1 root 423: }
1.1.1.6 ! root 424: FORCE_RET();
1.1 root 425: }
426:
1.1.1.5 root 427: void op_dmul (void)
428: {
429: T0 = (int64_t)T0 * (int64_t)T1;
1.1.1.6 ! root 430: FORCE_RET();
1.1.1.5 root 431: }
432:
433: /* Those might call libgcc functions. */
434: void op_ddiv (void)
435: {
436: do_ddiv();
1.1.1.6 ! root 437: FORCE_RET();
1.1.1.5 root 438: }
439:
1.1.1.6 ! root 440: #if TARGET_LONG_BITS > HOST_LONG_BITS
1.1.1.5 root 441: void op_ddivu (void)
442: {
443: do_ddivu();
1.1.1.6 ! root 444: FORCE_RET();
1.1.1.5 root 445: }
446: #else
447: void op_ddivu (void)
448: {
449: if (T1 != 0) {
1.1.1.6 ! root 450: env->LO[0][env->current_tc] = T0 / T1;
! 451: env->HI[0][env->current_tc] = T0 % T1;
1.1.1.5 root 452: }
1.1.1.6 ! root 453: FORCE_RET();
1.1.1.5 root 454: }
455: #endif
1.1.1.6 ! root 456: #endif /* TARGET_MIPS64 */
1.1.1.5 root 457:
458: /* Logical */
459: void op_and (void)
460: {
461: T0 &= T1;
1.1.1.6 ! root 462: FORCE_RET();
1.1.1.5 root 463: }
464:
465: void op_nor (void)
466: {
467: T0 = ~(T0 | T1);
1.1.1.6 ! root 468: FORCE_RET();
1.1.1.5 root 469: }
470:
471: void op_or (void)
472: {
473: T0 |= T1;
1.1.1.6 ! root 474: FORCE_RET();
1.1.1.5 root 475: }
476:
477: void op_xor (void)
478: {
479: T0 ^= T1;
1.1.1.6 ! root 480: FORCE_RET();
1.1.1.5 root 481: }
482:
483: void op_sll (void)
484: {
1.1.1.6 ! root 485: T0 = (int32_t)((uint32_t)T0 << T1);
! 486: FORCE_RET();
1.1.1.5 root 487: }
488:
489: void op_sra (void)
490: {
1.1.1.6 ! root 491: T0 = (int32_t)((int32_t)T0 >> T1);
! 492: FORCE_RET();
1.1.1.5 root 493: }
494:
495: void op_srl (void)
496: {
1.1.1.6 ! root 497: T0 = (int32_t)((uint32_t)T0 >> T1);
! 498: FORCE_RET();
1.1.1.5 root 499: }
500:
501: void op_rotr (void)
502: {
503: target_ulong tmp;
504:
505: if (T1) {
1.1.1.6 ! root 506: tmp = (int32_t)((uint32_t)T0 << (0x20 - T1));
! 507: T0 = (int32_t)((uint32_t)T0 >> T1) | tmp;
! 508: }
! 509: FORCE_RET();
1.1.1.5 root 510: }
511:
512: void op_sllv (void)
513: {
514: T0 = (int32_t)((uint32_t)T1 << ((uint32_t)T0 & 0x1F));
1.1.1.6 ! root 515: FORCE_RET();
1.1.1.5 root 516: }
517:
518: void op_srav (void)
519: {
520: T0 = (int32_t)((int32_t)T1 >> (T0 & 0x1F));
1.1.1.6 ! root 521: FORCE_RET();
1.1.1.5 root 522: }
523:
524: void op_srlv (void)
525: {
526: T0 = (int32_t)((uint32_t)T1 >> (T0 & 0x1F));
1.1.1.6 ! root 527: FORCE_RET();
1.1.1.5 root 528: }
529:
530: void op_rotrv (void)
531: {
532: target_ulong tmp;
533:
534: T0 &= 0x1F;
535: if (T0) {
536: tmp = (int32_t)((uint32_t)T1 << (0x20 - T0));
537: T0 = (int32_t)((uint32_t)T1 >> T0) | tmp;
538: } else
539: T0 = T1;
1.1.1.6 ! root 540: FORCE_RET();
1.1.1.5 root 541: }
542:
543: void op_clo (void)
544: {
1.1.1.6 ! root 545: T0 = clo32(T0);
! 546: FORCE_RET();
1.1.1.5 root 547: }
548:
549: void op_clz (void)
550: {
1.1.1.6 ! root 551: T0 = clz32(T0);
! 552: FORCE_RET();
1.1.1.5 root 553: }
554:
1.1.1.6 ! root 555: #if defined(TARGET_MIPS64)
1.1.1.5 root 556:
557: #if TARGET_LONG_BITS > HOST_LONG_BITS
558: /* Those might call libgcc functions. */
559: void op_dsll (void)
560: {
561: CALL_FROM_TB0(do_dsll);
1.1.1.6 ! root 562: FORCE_RET();
1.1.1.5 root 563: }
564:
565: void op_dsll32 (void)
566: {
567: CALL_FROM_TB0(do_dsll32);
1.1.1.6 ! root 568: FORCE_RET();
1.1.1.5 root 569: }
570:
571: void op_dsra (void)
572: {
573: CALL_FROM_TB0(do_dsra);
1.1.1.6 ! root 574: FORCE_RET();
1.1.1.5 root 575: }
576:
577: void op_dsra32 (void)
578: {
579: CALL_FROM_TB0(do_dsra32);
1.1.1.6 ! root 580: FORCE_RET();
1.1.1.5 root 581: }
582:
583: void op_dsrl (void)
584: {
585: CALL_FROM_TB0(do_dsrl);
1.1.1.6 ! root 586: FORCE_RET();
1.1.1.5 root 587: }
588:
589: void op_dsrl32 (void)
590: {
591: CALL_FROM_TB0(do_dsrl32);
1.1.1.6 ! root 592: FORCE_RET();
1.1.1.5 root 593: }
594:
595: void op_drotr (void)
596: {
597: CALL_FROM_TB0(do_drotr);
1.1.1.6 ! root 598: FORCE_RET();
1.1.1.5 root 599: }
600:
601: void op_drotr32 (void)
602: {
603: CALL_FROM_TB0(do_drotr32);
1.1.1.6 ! root 604: FORCE_RET();
1.1.1.5 root 605: }
606:
607: void op_dsllv (void)
608: {
609: CALL_FROM_TB0(do_dsllv);
1.1.1.6 ! root 610: FORCE_RET();
1.1.1.5 root 611: }
612:
613: void op_dsrav (void)
614: {
615: CALL_FROM_TB0(do_dsrav);
1.1.1.6 ! root 616: FORCE_RET();
1.1.1.5 root 617: }
618:
619: void op_dsrlv (void)
620: {
621: CALL_FROM_TB0(do_dsrlv);
1.1.1.6 ! root 622: FORCE_RET();
1.1.1.5 root 623: }
624:
625: void op_drotrv (void)
626: {
627: CALL_FROM_TB0(do_drotrv);
1.1.1.6 ! root 628: FORCE_RET();
! 629: }
! 630:
! 631: void op_dclo (void)
! 632: {
! 633: CALL_FROM_TB0(do_dclo);
! 634: FORCE_RET();
! 635: }
! 636:
! 637: void op_dclz (void)
! 638: {
! 639: CALL_FROM_TB0(do_dclz);
! 640: FORCE_RET();
1.1.1.5 root 641: }
642:
643: #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
644:
645: void op_dsll (void)
646: {
647: T0 = T0 << T1;
1.1.1.6 ! root 648: FORCE_RET();
1.1.1.5 root 649: }
650:
651: void op_dsll32 (void)
652: {
653: T0 = T0 << (T1 + 32);
1.1.1.6 ! root 654: FORCE_RET();
1.1.1.5 root 655: }
656:
657: void op_dsra (void)
658: {
659: T0 = (int64_t)T0 >> T1;
1.1.1.6 ! root 660: FORCE_RET();
1.1.1.5 root 661: }
662:
663: void op_dsra32 (void)
664: {
665: T0 = (int64_t)T0 >> (T1 + 32);
1.1.1.6 ! root 666: FORCE_RET();
1.1.1.5 root 667: }
668:
669: void op_dsrl (void)
670: {
671: T0 = T0 >> T1;
1.1.1.6 ! root 672: FORCE_RET();
1.1.1.5 root 673: }
674:
675: void op_dsrl32 (void)
676: {
677: T0 = T0 >> (T1 + 32);
1.1.1.6 ! root 678: FORCE_RET();
1.1.1.5 root 679: }
680:
681: void op_drotr (void)
682: {
683: target_ulong tmp;
684:
685: if (T1) {
1.1.1.6 ! root 686: tmp = T0 << (0x40 - T1);
! 687: T0 = (T0 >> T1) | tmp;
! 688: }
! 689: FORCE_RET();
1.1.1.5 root 690: }
691:
692: void op_drotr32 (void)
693: {
694: target_ulong tmp;
695:
1.1.1.6 ! root 696: tmp = T0 << (0x40 - (32 + T1));
! 697: T0 = (T0 >> (32 + T1)) | tmp;
! 698: FORCE_RET();
1.1.1.5 root 699: }
700:
701: void op_dsllv (void)
702: {
703: T0 = T1 << (T0 & 0x3F);
1.1.1.6 ! root 704: FORCE_RET();
1.1.1.5 root 705: }
706:
707: void op_dsrav (void)
708: {
709: T0 = (int64_t)T1 >> (T0 & 0x3F);
1.1.1.6 ! root 710: FORCE_RET();
1.1.1.5 root 711: }
712:
713: void op_dsrlv (void)
714: {
715: T0 = T1 >> (T0 & 0x3F);
1.1.1.6 ! root 716: FORCE_RET();
1.1.1.5 root 717: }
718:
719: void op_drotrv (void)
720: {
721: target_ulong tmp;
722:
723: T0 &= 0x3F;
724: if (T0) {
1.1.1.6 ! root 725: tmp = T1 << (0x40 - T0);
! 726: T0 = (T1 >> T0) | tmp;
1.1.1.5 root 727: } else
1.1.1.6 ! root 728: T0 = T1;
! 729: FORCE_RET();
1.1.1.5 root 730: }
731:
732: void op_dclo (void)
733: {
1.1.1.6 ! root 734: T0 = clo64(T0);
! 735: FORCE_RET();
1.1.1.5 root 736: }
737:
738: void op_dclz (void)
739: {
1.1.1.6 ! root 740: T0 = clz64(T0);
! 741: FORCE_RET();
1.1.1.5 root 742: }
1.1.1.6 ! root 743: #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
! 744: #endif /* TARGET_MIPS64 */
1.1.1.5 root 745:
746: /* 64 bits arithmetic */
747: #if TARGET_LONG_BITS > HOST_LONG_BITS
748: void op_mult (void)
749: {
750: CALL_FROM_TB0(do_mult);
1.1.1.6 ! root 751: FORCE_RET();
1.1.1.5 root 752: }
753:
754: void op_multu (void)
755: {
756: CALL_FROM_TB0(do_multu);
1.1.1.6 ! root 757: FORCE_RET();
1.1.1.5 root 758: }
759:
760: void op_madd (void)
761: {
762: CALL_FROM_TB0(do_madd);
1.1.1.6 ! root 763: FORCE_RET();
1.1.1.5 root 764: }
765:
766: void op_maddu (void)
767: {
768: CALL_FROM_TB0(do_maddu);
1.1.1.6 ! root 769: FORCE_RET();
1.1.1.5 root 770: }
771:
772: void op_msub (void)
773: {
774: CALL_FROM_TB0(do_msub);
1.1.1.6 ! root 775: FORCE_RET();
1.1.1.5 root 776: }
777:
778: void op_msubu (void)
779: {
780: CALL_FROM_TB0(do_msubu);
1.1.1.6 ! root 781: FORCE_RET();
! 782: }
! 783:
! 784: /* Multiplication variants of the vr54xx. */
! 785: void op_muls (void)
! 786: {
! 787: CALL_FROM_TB0(do_muls);
! 788: FORCE_RET();
! 789: }
! 790:
! 791: void op_mulsu (void)
! 792: {
! 793: CALL_FROM_TB0(do_mulsu);
! 794: FORCE_RET();
! 795: }
! 796:
! 797: void op_macc (void)
! 798: {
! 799: CALL_FROM_TB0(do_macc);
! 800: FORCE_RET();
! 801: }
! 802:
! 803: void op_macchi (void)
! 804: {
! 805: CALL_FROM_TB0(do_macchi);
! 806: FORCE_RET();
! 807: }
! 808:
! 809: void op_maccu (void)
! 810: {
! 811: CALL_FROM_TB0(do_maccu);
! 812: FORCE_RET();
! 813: }
! 814: void op_macchiu (void)
! 815: {
! 816: CALL_FROM_TB0(do_macchiu);
! 817: FORCE_RET();
! 818: }
! 819:
! 820: void op_msac (void)
! 821: {
! 822: CALL_FROM_TB0(do_msac);
! 823: FORCE_RET();
! 824: }
! 825:
! 826: void op_msachi (void)
! 827: {
! 828: CALL_FROM_TB0(do_msachi);
! 829: FORCE_RET();
! 830: }
! 831:
! 832: void op_msacu (void)
! 833: {
! 834: CALL_FROM_TB0(do_msacu);
! 835: FORCE_RET();
! 836: }
! 837:
! 838: void op_msachiu (void)
! 839: {
! 840: CALL_FROM_TB0(do_msachiu);
! 841: FORCE_RET();
! 842: }
! 843:
! 844: void op_mulhi (void)
! 845: {
! 846: CALL_FROM_TB0(do_mulhi);
! 847: FORCE_RET();
! 848: }
! 849:
! 850: void op_mulhiu (void)
! 851: {
! 852: CALL_FROM_TB0(do_mulhiu);
! 853: FORCE_RET();
! 854: }
! 855:
! 856: void op_mulshi (void)
! 857: {
! 858: CALL_FROM_TB0(do_mulshi);
! 859: FORCE_RET();
! 860: }
! 861:
! 862: void op_mulshiu (void)
! 863: {
! 864: CALL_FROM_TB0(do_mulshiu);
! 865: FORCE_RET();
1.1.1.5 root 866: }
867:
868: #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
869:
1.1.1.6 ! root 870: static always_inline uint64_t get_HILO (void)
! 871: {
! 872: return ((uint64_t)env->HI[0][env->current_tc] << 32) |
! 873: ((uint64_t)(uint32_t)env->LO[0][env->current_tc]);
! 874: }
! 875:
! 876: static always_inline void set_HILO (uint64_t HILO)
! 877: {
! 878: env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
! 879: env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
! 880: }
! 881:
! 882: static always_inline void set_HIT0_LO (uint64_t HILO)
1.1.1.5 root 883: {
1.1.1.6 ! root 884: env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
! 885: T0 = env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
1.1.1.5 root 886: }
887:
1.1.1.6 ! root 888: static always_inline void set_HI_LOT0 (uint64_t HILO)
1.1.1.5 root 889: {
1.1.1.6 ! root 890: T0 = env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
! 891: env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
1.1.1.5 root 892: }
893:
894: void op_mult (void)
895: {
896: set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
1.1.1.6 ! root 897: FORCE_RET();
1.1.1.5 root 898: }
899:
900: void op_multu (void)
901: {
902: set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
1.1.1.6 ! root 903: FORCE_RET();
1.1.1.5 root 904: }
905:
906: void op_madd (void)
907: {
908: int64_t tmp;
909:
910: tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
911: set_HILO((int64_t)get_HILO() + tmp);
1.1.1.6 ! root 912: FORCE_RET();
1.1.1.5 root 913: }
914:
915: void op_maddu (void)
916: {
917: uint64_t tmp;
918:
919: tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
920: set_HILO(get_HILO() + tmp);
1.1.1.6 ! root 921: FORCE_RET();
1.1.1.5 root 922: }
923:
924: void op_msub (void)
925: {
926: int64_t tmp;
927:
928: tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
929: set_HILO((int64_t)get_HILO() - tmp);
1.1.1.6 ! root 930: FORCE_RET();
1.1.1.5 root 931: }
932:
933: void op_msubu (void)
934: {
935: uint64_t tmp;
936:
937: tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
938: set_HILO(get_HILO() - tmp);
1.1.1.6 ! root 939: FORCE_RET();
! 940: }
! 941:
! 942: /* Multiplication variants of the vr54xx. */
! 943: void op_muls (void)
! 944: {
! 945: set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
! 946: FORCE_RET();
! 947: }
! 948:
! 949: void op_mulsu (void)
! 950: {
! 951: set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
! 952: FORCE_RET();
! 953: }
! 954:
! 955: void op_macc (void)
! 956: {
! 957: set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
! 958: FORCE_RET();
! 959: }
! 960:
! 961: void op_macchi (void)
! 962: {
! 963: set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
! 964: FORCE_RET();
! 965: }
! 966:
! 967: void op_maccu (void)
! 968: {
! 969: set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
! 970: FORCE_RET();
! 971: }
! 972:
! 973: void op_macchiu (void)
! 974: {
! 975: set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
! 976: FORCE_RET();
! 977: }
! 978:
! 979: void op_msac (void)
! 980: {
! 981: set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
! 982: FORCE_RET();
! 983: }
! 984:
! 985: void op_msachi (void)
! 986: {
! 987: set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
! 988: FORCE_RET();
! 989: }
! 990:
! 991: void op_msacu (void)
! 992: {
! 993: set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
! 994: FORCE_RET();
! 995: }
! 996:
! 997: void op_msachiu (void)
! 998: {
! 999: set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
! 1000: FORCE_RET();
! 1001: }
! 1002:
! 1003: void op_mulhi (void)
! 1004: {
! 1005: set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
! 1006: FORCE_RET();
! 1007: }
! 1008:
! 1009: void op_mulhiu (void)
! 1010: {
! 1011: set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
! 1012: FORCE_RET();
! 1013: }
! 1014:
! 1015: void op_mulshi (void)
! 1016: {
! 1017: set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
! 1018: FORCE_RET();
1.1.1.5 root 1019: }
1.1.1.6 ! root 1020:
! 1021: void op_mulshiu (void)
! 1022: {
! 1023: set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
! 1024: FORCE_RET();
! 1025: }
! 1026:
1.1.1.5 root 1027: #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
1028:
1.1.1.6 ! root 1029: #if defined(TARGET_MIPS64)
1.1.1.5 root 1030: void op_dmult (void)
1031: {
1.1.1.6 ! root 1032: CALL_FROM_TB4(muls64, &(env->LO[0][env->current_tc]), &(env->HI[0][env->current_tc]), T0, T1);
! 1033: FORCE_RET();
1.1.1.5 root 1034: }
1035:
1036: void op_dmultu (void)
1037: {
1.1.1.6 ! root 1038: CALL_FROM_TB4(mulu64, &(env->LO[0][env->current_tc]), &(env->HI[0][env->current_tc]), T0, T1);
! 1039: FORCE_RET();
1.1.1.5 root 1040: }
1041: #endif
1042:
1043: /* Conditional moves */
1044: void op_movn (void)
1045: {
1046: if (T1 != 0)
1.1.1.6 ! root 1047: env->gpr[PARAM1][env->current_tc] = T0;
! 1048: FORCE_RET();
1.1.1.5 root 1049: }
1050:
1051: void op_movz (void)
1052: {
1053: if (T1 == 0)
1.1.1.6 ! root 1054: env->gpr[PARAM1][env->current_tc] = T0;
! 1055: FORCE_RET();
1.1.1.5 root 1056: }
1057:
1058: void op_movf (void)
1059: {
1.1.1.6 ! root 1060: if (!(env->fpu->fcr31 & PARAM1))
! 1061: T0 = T1;
! 1062: FORCE_RET();
1.1.1.5 root 1063: }
1064:
1065: void op_movt (void)
1066: {
1.1.1.6 ! root 1067: if (env->fpu->fcr31 & PARAM1)
! 1068: T0 = T1;
! 1069: FORCE_RET();
1.1.1.5 root 1070: }
1071:
1072: /* Tests */
1073: #define OP_COND(name, cond) \
1074: void glue(op_, name) (void) \
1075: { \
1076: if (cond) { \
1077: T0 = 1; \
1078: } else { \
1079: T0 = 0; \
1080: } \
1.1.1.6 ! root 1081: FORCE_RET(); \
1.1.1.5 root 1082: }
1083:
1084: OP_COND(eq, T0 == T1);
1085: OP_COND(ne, T0 != T1);
1.1.1.6 ! root 1086: OP_COND(ge, (target_long)T0 >= (target_long)T1);
1.1.1.5 root 1087: OP_COND(geu, T0 >= T1);
1.1.1.6 ! root 1088: OP_COND(lt, (target_long)T0 < (target_long)T1);
1.1.1.5 root 1089: OP_COND(ltu, T0 < T1);
1.1.1.6 ! root 1090: OP_COND(gez, (target_long)T0 >= 0);
! 1091: OP_COND(gtz, (target_long)T0 > 0);
! 1092: OP_COND(lez, (target_long)T0 <= 0);
! 1093: OP_COND(ltz, (target_long)T0 < 0);
1.1.1.5 root 1094:
1095: /* Branches */
1096: void OPPROTO op_goto_tb0(void)
1097: {
1098: GOTO_TB(op_goto_tb0, PARAM1, 0);
1.1.1.6 ! root 1099: FORCE_RET();
1.1.1.5 root 1100: }
1101:
1102: void OPPROTO op_goto_tb1(void)
1103: {
1104: GOTO_TB(op_goto_tb1, PARAM1, 1);
1.1.1.6 ! root 1105: FORCE_RET();
1.1.1.5 root 1106: }
1107:
1108: /* Branch to register */
1109: void op_save_breg_target (void)
1110: {
1111: env->btarget = T2;
1.1.1.6 ! root 1112: FORCE_RET();
1.1.1.5 root 1113: }
1114:
1115: void op_restore_breg_target (void)
1116: {
1117: T2 = env->btarget;
1.1.1.6 ! root 1118: FORCE_RET();
1.1.1.5 root 1119: }
1120:
1121: void op_breg (void)
1122: {
1.1.1.6 ! root 1123: env->PC[env->current_tc] = T2;
! 1124: FORCE_RET();
1.1.1.5 root 1125: }
1126:
1127: void op_save_btarget (void)
1128: {
1129: env->btarget = PARAM1;
1.1.1.6 ! root 1130: FORCE_RET();
! 1131: }
! 1132:
! 1133: #if defined(TARGET_MIPS64)
! 1134: void op_save_btarget64 (void)
! 1135: {
! 1136: env->btarget = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
! 1137: FORCE_RET();
1.1.1.5 root 1138: }
1.1.1.6 ! root 1139: #endif
1.1.1.5 root 1140:
1141: /* Conditional branch */
1142: void op_set_bcond (void)
1143: {
1144: T2 = T0;
1.1.1.6 ! root 1145: FORCE_RET();
1.1.1.5 root 1146: }
1147:
1148: void op_save_bcond (void)
1149: {
1150: env->bcond = T2;
1.1.1.6 ! root 1151: FORCE_RET();
1.1.1.5 root 1152: }
1153:
1154: void op_restore_bcond (void)
1155: {
1156: T2 = env->bcond;
1.1.1.6 ! root 1157: FORCE_RET();
1.1.1.5 root 1158: }
1159:
1160: void op_jnz_T2 (void)
1161: {
1162: if (T2)
1163: GOTO_LABEL_PARAM(1);
1.1.1.6 ! root 1164: FORCE_RET();
1.1.1.5 root 1165: }
1166:
1167: /* CP0 functions */
1168: void op_mfc0_index (void)
1169: {
1170: T0 = env->CP0_Index;
1.1.1.6 ! root 1171: FORCE_RET();
1.1.1.5 root 1172: }
1173:
1.1.1.6 ! root 1174: void op_mfc0_mvpcontrol (void)
1.1.1.5 root 1175: {
1.1.1.6 ! root 1176: T0 = env->mvp->CP0_MVPControl;
! 1177: FORCE_RET();
1.1.1.5 root 1178: }
1179:
1.1.1.6 ! root 1180: void op_mfc0_mvpconf0 (void)
1.1.1.5 root 1181: {
1.1.1.6 ! root 1182: T0 = env->mvp->CP0_MVPConf0;
! 1183: FORCE_RET();
1.1.1.5 root 1184: }
1185:
1.1.1.6 ! root 1186: void op_mfc0_mvpconf1 (void)
1.1.1.5 root 1187: {
1.1.1.6 ! root 1188: T0 = env->mvp->CP0_MVPConf1;
! 1189: FORCE_RET();
1.1.1.5 root 1190: }
1191:
1.1.1.6 ! root 1192: void op_mfc0_random (void)
1.1.1.5 root 1193: {
1.1.1.6 ! root 1194: CALL_FROM_TB0(do_mfc0_random);
! 1195: FORCE_RET();
1.1.1.5 root 1196: }
1197:
1.1.1.6 ! root 1198: void op_mfc0_vpecontrol (void)
1.1.1.5 root 1199: {
1.1.1.6 ! root 1200: T0 = env->CP0_VPEControl;
! 1201: FORCE_RET();
1.1.1.5 root 1202: }
1203:
1.1.1.6 ! root 1204: void op_mfc0_vpeconf0 (void)
1.1.1.5 root 1205: {
1.1.1.6 ! root 1206: T0 = env->CP0_VPEConf0;
! 1207: FORCE_RET();
1.1.1.5 root 1208: }
1209:
1.1.1.6 ! root 1210: void op_mfc0_vpeconf1 (void)
1.1.1.5 root 1211: {
1.1.1.6 ! root 1212: T0 = env->CP0_VPEConf1;
! 1213: FORCE_RET();
1.1.1.5 root 1214: }
1215:
1.1.1.6 ! root 1216: void op_mfc0_yqmask (void)
1.1.1.5 root 1217: {
1.1.1.6 ! root 1218: T0 = env->CP0_YQMask;
! 1219: FORCE_RET();
1.1.1.5 root 1220: }
1221:
1.1.1.6 ! root 1222: void op_mfc0_vpeschedule (void)
1.1.1.5 root 1223: {
1.1.1.6 ! root 1224: T0 = env->CP0_VPESchedule;
! 1225: FORCE_RET();
1.1.1.5 root 1226: }
1227:
1.1.1.6 ! root 1228: void op_mfc0_vpeschefback (void)
1.1.1.5 root 1229: {
1.1.1.6 ! root 1230: T0 = env->CP0_VPEScheFBack;
! 1231: FORCE_RET();
1.1.1.5 root 1232: }
1233:
1.1.1.6 ! root 1234: void op_mfc0_vpeopt (void)
1.1.1.5 root 1235: {
1.1.1.6 ! root 1236: T0 = env->CP0_VPEOpt;
! 1237: FORCE_RET();
1.1.1.5 root 1238: }
1239:
1.1.1.6 ! root 1240: void op_mfc0_entrylo0 (void)
1.1.1.5 root 1241: {
1.1.1.6 ! root 1242: T0 = (int32_t)env->CP0_EntryLo0;
! 1243: FORCE_RET();
1.1.1.5 root 1244: }
1245:
1.1.1.6 ! root 1246: void op_mfc0_tcstatus (void)
1.1.1.5 root 1247: {
1.1.1.6 ! root 1248: T0 = env->CP0_TCStatus[env->current_tc];
! 1249: FORCE_RET();
1.1.1.5 root 1250: }
1251:
1.1.1.6 ! root 1252: void op_mftc0_tcstatus(void)
1.1.1.5 root 1253: {
1.1.1.6 ! root 1254: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1.1.1.5 root 1255:
1.1.1.6 ! root 1256: T0 = env->CP0_TCStatus[other_tc];
! 1257: FORCE_RET();
1.1.1.5 root 1258: }
1259:
1.1.1.6 ! root 1260: void op_mfc0_tcbind (void)
1.1.1.5 root 1261: {
1.1.1.6 ! root 1262: T0 = env->CP0_TCBind[env->current_tc];
! 1263: FORCE_RET();
1.1.1.5 root 1264: }
1265:
1.1.1.6 ! root 1266: void op_mftc0_tcbind(void)
1.1.1.5 root 1267: {
1.1.1.6 ! root 1268: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1269:
! 1270: T0 = env->CP0_TCBind[other_tc];
! 1271: FORCE_RET();
1.1.1.5 root 1272: }
1273:
1.1.1.6 ! root 1274: void op_mfc0_tcrestart (void)
1.1.1.5 root 1275: {
1.1.1.6 ! root 1276: T0 = env->PC[env->current_tc];
! 1277: FORCE_RET();
1.1.1.5 root 1278: }
1279:
1.1.1.6 ! root 1280: void op_mftc0_tcrestart(void)
1.1.1.5 root 1281: {
1.1.1.6 ! root 1282: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1283:
! 1284: T0 = env->PC[other_tc];
! 1285: FORCE_RET();
1.1.1.5 root 1286: }
1287:
1.1.1.6 ! root 1288: void op_mfc0_tchalt (void)
1.1.1.5 root 1289: {
1.1.1.6 ! root 1290: T0 = env->CP0_TCHalt[env->current_tc];
! 1291: FORCE_RET();
1.1.1.5 root 1292: }
1293:
1.1.1.6 ! root 1294: void op_mftc0_tchalt(void)
1.1.1.5 root 1295: {
1.1.1.6 ! root 1296: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1297:
! 1298: T0 = env->CP0_TCHalt[other_tc];
! 1299: FORCE_RET();
1.1.1.5 root 1300: }
1301:
1.1.1.6 ! root 1302: void op_mfc0_tccontext (void)
1.1.1.5 root 1303: {
1.1.1.6 ! root 1304: T0 = env->CP0_TCContext[env->current_tc];
! 1305: FORCE_RET();
1.1.1.5 root 1306: }
1307:
1.1.1.6 ! root 1308: void op_mftc0_tccontext(void)
1.1.1.5 root 1309: {
1.1.1.6 ! root 1310: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1311:
! 1312: T0 = env->CP0_TCContext[other_tc];
! 1313: FORCE_RET();
1.1.1.5 root 1314: }
1315:
1.1.1.6 ! root 1316: void op_mfc0_tcschedule (void)
1.1.1.5 root 1317: {
1.1.1.6 ! root 1318: T0 = env->CP0_TCSchedule[env->current_tc];
! 1319: FORCE_RET();
1.1.1.5 root 1320: }
1321:
1.1.1.6 ! root 1322: void op_mftc0_tcschedule(void)
1.1.1.5 root 1323: {
1.1.1.6 ! root 1324: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1325:
! 1326: T0 = env->CP0_TCSchedule[other_tc];
! 1327: FORCE_RET();
1.1.1.5 root 1328: }
1329:
1.1.1.6 ! root 1330: void op_mfc0_tcschefback (void)
1.1.1.5 root 1331: {
1.1.1.6 ! root 1332: T0 = env->CP0_TCScheFBack[env->current_tc];
! 1333: FORCE_RET();
1.1.1.5 root 1334: }
1335:
1.1.1.6 ! root 1336: void op_mftc0_tcschefback(void)
1.1.1.5 root 1337: {
1.1.1.6 ! root 1338: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1339:
! 1340: T0 = env->CP0_TCScheFBack[other_tc];
! 1341: FORCE_RET();
1.1.1.5 root 1342: }
1343:
1.1.1.6 ! root 1344: void op_mfc0_entrylo1 (void)
1.1.1.5 root 1345: {
1.1.1.6 ! root 1346: T0 = (int32_t)env->CP0_EntryLo1;
! 1347: FORCE_RET();
1.1.1.5 root 1348: }
1349:
1.1.1.6 ! root 1350: void op_mfc0_context (void)
1.1.1.5 root 1351: {
1.1.1.6 ! root 1352: T0 = (int32_t)env->CP0_Context;
! 1353: FORCE_RET();
1.1.1.5 root 1354: }
1355:
1.1.1.6 ! root 1356: void op_mfc0_pagemask (void)
1.1.1.5 root 1357: {
1.1.1.6 ! root 1358: T0 = env->CP0_PageMask;
! 1359: FORCE_RET();
1.1.1.5 root 1360: }
1361:
1.1.1.6 ! root 1362: void op_mfc0_pagegrain (void)
1.1.1.5 root 1363: {
1.1.1.6 ! root 1364: T0 = env->CP0_PageGrain;
! 1365: FORCE_RET();
1.1.1.5 root 1366: }
1367:
1.1.1.6 ! root 1368: void op_mfc0_wired (void)
1.1.1.5 root 1369: {
1.1.1.6 ! root 1370: T0 = env->CP0_Wired;
! 1371: FORCE_RET();
1.1.1.5 root 1372: }
1373:
1.1.1.6 ! root 1374: void op_mfc0_srsconf0 (void)
1.1.1.5 root 1375: {
1.1.1.6 ! root 1376: T0 = env->CP0_SRSConf0;
! 1377: FORCE_RET();
1.1.1.5 root 1378: }
1379:
1.1.1.6 ! root 1380: void op_mfc0_srsconf1 (void)
1.1.1.5 root 1381: {
1.1.1.6 ! root 1382: T0 = env->CP0_SRSConf1;
! 1383: FORCE_RET();
1.1.1.5 root 1384: }
1385:
1.1.1.6 ! root 1386: void op_mfc0_srsconf2 (void)
1.1.1.5 root 1387: {
1.1.1.6 ! root 1388: T0 = env->CP0_SRSConf2;
! 1389: FORCE_RET();
1.1.1.5 root 1390: }
1391:
1.1.1.6 ! root 1392: void op_mfc0_srsconf3 (void)
1.1.1.5 root 1393: {
1.1.1.6 ! root 1394: T0 = env->CP0_SRSConf3;
! 1395: FORCE_RET();
1.1.1.5 root 1396: }
1397:
1.1.1.6 ! root 1398: void op_mfc0_srsconf4 (void)
1.1.1.5 root 1399: {
1.1.1.6 ! root 1400: T0 = env->CP0_SRSConf4;
! 1401: FORCE_RET();
1.1.1.5 root 1402: }
1403:
1.1.1.6 ! root 1404: void op_mfc0_hwrena (void)
1.1.1.5 root 1405: {
1.1.1.6 ! root 1406: T0 = env->CP0_HWREna;
! 1407: FORCE_RET();
! 1408: }
! 1409:
! 1410: void op_mfc0_badvaddr (void)
! 1411: {
! 1412: T0 = (int32_t)env->CP0_BadVAddr;
! 1413: FORCE_RET();
! 1414: }
! 1415:
! 1416: void op_mfc0_count (void)
! 1417: {
! 1418: CALL_FROM_TB0(do_mfc0_count);
! 1419: FORCE_RET();
! 1420: }
! 1421:
! 1422: void op_mfc0_entryhi (void)
! 1423: {
! 1424: T0 = (int32_t)env->CP0_EntryHi;
! 1425: FORCE_RET();
! 1426: }
! 1427:
! 1428: void op_mftc0_entryhi(void)
! 1429: {
! 1430: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1431:
! 1432: T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
! 1433: FORCE_RET();
! 1434: }
! 1435:
! 1436: void op_mfc0_compare (void)
! 1437: {
! 1438: T0 = env->CP0_Compare;
! 1439: FORCE_RET();
! 1440: }
! 1441:
! 1442: void op_mfc0_status (void)
! 1443: {
! 1444: T0 = env->CP0_Status;
! 1445: FORCE_RET();
! 1446: }
! 1447:
! 1448: void op_mftc0_status(void)
! 1449: {
! 1450: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1451: uint32_t tcstatus = env->CP0_TCStatus[other_tc];
! 1452:
! 1453: T0 = env->CP0_Status & ~0xf1000018;
! 1454: T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
! 1455: T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
! 1456: T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
! 1457: FORCE_RET();
! 1458: }
! 1459:
! 1460: void op_mfc0_intctl (void)
! 1461: {
! 1462: T0 = env->CP0_IntCtl;
! 1463: FORCE_RET();
! 1464: }
! 1465:
! 1466: void op_mfc0_srsctl (void)
! 1467: {
! 1468: T0 = env->CP0_SRSCtl;
! 1469: FORCE_RET();
! 1470: }
! 1471:
! 1472: void op_mfc0_srsmap (void)
! 1473: {
! 1474: T0 = env->CP0_SRSMap;
! 1475: FORCE_RET();
! 1476: }
! 1477:
! 1478: void op_mfc0_cause (void)
! 1479: {
! 1480: T0 = env->CP0_Cause;
! 1481: FORCE_RET();
! 1482: }
! 1483:
! 1484: void op_mfc0_epc (void)
! 1485: {
! 1486: T0 = (int32_t)env->CP0_EPC;
! 1487: FORCE_RET();
! 1488: }
! 1489:
! 1490: void op_mfc0_prid (void)
! 1491: {
! 1492: T0 = env->CP0_PRid;
! 1493: FORCE_RET();
! 1494: }
! 1495:
! 1496: void op_mfc0_ebase (void)
! 1497: {
! 1498: T0 = env->CP0_EBase;
! 1499: FORCE_RET();
! 1500: }
! 1501:
! 1502: void op_mfc0_config0 (void)
! 1503: {
! 1504: T0 = env->CP0_Config0;
! 1505: FORCE_RET();
! 1506: }
! 1507:
! 1508: void op_mfc0_config1 (void)
! 1509: {
! 1510: T0 = env->CP0_Config1;
! 1511: FORCE_RET();
! 1512: }
! 1513:
! 1514: void op_mfc0_config2 (void)
! 1515: {
! 1516: T0 = env->CP0_Config2;
! 1517: FORCE_RET();
! 1518: }
! 1519:
! 1520: void op_mfc0_config3 (void)
! 1521: {
! 1522: T0 = env->CP0_Config3;
! 1523: FORCE_RET();
! 1524: }
! 1525:
! 1526: void op_mfc0_config6 (void)
! 1527: {
! 1528: T0 = env->CP0_Config6;
! 1529: FORCE_RET();
! 1530: }
! 1531:
! 1532: void op_mfc0_config7 (void)
! 1533: {
! 1534: T0 = env->CP0_Config7;
! 1535: FORCE_RET();
! 1536: }
! 1537:
! 1538: void op_mfc0_lladdr (void)
! 1539: {
! 1540: T0 = (int32_t)env->CP0_LLAddr >> 4;
! 1541: FORCE_RET();
! 1542: }
! 1543:
! 1544: void op_mfc0_watchlo (void)
! 1545: {
! 1546: T0 = (int32_t)env->CP0_WatchLo[PARAM1];
! 1547: FORCE_RET();
! 1548: }
! 1549:
! 1550: void op_mfc0_watchhi (void)
! 1551: {
! 1552: T0 = env->CP0_WatchHi[PARAM1];
! 1553: FORCE_RET();
! 1554: }
! 1555:
! 1556: void op_mfc0_xcontext (void)
! 1557: {
! 1558: T0 = (int32_t)env->CP0_XContext;
! 1559: FORCE_RET();
! 1560: }
! 1561:
! 1562: void op_mfc0_framemask (void)
! 1563: {
! 1564: T0 = env->CP0_Framemask;
! 1565: FORCE_RET();
! 1566: }
! 1567:
! 1568: void op_mfc0_debug (void)
! 1569: {
! 1570: T0 = env->CP0_Debug;
! 1571: if (env->hflags & MIPS_HFLAG_DM)
! 1572: T0 |= 1 << CP0DB_DM;
! 1573: FORCE_RET();
! 1574: }
! 1575:
! 1576: void op_mftc0_debug(void)
! 1577: {
! 1578: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1579:
! 1580: /* XXX: Might be wrong, check with EJTAG spec. */
! 1581: T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
! 1582: (env->CP0_Debug_tcstatus[other_tc] &
! 1583: ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
! 1584: FORCE_RET();
! 1585: }
! 1586:
! 1587: void op_mfc0_depc (void)
! 1588: {
! 1589: T0 = (int32_t)env->CP0_DEPC;
! 1590: FORCE_RET();
! 1591: }
! 1592:
! 1593: void op_mfc0_performance0 (void)
! 1594: {
! 1595: T0 = env->CP0_Performance0;
! 1596: FORCE_RET();
! 1597: }
! 1598:
! 1599: void op_mfc0_taglo (void)
! 1600: {
! 1601: T0 = env->CP0_TagLo;
! 1602: FORCE_RET();
! 1603: }
! 1604:
! 1605: void op_mfc0_datalo (void)
! 1606: {
! 1607: T0 = env->CP0_DataLo;
! 1608: FORCE_RET();
! 1609: }
! 1610:
! 1611: void op_mfc0_taghi (void)
! 1612: {
! 1613: T0 = env->CP0_TagHi;
! 1614: FORCE_RET();
! 1615: }
! 1616:
! 1617: void op_mfc0_datahi (void)
! 1618: {
! 1619: T0 = env->CP0_DataHi;
! 1620: FORCE_RET();
! 1621: }
! 1622:
! 1623: void op_mfc0_errorepc (void)
! 1624: {
! 1625: T0 = (int32_t)env->CP0_ErrorEPC;
! 1626: FORCE_RET();
! 1627: }
! 1628:
! 1629: void op_mfc0_desave (void)
! 1630: {
! 1631: T0 = env->CP0_DESAVE;
! 1632: FORCE_RET();
1.1.1.5 root 1633: }
1634:
1635: void op_mtc0_index (void)
1636: {
1.1.1.6 ! root 1637: int num = 1;
! 1638: unsigned int tmp = env->tlb->nb_tlb;
! 1639:
! 1640: do {
! 1641: tmp >>= 1;
! 1642: num <<= 1;
! 1643: } while (tmp);
! 1644: env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1));
! 1645: FORCE_RET();
! 1646: }
! 1647:
! 1648: void op_mtc0_mvpcontrol (void)
! 1649: {
! 1650: uint32_t mask = 0;
! 1651: uint32_t newval;
! 1652:
! 1653: if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
! 1654: mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
! 1655: (1 << CP0MVPCo_EVP);
! 1656: if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
! 1657: mask |= (1 << CP0MVPCo_STLB);
! 1658: newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
! 1659:
! 1660: // TODO: Enable/disable shared TLB, enable/disable VPEs.
! 1661:
! 1662: env->mvp->CP0_MVPControl = newval;
! 1663: FORCE_RET();
! 1664: }
! 1665:
! 1666: void op_mtc0_vpecontrol (void)
! 1667: {
! 1668: uint32_t mask;
! 1669: uint32_t newval;
! 1670:
! 1671: mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
! 1672: (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
! 1673: newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
! 1674:
! 1675: /* Yield scheduler intercept not implemented. */
! 1676: /* Gating storage scheduler intercept not implemented. */
! 1677:
! 1678: // TODO: Enable/disable TCs.
! 1679:
! 1680: env->CP0_VPEControl = newval;
! 1681: FORCE_RET();
! 1682: }
! 1683:
! 1684: void op_mtc0_vpeconf0 (void)
! 1685: {
! 1686: uint32_t mask = 0;
! 1687: uint32_t newval;
! 1688:
! 1689: if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
! 1690: if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
! 1691: mask |= (0xff << CP0VPEC0_XTC);
! 1692: mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
! 1693: }
! 1694: newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
! 1695:
! 1696: // TODO: TC exclusive handling due to ERL/EXL.
! 1697:
! 1698: env->CP0_VPEConf0 = newval;
! 1699: FORCE_RET();
! 1700: }
! 1701:
! 1702: void op_mtc0_vpeconf1 (void)
! 1703: {
! 1704: uint32_t mask = 0;
! 1705: uint32_t newval;
! 1706:
! 1707: if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
! 1708: mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
! 1709: (0xff << CP0VPEC1_NCP1);
! 1710: newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
! 1711:
! 1712: /* UDI not implemented. */
! 1713: /* CP2 not implemented. */
! 1714:
! 1715: // TODO: Handle FPU (CP1) binding.
! 1716:
! 1717: env->CP0_VPEConf1 = newval;
! 1718: FORCE_RET();
! 1719: }
! 1720:
! 1721: void op_mtc0_yqmask (void)
! 1722: {
! 1723: /* Yield qualifier inputs not implemented. */
! 1724: env->CP0_YQMask = 0x00000000;
! 1725: FORCE_RET();
! 1726: }
! 1727:
! 1728: void op_mtc0_vpeschedule (void)
! 1729: {
! 1730: env->CP0_VPESchedule = T0;
! 1731: FORCE_RET();
! 1732: }
! 1733:
! 1734: void op_mtc0_vpeschefback (void)
! 1735: {
! 1736: env->CP0_VPEScheFBack = T0;
! 1737: FORCE_RET();
! 1738: }
! 1739:
! 1740: void op_mtc0_vpeopt (void)
! 1741: {
! 1742: env->CP0_VPEOpt = T0 & 0x0000ffff;
! 1743: FORCE_RET();
1.1.1.5 root 1744: }
1745:
1746: void op_mtc0_entrylo0 (void)
1747: {
1.1.1.6 ! root 1748: /* Large physaddr (PABITS) not implemented */
1.1.1.5 root 1749: /* 1k pages not implemented */
1.1.1.6 ! root 1750: env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
! 1751: FORCE_RET();
! 1752: }
! 1753:
! 1754: void op_mtc0_tcstatus (void)
! 1755: {
! 1756: uint32_t mask = env->CP0_TCStatus_rw_bitmask;
! 1757: uint32_t newval;
! 1758:
! 1759: newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask);
! 1760:
! 1761: // TODO: Sync with CP0_Status.
! 1762:
! 1763: env->CP0_TCStatus[env->current_tc] = newval;
! 1764: FORCE_RET();
! 1765: }
! 1766:
! 1767: void op_mttc0_tcstatus (void)
! 1768: {
! 1769: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1770:
! 1771: // TODO: Sync with CP0_Status.
! 1772:
! 1773: env->CP0_TCStatus[other_tc] = T0;
! 1774: FORCE_RET();
! 1775: }
! 1776:
! 1777: void op_mtc0_tcbind (void)
! 1778: {
! 1779: uint32_t mask = (1 << CP0TCBd_TBE);
! 1780: uint32_t newval;
! 1781:
! 1782: if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
! 1783: mask |= (1 << CP0TCBd_CurVPE);
! 1784: newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask);
! 1785: env->CP0_TCBind[env->current_tc] = newval;
! 1786: FORCE_RET();
! 1787: }
! 1788:
! 1789: void op_mttc0_tcbind (void)
! 1790: {
! 1791: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1792: uint32_t mask = (1 << CP0TCBd_TBE);
! 1793: uint32_t newval;
! 1794:
! 1795: if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
! 1796: mask |= (1 << CP0TCBd_CurVPE);
! 1797: newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask);
! 1798: env->CP0_TCBind[other_tc] = newval;
! 1799: FORCE_RET();
! 1800: }
! 1801:
! 1802: void op_mtc0_tcrestart (void)
! 1803: {
! 1804: env->PC[env->current_tc] = T0;
! 1805: env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS);
! 1806: env->CP0_LLAddr = 0ULL;
! 1807: /* MIPS16 not implemented. */
! 1808: FORCE_RET();
! 1809: }
! 1810:
! 1811: void op_mttc0_tcrestart (void)
! 1812: {
! 1813: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1814:
! 1815: env->PC[other_tc] = T0;
! 1816: env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
! 1817: env->CP0_LLAddr = 0ULL;
! 1818: /* MIPS16 not implemented. */
! 1819: FORCE_RET();
! 1820: }
! 1821:
! 1822: void op_mtc0_tchalt (void)
! 1823: {
! 1824: env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
! 1825:
! 1826: // TODO: Halt TC / Restart (if allocated+active) TC.
! 1827:
! 1828: FORCE_RET();
! 1829: }
! 1830:
! 1831: void op_mttc0_tchalt (void)
! 1832: {
! 1833: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1834:
! 1835: // TODO: Halt TC / Restart (if allocated+active) TC.
! 1836:
! 1837: env->CP0_TCHalt[other_tc] = T0;
! 1838: FORCE_RET();
! 1839: }
! 1840:
! 1841: void op_mtc0_tccontext (void)
! 1842: {
! 1843: env->CP0_TCContext[env->current_tc] = T0;
! 1844: FORCE_RET();
! 1845: }
! 1846:
! 1847: void op_mttc0_tccontext (void)
! 1848: {
! 1849: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1850:
! 1851: env->CP0_TCContext[other_tc] = T0;
! 1852: FORCE_RET();
! 1853: }
! 1854:
! 1855: void op_mtc0_tcschedule (void)
! 1856: {
! 1857: env->CP0_TCSchedule[env->current_tc] = T0;
! 1858: FORCE_RET();
! 1859: }
! 1860:
! 1861: void op_mttc0_tcschedule (void)
! 1862: {
! 1863: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1864:
! 1865: env->CP0_TCSchedule[other_tc] = T0;
! 1866: FORCE_RET();
! 1867: }
! 1868:
! 1869: void op_mtc0_tcschefback (void)
! 1870: {
! 1871: env->CP0_TCScheFBack[env->current_tc] = T0;
! 1872: FORCE_RET();
! 1873: }
! 1874:
! 1875: void op_mttc0_tcschefback (void)
! 1876: {
! 1877: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1878:
! 1879: env->CP0_TCScheFBack[other_tc] = T0;
! 1880: FORCE_RET();
1.1.1.5 root 1881: }
1882:
1883: void op_mtc0_entrylo1 (void)
1884: {
1.1.1.6 ! root 1885: /* Large physaddr (PABITS) not implemented */
1.1.1.5 root 1886: /* 1k pages not implemented */
1.1.1.6 ! root 1887: env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
! 1888: FORCE_RET();
1.1.1.5 root 1889: }
1890:
1891: void op_mtc0_context (void)
1892: {
1.1.1.6 ! root 1893: env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF);
! 1894: FORCE_RET();
1.1.1.5 root 1895: }
1896:
1897: void op_mtc0_pagemask (void)
1.1 root 1898: {
1.1.1.5 root 1899: /* 1k pages not implemented */
1.1.1.6 ! root 1900: env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
! 1901: FORCE_RET();
1.1 root 1902: }
1903:
1.1.1.5 root 1904: void op_mtc0_pagegrain (void)
1.1 root 1905: {
1.1.1.5 root 1906: /* SmartMIPS not implemented */
1.1.1.6 ! root 1907: /* Large physaddr (PABITS) not implemented */
1.1.1.5 root 1908: /* 1k pages not implemented */
1909: env->CP0_PageGrain = 0;
1.1.1.6 ! root 1910: FORCE_RET();
! 1911: }
! 1912:
! 1913: void op_mtc0_wired (void)
! 1914: {
! 1915: env->CP0_Wired = T0 % env->tlb->nb_tlb;
! 1916: FORCE_RET();
! 1917: }
! 1918:
! 1919: void op_mtc0_srsconf0 (void)
! 1920: {
! 1921: env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
! 1922: FORCE_RET();
! 1923: }
! 1924:
! 1925: void op_mtc0_srsconf1 (void)
! 1926: {
! 1927: env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
! 1928: FORCE_RET();
! 1929: }
! 1930:
! 1931: void op_mtc0_srsconf2 (void)
! 1932: {
! 1933: env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
! 1934: FORCE_RET();
! 1935: }
! 1936:
! 1937: void op_mtc0_srsconf3 (void)
! 1938: {
! 1939: env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
! 1940: FORCE_RET();
1.1 root 1941: }
1942:
1.1.1.6 ! root 1943: void op_mtc0_srsconf4 (void)
1.1 root 1944: {
1.1.1.6 ! root 1945: env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
! 1946: FORCE_RET();
1.1 root 1947: }
1948:
1.1.1.5 root 1949: void op_mtc0_hwrena (void)
1.1 root 1950: {
1.1.1.5 root 1951: env->CP0_HWREna = T0 & 0x0000000F;
1.1.1.6 ! root 1952: FORCE_RET();
1.1 root 1953: }
1954:
1.1.1.5 root 1955: void op_mtc0_count (void)
1.1 root 1956: {
1.1.1.5 root 1957: CALL_FROM_TB2(cpu_mips_store_count, env, T0);
1.1.1.6 ! root 1958: FORCE_RET();
1.1 root 1959: }
1960:
1.1.1.5 root 1961: void op_mtc0_entryhi (void)
1.1 root 1962: {
1.1.1.5 root 1963: target_ulong old, val;
1964:
1965: /* 1k pages not implemented */
1.1.1.6 ! root 1966: val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
! 1967: #if defined(TARGET_MIPS64)
! 1968: val &= env->SEGMask;
! 1969: #endif
1.1.1.5 root 1970: old = env->CP0_EntryHi;
1971: env->CP0_EntryHi = val;
1.1.1.6 ! root 1972: if (env->CP0_Config3 & (1 << CP0C3_MT)) {
! 1973: uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff;
! 1974: env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff);
! 1975: }
1.1.1.5 root 1976: /* If the ASID changes, flush qemu's TLB. */
1977: if ((old & 0xFF) != (val & 0xFF))
1978: CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1.1.1.6 ! root 1979: FORCE_RET();
! 1980: }
! 1981:
! 1982: void op_mttc0_entryhi(void)
! 1983: {
! 1984: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 1985:
! 1986: env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
! 1987: env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
! 1988: FORCE_RET();
1.1 root 1989: }
1990:
1.1.1.5 root 1991: void op_mtc0_compare (void)
1.1 root 1992: {
1.1.1.5 root 1993: CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1.1.1.6 ! root 1994: FORCE_RET();
1.1 root 1995: }
1996:
1.1.1.5 root 1997: void op_mtc0_status (void)
1.1 root 1998: {
1.1.1.5 root 1999: uint32_t val, old;
1.1.1.6 ! root 2000: uint32_t mask = env->CP0_Status_rw_bitmask;
1.1.1.5 root 2001:
1.1.1.6 ! root 2002: val = T0 & mask;
1.1.1.5 root 2003: old = env->CP0_Status;
1.1.1.6 ! root 2004: env->CP0_Status = (env->CP0_Status & ~mask) | val;
! 2005: CALL_FROM_TB1(compute_hflags, env);
! 2006: if (loglevel & CPU_LOG_EXEC)
! 2007: CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1.1.1.5 root 2008: CALL_FROM_TB1(cpu_mips_update_irq, env);
1.1.1.6 ! root 2009: FORCE_RET();
! 2010: }
! 2011:
! 2012: void op_mttc0_status(void)
! 2013: {
! 2014: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 2015: uint32_t tcstatus = env->CP0_TCStatus[other_tc];
! 2016:
! 2017: env->CP0_Status = T0 & ~0xf1000018;
! 2018: tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0));
! 2019: tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
! 2020: tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
! 2021: env->CP0_TCStatus[other_tc] = tcstatus;
! 2022: FORCE_RET();
1.1 root 2023: }
2024:
1.1.1.5 root 2025: void op_mtc0_intctl (void)
1.1 root 2026: {
1.1.1.6 ! root 2027: /* vectored interrupts not implemented, no performance counters. */
! 2028: env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0);
! 2029: FORCE_RET();
1.1 root 2030: }
2031:
1.1.1.5 root 2032: void op_mtc0_srsctl (void)
1.1 root 2033: {
1.1.1.6 ! root 2034: uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
! 2035: env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
! 2036: FORCE_RET();
1.1 root 2037: }
2038:
1.1.1.5 root 2039: void op_mtc0_srsmap (void)
1.1 root 2040: {
1.1.1.6 ! root 2041: env->CP0_SRSMap = T0;
! 2042: FORCE_RET();
1.1 root 2043: }
2044:
1.1.1.5 root 2045: void op_mtc0_cause (void)
1.1 root 2046: {
1.1.1.6 ! root 2047: uint32_t mask = 0x00C00300;
! 2048: uint32_t old = env->CP0_Cause;
! 2049:
! 2050: if (env->insn_flags & ISA_MIPS32R2)
! 2051: mask |= 1 << CP0Ca_DC;
! 2052:
! 2053: env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
! 2054:
! 2055: if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
! 2056: if (env->CP0_Cause & (1 << CP0Ca_DC))
! 2057: CALL_FROM_TB1(cpu_mips_stop_count, env);
! 2058: else
! 2059: CALL_FROM_TB1(cpu_mips_start_count, env);
! 2060: }
1.1.1.5 root 2061:
2062: /* Handle the software interrupt as an hardware one, as they
2063: are very similar */
2064: if (T0 & CP0Ca_IP_mask) {
2065: CALL_FROM_TB1(cpu_mips_update_irq, env);
2066: }
1.1.1.6 ! root 2067: FORCE_RET();
1.1 root 2068: }
2069:
1.1.1.5 root 2070: void op_mtc0_epc (void)
1.1 root 2071: {
1.1.1.6 ! root 2072: env->CP0_EPC = T0;
! 2073: FORCE_RET();
1.1 root 2074: }
2075:
1.1.1.5 root 2076: void op_mtc0_ebase (void)
1.1 root 2077: {
1.1.1.5 root 2078: /* vectored interrupts not implemented */
2079: /* Multi-CPU not implemented */
2080: env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
1.1.1.6 ! root 2081: FORCE_RET();
1.1 root 2082: }
2083:
1.1.1.5 root 2084: void op_mtc0_config0 (void)
1.1 root 2085: {
1.1.1.6 ! root 2086: env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
! 2087: FORCE_RET();
1.1 root 2088: }
2089:
1.1.1.5 root 2090: void op_mtc0_config2 (void)
1.1 root 2091: {
1.1.1.5 root 2092: /* tertiary/secondary caches not implemented */
2093: env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
1.1.1.6 ! root 2094: FORCE_RET();
1.1 root 2095: }
2096:
1.1.1.6 ! root 2097: void op_mtc0_watchlo (void)
1.1 root 2098: {
1.1.1.6 ! root 2099: /* Watch exceptions for instructions, data loads, data stores
! 2100: not implemented. */
! 2101: env->CP0_WatchLo[PARAM1] = (T0 & ~0x7);
! 2102: FORCE_RET();
1.1 root 2103: }
2104:
1.1.1.6 ! root 2105: void op_mtc0_watchhi (void)
1.1 root 2106: {
1.1.1.6 ! root 2107: env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8);
! 2108: env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7);
! 2109: FORCE_RET();
1.1 root 2110: }
2111:
1.1.1.5 root 2112: void op_mtc0_xcontext (void)
1.1 root 2113: {
1.1.1.6 ! root 2114: target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
! 2115: env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
! 2116: FORCE_RET();
1.1 root 2117: }
2118:
1.1.1.5 root 2119: void op_mtc0_framemask (void)
1.1 root 2120: {
1.1.1.5 root 2121: env->CP0_Framemask = T0; /* XXX */
1.1.1.6 ! root 2122: FORCE_RET();
1.1 root 2123: }
2124:
1.1.1.5 root 2125: void op_mtc0_debug (void)
1.1 root 2126: {
1.1.1.5 root 2127: env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
2128: if (T0 & (1 << CP0DB_DM))
2129: env->hflags |= MIPS_HFLAG_DM;
2130: else
2131: env->hflags &= ~MIPS_HFLAG_DM;
1.1.1.6 ! root 2132: FORCE_RET();
! 2133: }
! 2134:
! 2135: void op_mttc0_debug(void)
! 2136: {
! 2137: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 2138:
! 2139: /* XXX: Might be wrong, check with EJTAG spec. */
! 2140: env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
! 2141: env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
! 2142: (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
! 2143: FORCE_RET();
1.1 root 2144: }
2145:
1.1.1.5 root 2146: void op_mtc0_depc (void)
1.1 root 2147: {
1.1.1.6 ! root 2148: env->CP0_DEPC = T0;
! 2149: FORCE_RET();
1.1 root 2150: }
2151:
1.1.1.5 root 2152: void op_mtc0_performance0 (void)
1.1 root 2153: {
1.1.1.6 ! root 2154: env->CP0_Performance0 = T0 & 0x000007ff;
! 2155: FORCE_RET();
1.1 root 2156: }
2157:
1.1.1.5 root 2158: void op_mtc0_taglo (void)
1.1 root 2159: {
1.1.1.5 root 2160: env->CP0_TagLo = T0 & 0xFFFFFCF6;
1.1.1.6 ! root 2161: FORCE_RET();
1.1 root 2162: }
2163:
1.1.1.5 root 2164: void op_mtc0_datalo (void)
1.1 root 2165: {
1.1.1.5 root 2166: env->CP0_DataLo = T0; /* XXX */
1.1.1.6 ! root 2167: FORCE_RET();
1.1 root 2168: }
1.1.1.5 root 2169:
2170: void op_mtc0_taghi (void)
1.1 root 2171: {
1.1.1.5 root 2172: env->CP0_TagHi = T0; /* XXX */
1.1.1.6 ! root 2173: FORCE_RET();
1.1 root 2174: }
2175:
1.1.1.5 root 2176: void op_mtc0_datahi (void)
1.1 root 2177: {
1.1.1.5 root 2178: env->CP0_DataHi = T0; /* XXX */
1.1.1.6 ! root 2179: FORCE_RET();
1.1 root 2180: }
2181:
1.1.1.5 root 2182: void op_mtc0_errorepc (void)
1.1 root 2183: {
1.1.1.6 ! root 2184: env->CP0_ErrorEPC = T0;
! 2185: FORCE_RET();
1.1 root 2186: }
2187:
1.1.1.5 root 2188: void op_mtc0_desave (void)
1.1 root 2189: {
1.1.1.5 root 2190: env->CP0_DESAVE = T0;
1.1.1.6 ! root 2191: FORCE_RET();
! 2192: }
! 2193:
! 2194: #if defined(TARGET_MIPS64)
! 2195: void op_dmfc0_yqmask (void)
! 2196: {
! 2197: T0 = env->CP0_YQMask;
! 2198: FORCE_RET();
! 2199: }
! 2200:
! 2201: void op_dmfc0_vpeschedule (void)
! 2202: {
! 2203: T0 = env->CP0_VPESchedule;
! 2204: FORCE_RET();
! 2205: }
! 2206:
! 2207: void op_dmfc0_vpeschefback (void)
! 2208: {
! 2209: T0 = env->CP0_VPEScheFBack;
! 2210: FORCE_RET();
1.1 root 2211: }
2212:
1.1.1.5 root 2213: void op_dmfc0_entrylo0 (void)
1.1 root 2214: {
1.1.1.5 root 2215: T0 = env->CP0_EntryLo0;
1.1.1.6 ! root 2216: FORCE_RET();
! 2217: }
! 2218:
! 2219: void op_dmfc0_tcrestart (void)
! 2220: {
! 2221: T0 = env->PC[env->current_tc];
! 2222: FORCE_RET();
! 2223: }
! 2224:
! 2225: void op_dmfc0_tchalt (void)
! 2226: {
! 2227: T0 = env->CP0_TCHalt[env->current_tc];
! 2228: FORCE_RET();
! 2229: }
! 2230:
! 2231: void op_dmfc0_tccontext (void)
! 2232: {
! 2233: T0 = env->CP0_TCContext[env->current_tc];
! 2234: FORCE_RET();
! 2235: }
! 2236:
! 2237: void op_dmfc0_tcschedule (void)
! 2238: {
! 2239: T0 = env->CP0_TCSchedule[env->current_tc];
! 2240: FORCE_RET();
! 2241: }
! 2242:
! 2243: void op_dmfc0_tcschefback (void)
! 2244: {
! 2245: T0 = env->CP0_TCScheFBack[env->current_tc];
! 2246: FORCE_RET();
1.1 root 2247: }
2248:
1.1.1.5 root 2249: void op_dmfc0_entrylo1 (void)
1.1 root 2250: {
1.1.1.5 root 2251: T0 = env->CP0_EntryLo1;
1.1.1.6 ! root 2252: FORCE_RET();
1.1 root 2253: }
2254:
1.1.1.5 root 2255: void op_dmfc0_context (void)
1.1 root 2256: {
1.1.1.5 root 2257: T0 = env->CP0_Context;
1.1.1.6 ! root 2258: FORCE_RET();
1.1 root 2259: }
2260:
1.1.1.5 root 2261: void op_dmfc0_badvaddr (void)
1.1 root 2262: {
1.1.1.5 root 2263: T0 = env->CP0_BadVAddr;
1.1.1.6 ! root 2264: FORCE_RET();
1.1 root 2265: }
2266:
1.1.1.5 root 2267: void op_dmfc0_entryhi (void)
2268: {
2269: T0 = env->CP0_EntryHi;
1.1.1.6 ! root 2270: FORCE_RET();
1.1 root 2271: }
2272:
1.1.1.5 root 2273: void op_dmfc0_epc (void)
2274: {
2275: T0 = env->CP0_EPC;
1.1.1.6 ! root 2276: FORCE_RET();
1.1.1.5 root 2277: }
1.1 root 2278:
1.1.1.5 root 2279: void op_dmfc0_lladdr (void)
2280: {
2281: T0 = env->CP0_LLAddr >> 4;
1.1.1.6 ! root 2282: FORCE_RET();
1.1.1.5 root 2283: }
1.1.1.2 root 2284:
1.1.1.6 ! root 2285: void op_dmfc0_watchlo (void)
1.1.1.2 root 2286: {
1.1.1.6 ! root 2287: T0 = env->CP0_WatchLo[PARAM1];
! 2288: FORCE_RET();
1.1.1.2 root 2289: }
2290:
1.1.1.5 root 2291: void op_dmfc0_xcontext (void)
1.1.1.2 root 2292: {
1.1.1.5 root 2293: T0 = env->CP0_XContext;
1.1.1.6 ! root 2294: FORCE_RET();
1.1.1.2 root 2295: }
1.1 root 2296:
1.1.1.5 root 2297: void op_dmfc0_depc (void)
1.1 root 2298: {
1.1.1.5 root 2299: T0 = env->CP0_DEPC;
1.1.1.6 ! root 2300: FORCE_RET();
1.1 root 2301: }
2302:
1.1.1.5 root 2303: void op_dmfc0_errorepc (void)
1.1 root 2304: {
1.1.1.5 root 2305: T0 = env->CP0_ErrorEPC;
1.1.1.6 ! root 2306: FORCE_RET();
1.1 root 2307: }
1.1.1.6 ! root 2308: #endif /* TARGET_MIPS64 */
1.1 root 2309:
1.1.1.6 ! root 2310: /* MIPS MT functions */
! 2311: void op_mftgpr(void)
1.1 root 2312: {
1.1.1.6 ! root 2313: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 2314:
! 2315: T0 = env->gpr[PARAM1][other_tc];
! 2316: FORCE_RET();
1.1 root 2317: }
2318:
1.1.1.6 ! root 2319: void op_mftlo(void)
1.1 root 2320: {
1.1.1.6 ! root 2321: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 2322:
! 2323: T0 = env->LO[PARAM1][other_tc];
! 2324: FORCE_RET();
1.1 root 2325: }
2326:
1.1.1.6 ! root 2327: void op_mfthi(void)
1.1 root 2328: {
1.1.1.6 ! root 2329: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 2330:
! 2331: T0 = env->HI[PARAM1][other_tc];
! 2332: FORCE_RET();
1.1 root 2333: }
2334:
1.1.1.6 ! root 2335: void op_mftacx(void)
1.1 root 2336: {
1.1.1.6 ! root 2337: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 2338:
! 2339: T0 = env->ACX[PARAM1][other_tc];
! 2340: FORCE_RET();
1.1 root 2341: }
2342:
1.1.1.6 ! root 2343: void op_mftdsp(void)
1.1 root 2344: {
1.1.1.6 ! root 2345: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 2346:
! 2347: T0 = env->DSPControl[other_tc];
! 2348: FORCE_RET();
1.1 root 2349: }
2350:
1.1.1.6 ! root 2351: void op_mttgpr(void)
1.1 root 2352: {
1.1.1.6 ! root 2353: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 2354:
! 2355: T0 = env->gpr[PARAM1][other_tc];
! 2356: FORCE_RET();
1.1 root 2357: }
2358:
1.1.1.6 ! root 2359: void op_mttlo(void)
1.1 root 2360: {
1.1.1.6 ! root 2361: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 2362:
! 2363: T0 = env->LO[PARAM1][other_tc];
! 2364: FORCE_RET();
1.1 root 2365: }
2366:
1.1.1.6 ! root 2367: void op_mtthi(void)
1.1 root 2368: {
1.1.1.6 ! root 2369: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 2370:
! 2371: T0 = env->HI[PARAM1][other_tc];
! 2372: FORCE_RET();
1.1 root 2373: }
2374:
1.1.1.6 ! root 2375: void op_mttacx(void)
! 2376: {
! 2377: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1.1.1.4 root 2378:
1.1.1.6 ! root 2379: T0 = env->ACX[PARAM1][other_tc];
! 2380: FORCE_RET();
! 2381: }
! 2382:
! 2383: void op_mttdsp(void)
! 2384: {
! 2385: int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
! 2386:
! 2387: T0 = env->DSPControl[other_tc];
! 2388: FORCE_RET();
! 2389: }
! 2390:
! 2391:
! 2392: void op_dmt(void)
! 2393: {
! 2394: // TODO
! 2395: T0 = 0;
! 2396: // rt = T0
! 2397: FORCE_RET();
! 2398: }
! 2399:
! 2400: void op_emt(void)
! 2401: {
! 2402: // TODO
! 2403: T0 = 0;
! 2404: // rt = T0
! 2405: FORCE_RET();
! 2406: }
! 2407:
! 2408: void op_dvpe(void)
! 2409: {
! 2410: // TODO
! 2411: T0 = 0;
! 2412: // rt = T0
! 2413: FORCE_RET();
! 2414: }
1.1.1.4 root 2415:
1.1.1.6 ! root 2416: void op_evpe(void)
1.1.1.4 root 2417: {
1.1.1.6 ! root 2418: // TODO
! 2419: T0 = 0;
! 2420: // rt = T0
! 2421: FORCE_RET();
! 2422: }
! 2423:
! 2424: void op_fork(void)
! 2425: {
! 2426: // T0 = rt, T1 = rs
! 2427: T0 = 0;
! 2428: // TODO: store to TC register
! 2429: FORCE_RET();
! 2430: }
! 2431:
! 2432: void op_yield(void)
! 2433: {
! 2434: if (T0 < 0) {
! 2435: /* No scheduling policy implemented. */
! 2436: if (T0 != -2) {
! 2437: if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
! 2438: env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) {
! 2439: env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
! 2440: env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
! 2441: CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
! 2442: }
! 2443: }
! 2444: } else if (T0 == 0) {
! 2445: if (0 /* TODO: TC underflow */) {
! 2446: env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
! 2447: CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
! 2448: } else {
! 2449: // TODO: Deallocate TC
! 2450: }
! 2451: } else if (T0 > 0) {
! 2452: /* Yield qualifier inputs not implemented. */
! 2453: env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
! 2454: env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
! 2455: CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1.1.1.4 root 2456: }
1.1.1.6 ! root 2457: T0 = env->CP0_YQMask;
! 2458: FORCE_RET();
1.1.1.4 root 2459: }
2460:
2461: /* CP1 functions */
1.1.1.6 ! root 2462: #if 0
! 2463: # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
! 2464: #else
! 2465: # define DEBUG_FPU_STATE() do { } while(0)
! 2466: #endif
! 2467:
1.1.1.4 root 2468: void op_cfc1 (void)
2469: {
1.1.1.6 ! root 2470: CALL_FROM_TB1(do_cfc1, PARAM1);
1.1.1.4 root 2471: DEBUG_FPU_STATE();
1.1.1.6 ! root 2472: FORCE_RET();
1.1.1.4 root 2473: }
2474:
2475: void op_ctc1 (void)
2476: {
1.1.1.6 ! root 2477: CALL_FROM_TB1(do_ctc1, PARAM1);
1.1.1.4 root 2478: DEBUG_FPU_STATE();
1.1.1.6 ! root 2479: FORCE_RET();
1.1.1.4 root 2480: }
2481:
2482: void op_mfc1 (void)
2483: {
1.1.1.6 ! root 2484: T0 = (int32_t)WT0;
1.1.1.4 root 2485: DEBUG_FPU_STATE();
1.1.1.6 ! root 2486: FORCE_RET();
1.1.1.4 root 2487: }
2488:
2489: void op_mtc1 (void)
2490: {
2491: WT0 = T0;
2492: DEBUG_FPU_STATE();
1.1.1.6 ! root 2493: FORCE_RET();
! 2494: }
! 2495:
! 2496: void op_dmfc1 (void)
! 2497: {
! 2498: T0 = DT0;
! 2499: DEBUG_FPU_STATE();
! 2500: FORCE_RET();
! 2501: }
! 2502:
! 2503: void op_dmtc1 (void)
! 2504: {
! 2505: DT0 = T0;
! 2506: DEBUG_FPU_STATE();
! 2507: FORCE_RET();
! 2508: }
! 2509:
! 2510: void op_mfhc1 (void)
! 2511: {
! 2512: T0 = (int32_t)WTH0;
! 2513: DEBUG_FPU_STATE();
! 2514: FORCE_RET();
! 2515: }
! 2516:
! 2517: void op_mthc1 (void)
! 2518: {
! 2519: WTH0 = T0;
! 2520: DEBUG_FPU_STATE();
! 2521: FORCE_RET();
1.1.1.4 root 2522: }
2523:
2524: /* Float support.
2525: Single precition routines have a "s" suffix, double precision a
1.1.1.6 ! root 2526: "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
! 2527: paired single lowwer "pl", paired single upper "pu". */
1.1.1.4 root 2528:
2529: #define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
2530:
1.1.1.5 root 2531: FLOAT_OP(cvtd, s)
2532: {
1.1.1.6 ! root 2533: CALL_FROM_TB0(do_float_cvtd_s);
1.1.1.5 root 2534: DEBUG_FPU_STATE();
1.1.1.6 ! root 2535: FORCE_RET();
1.1.1.5 root 2536: }
1.1.1.4 root 2537: FLOAT_OP(cvtd, w)
2538: {
1.1.1.6 ! root 2539: CALL_FROM_TB0(do_float_cvtd_w);
! 2540: DEBUG_FPU_STATE();
! 2541: FORCE_RET();
! 2542: }
! 2543: FLOAT_OP(cvtd, l)
! 2544: {
! 2545: CALL_FROM_TB0(do_float_cvtd_l);
! 2546: DEBUG_FPU_STATE();
! 2547: FORCE_RET();
! 2548: }
! 2549: FLOAT_OP(cvtl, d)
! 2550: {
! 2551: CALL_FROM_TB0(do_float_cvtl_d);
! 2552: DEBUG_FPU_STATE();
! 2553: FORCE_RET();
! 2554: }
! 2555: FLOAT_OP(cvtl, s)
! 2556: {
! 2557: CALL_FROM_TB0(do_float_cvtl_s);
! 2558: DEBUG_FPU_STATE();
! 2559: FORCE_RET();
! 2560: }
! 2561: FLOAT_OP(cvtps, s)
! 2562: {
! 2563: WT2 = WT0;
! 2564: WTH2 = WT1;
1.1.1.4 root 2565: DEBUG_FPU_STATE();
1.1.1.6 ! root 2566: FORCE_RET();
! 2567: }
! 2568: FLOAT_OP(cvtps, pw)
! 2569: {
! 2570: CALL_FROM_TB0(do_float_cvtps_pw);
! 2571: DEBUG_FPU_STATE();
! 2572: FORCE_RET();
! 2573: }
! 2574: FLOAT_OP(cvtpw, ps)
! 2575: {
! 2576: CALL_FROM_TB0(do_float_cvtpw_ps);
! 2577: DEBUG_FPU_STATE();
! 2578: FORCE_RET();
1.1.1.4 root 2579: }
1.1.1.5 root 2580: FLOAT_OP(cvts, d)
2581: {
1.1.1.6 ! root 2582: CALL_FROM_TB0(do_float_cvts_d);
1.1.1.5 root 2583: DEBUG_FPU_STATE();
1.1.1.6 ! root 2584: FORCE_RET();
1.1.1.5 root 2585: }
1.1.1.4 root 2586: FLOAT_OP(cvts, w)
2587: {
1.1.1.6 ! root 2588: CALL_FROM_TB0(do_float_cvts_w);
! 2589: DEBUG_FPU_STATE();
! 2590: FORCE_RET();
! 2591: }
! 2592: FLOAT_OP(cvts, l)
! 2593: {
! 2594: CALL_FROM_TB0(do_float_cvts_l);
! 2595: DEBUG_FPU_STATE();
! 2596: FORCE_RET();
! 2597: }
! 2598: FLOAT_OP(cvts, pl)
! 2599: {
! 2600: CALL_FROM_TB0(do_float_cvts_pl);
1.1.1.4 root 2601: DEBUG_FPU_STATE();
1.1.1.6 ! root 2602: FORCE_RET();
! 2603: }
! 2604: FLOAT_OP(cvts, pu)
! 2605: {
! 2606: CALL_FROM_TB0(do_float_cvts_pu);
! 2607: DEBUG_FPU_STATE();
! 2608: FORCE_RET();
1.1.1.4 root 2609: }
2610: FLOAT_OP(cvtw, s)
2611: {
1.1.1.6 ! root 2612: CALL_FROM_TB0(do_float_cvtw_s);
1.1.1.4 root 2613: DEBUG_FPU_STATE();
1.1.1.6 ! root 2614: FORCE_RET();
1.1.1.4 root 2615: }
2616: FLOAT_OP(cvtw, d)
2617: {
1.1.1.6 ! root 2618: CALL_FROM_TB0(do_float_cvtw_d);
1.1.1.4 root 2619: DEBUG_FPU_STATE();
1.1.1.6 ! root 2620: FORCE_RET();
1.1.1.4 root 2621: }
2622:
1.1.1.6 ! root 2623: FLOAT_OP(pll, ps)
1.1.1.4 root 2624: {
1.1.1.6 ! root 2625: DT2 = ((uint64_t)WT0 << 32) | WT1;
1.1.1.4 root 2626: DEBUG_FPU_STATE();
1.1.1.6 ! root 2627: FORCE_RET();
1.1.1.4 root 2628: }
1.1.1.6 ! root 2629: FLOAT_OP(plu, ps)
1.1.1.4 root 2630: {
1.1.1.6 ! root 2631: DT2 = ((uint64_t)WT0 << 32) | WTH1;
1.1.1.4 root 2632: DEBUG_FPU_STATE();
1.1.1.6 ! root 2633: FORCE_RET();
1.1.1.4 root 2634: }
1.1.1.6 ! root 2635: FLOAT_OP(pul, ps)
1.1.1.4 root 2636: {
1.1.1.6 ! root 2637: DT2 = ((uint64_t)WTH0 << 32) | WT1;
1.1.1.4 root 2638: DEBUG_FPU_STATE();
1.1.1.6 ! root 2639: FORCE_RET();
1.1.1.4 root 2640: }
1.1.1.6 ! root 2641: FLOAT_OP(puu, ps)
1.1.1.4 root 2642: {
1.1.1.6 ! root 2643: DT2 = ((uint64_t)WTH0 << 32) | WTH1;
1.1.1.4 root 2644: DEBUG_FPU_STATE();
1.1.1.6 ! root 2645: FORCE_RET();
1.1.1.4 root 2646: }
2647:
1.1.1.6 ! root 2648: #define FLOAT_ROUNDOP(op, ttype, stype) \
! 2649: FLOAT_OP(op ## ttype, stype) \
! 2650: { \
! 2651: CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
! 2652: DEBUG_FPU_STATE(); \
! 2653: FORCE_RET(); \
! 2654: }
! 2655:
! 2656: FLOAT_ROUNDOP(round, l, d)
! 2657: FLOAT_ROUNDOP(round, l, s)
! 2658: FLOAT_ROUNDOP(round, w, d)
! 2659: FLOAT_ROUNDOP(round, w, s)
1.1.1.4 root 2660:
1.1.1.6 ! root 2661: FLOAT_ROUNDOP(trunc, l, d)
! 2662: FLOAT_ROUNDOP(trunc, l, s)
! 2663: FLOAT_ROUNDOP(trunc, w, d)
! 2664: FLOAT_ROUNDOP(trunc, w, s)
! 2665:
! 2666: FLOAT_ROUNDOP(ceil, l, d)
! 2667: FLOAT_ROUNDOP(ceil, l, s)
! 2668: FLOAT_ROUNDOP(ceil, w, d)
! 2669: FLOAT_ROUNDOP(ceil, w, s)
! 2670:
! 2671: FLOAT_ROUNDOP(floor, l, d)
! 2672: FLOAT_ROUNDOP(floor, l, s)
! 2673: FLOAT_ROUNDOP(floor, w, d)
! 2674: FLOAT_ROUNDOP(floor, w, s)
! 2675: #undef FLOAR_ROUNDOP
! 2676:
! 2677: FLOAT_OP(movf, d)
! 2678: {
! 2679: if (!(env->fpu->fcr31 & PARAM1))
! 2680: DT2 = DT0;
1.1.1.4 root 2681: DEBUG_FPU_STATE();
1.1.1.6 ! root 2682: FORCE_RET();
1.1.1.4 root 2683: }
1.1.1.6 ! root 2684: FLOAT_OP(movf, s)
1.1.1.4 root 2685: {
1.1.1.6 ! root 2686: if (!(env->fpu->fcr31 & PARAM1))
! 2687: WT2 = WT0;
1.1.1.4 root 2688: DEBUG_FPU_STATE();
1.1.1.6 ! root 2689: FORCE_RET();
1.1.1.4 root 2690: }
1.1.1.6 ! root 2691: FLOAT_OP(movf, ps)
1.1.1.4 root 2692: {
1.1.1.6 ! root 2693: if (!(env->fpu->fcr31 & PARAM1)) {
! 2694: WT2 = WT0;
! 2695: WTH2 = WTH0;
! 2696: }
! 2697: DEBUG_FPU_STATE();
! 2698: FORCE_RET();
! 2699: }
! 2700: FLOAT_OP(movt, d)
! 2701: {
! 2702: if (env->fpu->fcr31 & PARAM1)
! 2703: DT2 = DT0;
! 2704: DEBUG_FPU_STATE();
! 2705: FORCE_RET();
! 2706: }
! 2707: FLOAT_OP(movt, s)
! 2708: {
! 2709: if (env->fpu->fcr31 & PARAM1)
! 2710: WT2 = WT0;
! 2711: DEBUG_FPU_STATE();
! 2712: FORCE_RET();
! 2713: }
! 2714: FLOAT_OP(movt, ps)
! 2715: {
! 2716: if (env->fpu->fcr31 & PARAM1) {
! 2717: WT2 = WT0;
! 2718: WTH2 = WTH0;
! 2719: }
! 2720: DEBUG_FPU_STATE();
! 2721: FORCE_RET();
! 2722: }
! 2723: FLOAT_OP(movz, d)
! 2724: {
! 2725: if (!T0)
! 2726: DT2 = DT0;
1.1.1.4 root 2727: DEBUG_FPU_STATE();
1.1.1.6 ! root 2728: FORCE_RET();
1.1.1.4 root 2729: }
1.1.1.6 ! root 2730: FLOAT_OP(movz, s)
1.1.1.4 root 2731: {
1.1.1.6 ! root 2732: if (!T0)
! 2733: WT2 = WT0;
1.1.1.4 root 2734: DEBUG_FPU_STATE();
1.1.1.6 ! root 2735: FORCE_RET();
! 2736: }
! 2737: FLOAT_OP(movz, ps)
! 2738: {
! 2739: if (!T0) {
! 2740: WT2 = WT0;
! 2741: WTH2 = WTH0;
! 2742: }
! 2743: DEBUG_FPU_STATE();
! 2744: FORCE_RET();
! 2745: }
! 2746: FLOAT_OP(movn, d)
! 2747: {
! 2748: if (T0)
! 2749: DT2 = DT0;
! 2750: DEBUG_FPU_STATE();
! 2751: FORCE_RET();
! 2752: }
! 2753: FLOAT_OP(movn, s)
! 2754: {
! 2755: if (T0)
! 2756: WT2 = WT0;
! 2757: DEBUG_FPU_STATE();
! 2758: FORCE_RET();
! 2759: }
! 2760: FLOAT_OP(movn, ps)
! 2761: {
! 2762: if (T0) {
! 2763: WT2 = WT0;
! 2764: WTH2 = WTH0;
! 2765: }
! 2766: DEBUG_FPU_STATE();
! 2767: FORCE_RET();
! 2768: }
! 2769:
! 2770: /* operations calling helpers, for s, d and ps */
! 2771: #define FLOAT_HOP(name) \
! 2772: FLOAT_OP(name, d) \
! 2773: { \
! 2774: CALL_FROM_TB0(do_float_ ## name ## _d); \
! 2775: DEBUG_FPU_STATE(); \
! 2776: FORCE_RET(); \
! 2777: } \
! 2778: FLOAT_OP(name, s) \
! 2779: { \
! 2780: CALL_FROM_TB0(do_float_ ## name ## _s); \
! 2781: DEBUG_FPU_STATE(); \
! 2782: FORCE_RET(); \
! 2783: } \
! 2784: FLOAT_OP(name, ps) \
! 2785: { \
! 2786: CALL_FROM_TB0(do_float_ ## name ## _ps); \
! 2787: DEBUG_FPU_STATE(); \
! 2788: FORCE_RET(); \
1.1.1.4 root 2789: }
1.1.1.6 ! root 2790: FLOAT_HOP(add)
! 2791: FLOAT_HOP(sub)
! 2792: FLOAT_HOP(mul)
! 2793: FLOAT_HOP(div)
! 2794: FLOAT_HOP(recip2)
! 2795: FLOAT_HOP(rsqrt2)
! 2796: FLOAT_HOP(rsqrt1)
! 2797: FLOAT_HOP(recip1)
! 2798: #undef FLOAT_HOP
1.1.1.4 root 2799:
1.1.1.6 ! root 2800: /* operations calling helpers, for s and d */
! 2801: #define FLOAT_HOP(name) \
1.1.1.4 root 2802: FLOAT_OP(name, d) \
2803: { \
1.1.1.6 ! root 2804: CALL_FROM_TB0(do_float_ ## name ## _d); \
1.1.1.4 root 2805: DEBUG_FPU_STATE(); \
1.1.1.6 ! root 2806: FORCE_RET(); \
1.1.1.4 root 2807: } \
2808: FLOAT_OP(name, s) \
2809: { \
1.1.1.6 ! root 2810: CALL_FROM_TB0(do_float_ ## name ## _s); \
! 2811: DEBUG_FPU_STATE(); \
! 2812: FORCE_RET(); \
! 2813: }
! 2814: FLOAT_HOP(rsqrt)
! 2815: FLOAT_HOP(recip)
! 2816: #undef FLOAT_HOP
! 2817:
! 2818: /* operations calling helpers, for ps */
! 2819: #define FLOAT_HOP(name) \
! 2820: FLOAT_OP(name, ps) \
! 2821: { \
! 2822: CALL_FROM_TB0(do_float_ ## name ## _ps); \
1.1.1.4 root 2823: DEBUG_FPU_STATE(); \
1.1.1.6 ! root 2824: FORCE_RET(); \
1.1.1.4 root 2825: }
1.1.1.6 ! root 2826: FLOAT_HOP(addr)
! 2827: FLOAT_HOP(mulr)
! 2828: #undef FLOAT_HOP
! 2829:
! 2830: /* ternary operations */
! 2831: #define FLOAT_TERNOP(name1, name2) \
! 2832: FLOAT_OP(name1 ## name2, d) \
! 2833: { \
! 2834: FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \
! 2835: FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \
! 2836: DEBUG_FPU_STATE(); \
! 2837: FORCE_RET(); \
! 2838: } \
! 2839: FLOAT_OP(name1 ## name2, s) \
! 2840: { \
! 2841: FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
! 2842: FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
! 2843: DEBUG_FPU_STATE(); \
! 2844: FORCE_RET(); \
! 2845: } \
! 2846: FLOAT_OP(name1 ## name2, ps) \
! 2847: { \
! 2848: FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
! 2849: FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
! 2850: FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
! 2851: FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
! 2852: DEBUG_FPU_STATE(); \
! 2853: FORCE_RET(); \
! 2854: }
! 2855: FLOAT_TERNOP(mul, add)
! 2856: FLOAT_TERNOP(mul, sub)
! 2857: #undef FLOAT_TERNOP
! 2858:
! 2859: /* negated ternary operations */
! 2860: #define FLOAT_NTERNOP(name1, name2) \
! 2861: FLOAT_OP(n ## name1 ## name2, d) \
! 2862: { \
! 2863: FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \
! 2864: FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \
! 2865: FDT2 = float64_chs(FDT2); \
! 2866: DEBUG_FPU_STATE(); \
! 2867: FORCE_RET(); \
! 2868: } \
! 2869: FLOAT_OP(n ## name1 ## name2, s) \
! 2870: { \
! 2871: FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
! 2872: FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
! 2873: FST2 = float32_chs(FST2); \
! 2874: DEBUG_FPU_STATE(); \
! 2875: FORCE_RET(); \
! 2876: } \
! 2877: FLOAT_OP(n ## name1 ## name2, ps) \
! 2878: { \
! 2879: FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
! 2880: FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
! 2881: FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
! 2882: FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
! 2883: FST2 = float32_chs(FST2); \
! 2884: FSTH2 = float32_chs(FSTH2); \
! 2885: DEBUG_FPU_STATE(); \
! 2886: FORCE_RET(); \
! 2887: }
! 2888: FLOAT_NTERNOP(mul, add)
! 2889: FLOAT_NTERNOP(mul, sub)
! 2890: #undef FLOAT_NTERNOP
1.1.1.4 root 2891:
2892: /* unary operations, modifying fp status */
2893: #define FLOAT_UNOP(name) \
2894: FLOAT_OP(name, d) \
2895: { \
1.1.1.6 ! root 2896: FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
1.1.1.4 root 2897: DEBUG_FPU_STATE(); \
1.1.1.6 ! root 2898: FORCE_RET(); \
1.1.1.4 root 2899: } \
2900: FLOAT_OP(name, s) \
2901: { \
1.1.1.6 ! root 2902: FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
1.1.1.4 root 2903: DEBUG_FPU_STATE(); \
1.1.1.6 ! root 2904: FORCE_RET(); \
1.1.1.4 root 2905: }
2906: FLOAT_UNOP(sqrt)
2907: #undef FLOAT_UNOP
2908:
2909: /* unary operations, not modifying fp status */
2910: #define FLOAT_UNOP(name) \
2911: FLOAT_OP(name, d) \
2912: { \
2913: FDT2 = float64_ ## name(FDT0); \
2914: DEBUG_FPU_STATE(); \
1.1.1.6 ! root 2915: FORCE_RET(); \
1.1.1.4 root 2916: } \
2917: FLOAT_OP(name, s) \
2918: { \
2919: FST2 = float32_ ## name(FST0); \
2920: DEBUG_FPU_STATE(); \
1.1.1.6 ! root 2921: FORCE_RET(); \
! 2922: } \
! 2923: FLOAT_OP(name, ps) \
! 2924: { \
! 2925: FST2 = float32_ ## name(FST0); \
! 2926: FSTH2 = float32_ ## name(FSTH0); \
! 2927: DEBUG_FPU_STATE(); \
! 2928: FORCE_RET(); \
1.1.1.4 root 2929: }
2930: FLOAT_UNOP(abs)
2931: FLOAT_UNOP(chs)
2932: #undef FLOAT_UNOP
2933:
2934: FLOAT_OP(mov, d)
2935: {
2936: FDT2 = FDT0;
2937: DEBUG_FPU_STATE();
1.1.1.6 ! root 2938: FORCE_RET();
1.1.1.4 root 2939: }
2940: FLOAT_OP(mov, s)
2941: {
2942: FST2 = FST0;
2943: DEBUG_FPU_STATE();
1.1.1.6 ! root 2944: FORCE_RET();
! 2945: }
! 2946: FLOAT_OP(mov, ps)
! 2947: {
! 2948: FST2 = FST0;
! 2949: FSTH2 = FSTH0;
! 2950: DEBUG_FPU_STATE();
! 2951: FORCE_RET();
! 2952: }
! 2953: FLOAT_OP(alnv, ps)
! 2954: {
! 2955: switch (T0 & 0x7) {
! 2956: case 0:
! 2957: FST2 = FST0;
! 2958: FSTH2 = FSTH0;
! 2959: break;
! 2960: case 4:
! 2961: #ifdef TARGET_WORDS_BIGENDIAN
! 2962: FSTH2 = FST0;
! 2963: FST2 = FSTH1;
! 2964: #else
! 2965: FSTH2 = FST1;
! 2966: FST2 = FSTH0;
! 2967: #endif
! 2968: break;
! 2969: default: /* unpredictable */
! 2970: break;
! 2971: }
! 2972: DEBUG_FPU_STATE();
! 2973: FORCE_RET();
1.1.1.4 root 2974: }
2975:
2976: #ifdef CONFIG_SOFTFLOAT
2977: #define clear_invalid() do { \
1.1.1.6 ! root 2978: int flags = get_float_exception_flags(&env->fpu->fp_status); \
1.1.1.4 root 2979: flags &= ~float_flag_invalid; \
1.1.1.6 ! root 2980: set_float_exception_flags(flags, &env->fpu->fp_status); \
1.1.1.4 root 2981: } while(0)
2982: #else
2983: #define clear_invalid() do { } while(0)
2984: #endif
2985:
2986: extern void dump_fpu_s(CPUState *env);
2987:
1.1.1.6 ! root 2988: #define CMP_OP(fmt, op) \
! 2989: void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void) \
! 2990: { \
! 2991: CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
! 2992: DEBUG_FPU_STATE(); \
! 2993: FORCE_RET(); \
! 2994: } \
! 2995: void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void) \
! 2996: { \
! 2997: CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
! 2998: DEBUG_FPU_STATE(); \
! 2999: FORCE_RET(); \
! 3000: }
! 3001: #define CMP_OPS(op) \
! 3002: CMP_OP(d, op) \
! 3003: CMP_OP(s, op) \
! 3004: CMP_OP(ps, op)
! 3005:
! 3006: CMP_OPS(f)
! 3007: CMP_OPS(un)
! 3008: CMP_OPS(eq)
! 3009: CMP_OPS(ueq)
! 3010: CMP_OPS(olt)
! 3011: CMP_OPS(ult)
! 3012: CMP_OPS(ole)
! 3013: CMP_OPS(ule)
! 3014: CMP_OPS(sf)
! 3015: CMP_OPS(ngle)
! 3016: CMP_OPS(seq)
! 3017: CMP_OPS(ngl)
! 3018: CMP_OPS(lt)
! 3019: CMP_OPS(nge)
! 3020: CMP_OPS(le)
! 3021: CMP_OPS(ngt)
! 3022: #undef CMP_OPS
! 3023: #undef CMP_OP
1.1.1.4 root 3024:
1.1.1.6 ! root 3025: void op_bc1f (void)
1.1.1.4 root 3026: {
1.1.1.6 ! root 3027: T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
! 3028: DEBUG_FPU_STATE();
! 3029: FORCE_RET();
1.1.1.4 root 3030: }
1.1.1.6 ! root 3031: void op_bc1any2f (void)
! 3032: {
! 3033: T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
! 3034: DEBUG_FPU_STATE();
! 3035: FORCE_RET();
! 3036: }
! 3037: void op_bc1any4f (void)
1.1.1.4 root 3038: {
1.1.1.6 ! root 3039: T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
1.1.1.4 root 3040: DEBUG_FPU_STATE();
1.1.1.6 ! root 3041: FORCE_RET();
1.1.1.4 root 3042: }
3043:
3044: void op_bc1t (void)
3045: {
1.1.1.6 ! root 3046: T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
! 3047: DEBUG_FPU_STATE();
! 3048: FORCE_RET();
! 3049: }
! 3050: void op_bc1any2t (void)
! 3051: {
! 3052: T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
! 3053: DEBUG_FPU_STATE();
! 3054: FORCE_RET();
! 3055: }
! 3056: void op_bc1any4t (void)
! 3057: {
! 3058: T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
1.1.1.4 root 3059: DEBUG_FPU_STATE();
1.1.1.6 ! root 3060: FORCE_RET();
1.1.1.4 root 3061: }
3062:
1.1 root 3063: void op_tlbwi (void)
3064: {
1.1.1.6 ! root 3065: CALL_FROM_TB0(env->tlb->do_tlbwi);
! 3066: FORCE_RET();
1.1 root 3067: }
3068:
3069: void op_tlbwr (void)
3070: {
1.1.1.6 ! root 3071: CALL_FROM_TB0(env->tlb->do_tlbwr);
! 3072: FORCE_RET();
1.1 root 3073: }
3074:
3075: void op_tlbp (void)
3076: {
1.1.1.6 ! root 3077: CALL_FROM_TB0(env->tlb->do_tlbp);
! 3078: FORCE_RET();
1.1 root 3079: }
3080:
3081: void op_tlbr (void)
3082: {
1.1.1.6 ! root 3083: CALL_FROM_TB0(env->tlb->do_tlbr);
! 3084: FORCE_RET();
1.1 root 3085: }
3086:
3087: /* Specials */
1.1.1.6 ! root 3088: #if defined (CONFIG_USER_ONLY)
! 3089: void op_tls_value (void)
! 3090: {
! 3091: T0 = env->tls_value;
! 3092: }
! 3093: #endif
! 3094:
1.1 root 3095: void op_pmon (void)
3096: {
3097: CALL_FROM_TB1(do_pmon, PARAM1);
1.1.1.6 ! root 3098: FORCE_RET();
1.1.1.5 root 3099: }
3100:
3101: void op_di (void)
3102: {
3103: T0 = env->CP0_Status;
3104: env->CP0_Status = T0 & ~(1 << CP0St_IE);
3105: CALL_FROM_TB1(cpu_mips_update_irq, env);
1.1.1.6 ! root 3106: FORCE_RET();
1.1.1.5 root 3107: }
3108:
3109: void op_ei (void)
3110: {
3111: T0 = env->CP0_Status;
3112: env->CP0_Status = T0 | (1 << CP0St_IE);
3113: CALL_FROM_TB1(cpu_mips_update_irq, env);
1.1.1.6 ! root 3114: FORCE_RET();
1.1 root 3115: }
3116:
3117: void op_trap (void)
3118: {
3119: if (T0) {
1.1.1.6 ! root 3120: CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
1.1 root 3121: }
1.1.1.6 ! root 3122: FORCE_RET();
1.1 root 3123: }
3124:
1.1.1.2 root 3125: void op_debug (void)
3126: {
1.1.1.5 root 3127: CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
1.1.1.6 ! root 3128: FORCE_RET();
1.1.1.2 root 3129: }
3130:
1.1 root 3131: void op_set_lladdr (void)
3132: {
3133: env->CP0_LLAddr = T2;
1.1.1.6 ! root 3134: FORCE_RET();
1.1 root 3135: }
3136:
1.1.1.6 ! root 3137: void debug_pre_eret (void);
! 3138: void debug_post_eret (void);
1.1 root 3139: void op_eret (void)
3140: {
1.1.1.6 ! root 3141: if (loglevel & CPU_LOG_EXEC)
! 3142: CALL_FROM_TB0(debug_pre_eret);
! 3143: if (env->CP0_Status & (1 << CP0St_ERL)) {
! 3144: env->PC[env->current_tc] = env->CP0_ErrorEPC;
! 3145: env->CP0_Status &= ~(1 << CP0St_ERL);
1.1 root 3146: } else {
1.1.1.6 ! root 3147: env->PC[env->current_tc] = env->CP0_EPC;
! 3148: env->CP0_Status &= ~(1 << CP0St_EXL);
1.1 root 3149: }
1.1.1.6 ! root 3150: CALL_FROM_TB1(compute_hflags, env);
! 3151: if (loglevel & CPU_LOG_EXEC)
! 3152: CALL_FROM_TB0(debug_post_eret);
1.1 root 3153: env->CP0_LLAddr = 1;
1.1.1.6 ! root 3154: FORCE_RET();
1.1 root 3155: }
3156:
3157: void op_deret (void)
3158: {
1.1.1.6 ! root 3159: if (loglevel & CPU_LOG_EXEC)
! 3160: CALL_FROM_TB0(debug_pre_eret);
! 3161: env->PC[env->current_tc] = env->CP0_DEPC;
! 3162: env->hflags &= MIPS_HFLAG_DM;
! 3163: CALL_FROM_TB1(compute_hflags, env);
! 3164: if (loglevel & CPU_LOG_EXEC)
! 3165: CALL_FROM_TB0(debug_post_eret);
! 3166: env->CP0_LLAddr = 1;
! 3167: FORCE_RET();
1.1.1.5 root 3168: }
3169:
3170: void op_rdhwr_cpunum(void)
3171: {
1.1.1.6 ! root 3172: if ((env->hflags & MIPS_HFLAG_CP0) ||
! 3173: (env->CP0_HWREna & (1 << 0)))
! 3174: T0 = env->CP0_EBase & 0x3ff;
1.1.1.5 root 3175: else
1.1.1.6 ! root 3176: CALL_FROM_TB1(do_raise_exception, EXCP_RI);
! 3177: FORCE_RET();
1.1.1.5 root 3178: }
3179:
3180: void op_rdhwr_synci_step(void)
3181: {
1.1.1.6 ! root 3182: if ((env->hflags & MIPS_HFLAG_CP0) ||
! 3183: (env->CP0_HWREna & (1 << 1)))
! 3184: T0 = env->SYNCI_Step;
1.1.1.5 root 3185: else
1.1.1.6 ! root 3186: CALL_FROM_TB1(do_raise_exception, EXCP_RI);
! 3187: FORCE_RET();
1.1.1.5 root 3188: }
3189:
3190: void op_rdhwr_cc(void)
3191: {
1.1.1.6 ! root 3192: if ((env->hflags & MIPS_HFLAG_CP0) ||
! 3193: (env->CP0_HWREna & (1 << 2)))
! 3194: T0 = env->CP0_Count;
1.1.1.5 root 3195: else
1.1.1.6 ! root 3196: CALL_FROM_TB1(do_raise_exception, EXCP_RI);
! 3197: FORCE_RET();
1.1.1.5 root 3198: }
3199:
3200: void op_rdhwr_ccres(void)
3201: {
1.1.1.6 ! root 3202: if ((env->hflags & MIPS_HFLAG_CP0) ||
! 3203: (env->CP0_HWREna & (1 << 3)))
! 3204: T0 = env->CCRes;
1.1.1.5 root 3205: else
1.1.1.6 ! root 3206: CALL_FROM_TB1(do_raise_exception, EXCP_RI);
! 3207: FORCE_RET();
1.1 root 3208: }
3209:
3210: void op_save_state (void)
3211: {
3212: env->hflags = PARAM1;
1.1.1.6 ! root 3213: FORCE_RET();
1.1 root 3214: }
3215:
3216: void op_save_pc (void)
3217: {
1.1.1.6 ! root 3218: env->PC[env->current_tc] = PARAM1;
! 3219: FORCE_RET();
! 3220: }
! 3221:
! 3222: #if defined(TARGET_MIPS64)
! 3223: void op_save_pc64 (void)
! 3224: {
! 3225: env->PC[env->current_tc] = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2;
! 3226: FORCE_RET();
! 3227: }
! 3228: #endif
! 3229:
! 3230: void op_interrupt_restart (void)
! 3231: {
! 3232: if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
! 3233: !(env->CP0_Status & (1 << CP0St_ERL)) &&
! 3234: !(env->hflags & MIPS_HFLAG_DM) &&
! 3235: (env->CP0_Status & (1 << CP0St_IE)) &&
! 3236: (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask)) {
! 3237: env->CP0_Cause &= ~(0x1f << CP0Ca_EC);
! 3238: CALL_FROM_TB1(do_raise_exception, EXCP_EXT_INTERRUPT);
! 3239: }
! 3240: FORCE_RET();
1.1 root 3241: }
3242:
3243: void op_raise_exception (void)
3244: {
3245: CALL_FROM_TB1(do_raise_exception, PARAM1);
1.1.1.6 ! root 3246: FORCE_RET();
1.1 root 3247: }
3248:
3249: void op_raise_exception_err (void)
3250: {
3251: CALL_FROM_TB2(do_raise_exception_err, PARAM1, PARAM2);
1.1.1.6 ! root 3252: FORCE_RET();
1.1 root 3253: }
3254:
3255: void op_exit_tb (void)
3256: {
3257: EXIT_TB();
1.1.1.6 ! root 3258: FORCE_RET();
1.1 root 3259: }
3260:
1.1.1.2 root 3261: void op_wait (void)
3262: {
3263: env->halted = 1;
3264: CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
1.1.1.6 ! root 3265: FORCE_RET();
1.1.1.5 root 3266: }
3267:
3268: /* Bitfield operations. */
3269: void op_ext(void)
3270: {
3271: unsigned int pos = PARAM1;
3272: unsigned int size = PARAM2;
3273:
1.1.1.6 ! root 3274: T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
! 3275: FORCE_RET();
1.1.1.5 root 3276: }
3277:
3278: void op_ins(void)
3279: {
3280: unsigned int pos = PARAM1;
3281: unsigned int size = PARAM2;
1.1.1.6 ! root 3282: target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
1.1.1.5 root 3283:
1.1.1.6 ! root 3284: T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
! 3285: FORCE_RET();
1.1.1.5 root 3286: }
3287:
3288: void op_wsbh(void)
3289: {
1.1.1.6 ! root 3290: T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
! 3291: FORCE_RET();
1.1.1.5 root 3292: }
3293:
1.1.1.6 ! root 3294: #if defined(TARGET_MIPS64)
1.1.1.5 root 3295: void op_dext(void)
3296: {
3297: unsigned int pos = PARAM1;
3298: unsigned int size = PARAM2;
3299:
1.1.1.6 ! root 3300: T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
! 3301: FORCE_RET();
1.1.1.5 root 3302: }
3303:
3304: void op_dins(void)
3305: {
3306: unsigned int pos = PARAM1;
3307: unsigned int size = PARAM2;
1.1.1.6 ! root 3308: target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
1.1.1.5 root 3309:
1.1.1.6 ! root 3310: T0 = (T0 & ~mask) | ((T1 << pos) & mask);
! 3311: FORCE_RET();
1.1.1.5 root 3312: }
3313:
3314: void op_dsbh(void)
3315: {
3316: T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
1.1.1.6 ! root 3317: FORCE_RET();
1.1.1.5 root 3318: }
3319:
3320: void op_dshd(void)
3321: {
1.1.1.6 ! root 3322: T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
! 3323: T0 = (T1 << 32) | (T1 >> 32);
! 3324: FORCE_RET();
1.1.1.5 root 3325: }
3326: #endif
3327:
3328: void op_seb(void)
3329: {
3330: T0 = ((T1 & 0xFF) ^ 0x80) - 0x80;
1.1.1.6 ! root 3331: FORCE_RET();
1.1.1.5 root 3332: }
3333:
3334: void op_seh(void)
3335: {
3336: T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000;
1.1.1.6 ! root 3337: FORCE_RET();
1.1.1.2 root 3338: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.