2 * MIPS emulation micro-operations for qemu.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2007 Thiemo Seufer (64-bit FPU support)
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.
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.
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
25 #include "host-utils.h"
28 #define CALL_FROM_TB0(func) func()
31 #define CALL_FROM_TB1(func, arg0) func(arg0)
33 #ifndef CALL_FROM_TB1_CONST16
34 #define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0)
37 #define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1)
39 #ifndef CALL_FROM_TB2_CONST16
40 #define CALL_FROM_TB2_CONST16(func, arg0, arg1) \
41 CALL_FROM_TB2(func, arg0, arg1)
44 #define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2)
47 #define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \
48 func(arg0, arg1, arg2, arg3)
52 #include "fop_template.c"
55 #include "fop_template.c"
58 #include "fop_template.c"
61 #include "fop_template.c"
64 #include "fop_template.c"
67 #include "fop_template.c"
70 #include "fop_template.c"
73 #include "fop_template.c"
76 #include "fop_template.c"
79 #include "fop_template.c"
82 #include "fop_template.c"
85 #include "fop_template.c"
88 #include "fop_template.c"
91 #include "fop_template.c"
94 #include "fop_template.c"
97 #include "fop_template.c"
100 #include "fop_template.c"
103 #include "fop_template.c"
106 #include "fop_template.c"
109 #include "fop_template.c"
112 #include "fop_template.c"
115 #include "fop_template.c"
118 #include "fop_template.c"
121 #include "fop_template.c"
124 #include "fop_template.c"
127 #include "fop_template.c"
130 #include "fop_template.c"
133 #include "fop_template.c"
136 #include "fop_template.c"
139 #include "fop_template.c"
142 #include "fop_template.c"
145 #include "fop_template.c"
149 #define MEMSUFFIX _raw
152 #if !defined(CONFIG_USER_ONLY)
153 #define MEMSUFFIX _user
157 #define MEMSUFFIX _super
161 #define MEMSUFFIX _kernel
166 /* 64 bits arithmetic */
167 #if TARGET_LONG_BITS > HOST_LONG_BITS
170 CALL_FROM_TB0(do_mult);
176 CALL_FROM_TB0(do_multu);
182 CALL_FROM_TB0(do_madd);
188 CALL_FROM_TB0(do_maddu);
194 CALL_FROM_TB0(do_msub);
200 CALL_FROM_TB0(do_msubu);
204 /* Multiplication variants of the vr54xx. */
207 CALL_FROM_TB0(do_muls);
213 CALL_FROM_TB0(do_mulsu);
219 CALL_FROM_TB0(do_macc);
223 void op_macchi (void)
225 CALL_FROM_TB0(do_macchi);
231 CALL_FROM_TB0(do_maccu);
234 void op_macchiu (void)
236 CALL_FROM_TB0(do_macchiu);
242 CALL_FROM_TB0(do_msac);
246 void op_msachi (void)
248 CALL_FROM_TB0(do_msachi);
254 CALL_FROM_TB0(do_msacu);
258 void op_msachiu (void)
260 CALL_FROM_TB0(do_msachiu);
266 CALL_FROM_TB0(do_mulhi);
270 void op_mulhiu (void)
272 CALL_FROM_TB0(do_mulhiu);
276 void op_mulshi (void)
278 CALL_FROM_TB0(do_mulshi);
282 void op_mulshiu (void)
284 CALL_FROM_TB0(do_mulshiu);
288 #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
290 static always_inline uint64_t get_HILO (void)
292 return ((uint64_t)env->HI[env->current_tc][0] << 32) |
293 ((uint64_t)(uint32_t)env->LO[env->current_tc][0]);
296 static always_inline void set_HILO (uint64_t HILO)
298 env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
299 env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
302 static always_inline void set_HIT0_LO (uint64_t HILO)
304 env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
305 T0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
308 static always_inline void set_HI_LOT0 (uint64_t HILO)
310 T0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF);
311 env->HI[env->current_tc][0] = (int32_t)(HILO >> 32);
316 set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
322 set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
330 tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
331 set_HILO((int64_t)get_HILO() + tmp);
339 tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
340 set_HILO(get_HILO() + tmp);
348 tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
349 set_HILO((int64_t)get_HILO() - tmp);
357 tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
358 set_HILO(get_HILO() - tmp);
362 /* Multiplication variants of the vr54xx. */
365 set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
371 set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
377 set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
381 void op_macchi (void)
383 set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
389 set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
393 void op_macchiu (void)
395 set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
401 set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
405 void op_msachi (void)
407 set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
413 set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
417 void op_msachiu (void)
419 set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
425 set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
429 void op_mulhiu (void)
431 set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
435 void op_mulshi (void)
437 set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
441 void op_mulshiu (void)
443 set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
447 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
449 #if defined(TARGET_MIPS64)
452 CALL_FROM_TB4(muls64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
456 void op_dmultu (void)
458 CALL_FROM_TB4(mulu64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1);
464 void op_mfc0_index (void)
470 void op_mfc0_mvpcontrol (void)
472 T0 = env->mvp->CP0_MVPControl;
476 void op_mfc0_mvpconf0 (void)
478 T0 = env->mvp->CP0_MVPConf0;
482 void op_mfc0_mvpconf1 (void)
484 T0 = env->mvp->CP0_MVPConf1;
488 void op_mfc0_random (void)
490 CALL_FROM_TB0(do_mfc0_random);
494 void op_mfc0_vpecontrol (void)
496 T0 = env->CP0_VPEControl;
500 void op_mfc0_vpeconf0 (void)
502 T0 = env->CP0_VPEConf0;
506 void op_mfc0_vpeconf1 (void)
508 T0 = env->CP0_VPEConf1;
512 void op_mfc0_yqmask (void)
514 T0 = env->CP0_YQMask;
518 void op_mfc0_vpeschedule (void)
520 T0 = env->CP0_VPESchedule;
524 void op_mfc0_vpeschefback (void)
526 T0 = env->CP0_VPEScheFBack;
530 void op_mfc0_vpeopt (void)
532 T0 = env->CP0_VPEOpt;
536 void op_mfc0_entrylo0 (void)
538 T0 = (int32_t)env->CP0_EntryLo0;
542 void op_mfc0_tcstatus (void)
544 T0 = env->CP0_TCStatus[env->current_tc];
548 void op_mftc0_tcstatus(void)
550 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
552 T0 = env->CP0_TCStatus[other_tc];
556 void op_mfc0_tcbind (void)
558 T0 = env->CP0_TCBind[env->current_tc];
562 void op_mftc0_tcbind(void)
564 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
566 T0 = env->CP0_TCBind[other_tc];
570 void op_mfc0_tcrestart (void)
572 T0 = env->PC[env->current_tc];
576 void op_mftc0_tcrestart(void)
578 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
580 T0 = env->PC[other_tc];
584 void op_mfc0_tchalt (void)
586 T0 = env->CP0_TCHalt[env->current_tc];
590 void op_mftc0_tchalt(void)
592 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
594 T0 = env->CP0_TCHalt[other_tc];
598 void op_mfc0_tccontext (void)
600 T0 = env->CP0_TCContext[env->current_tc];
604 void op_mftc0_tccontext(void)
606 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
608 T0 = env->CP0_TCContext[other_tc];
612 void op_mfc0_tcschedule (void)
614 T0 = env->CP0_TCSchedule[env->current_tc];
618 void op_mftc0_tcschedule(void)
620 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
622 T0 = env->CP0_TCSchedule[other_tc];
626 void op_mfc0_tcschefback (void)
628 T0 = env->CP0_TCScheFBack[env->current_tc];
632 void op_mftc0_tcschefback(void)
634 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
636 T0 = env->CP0_TCScheFBack[other_tc];
640 void op_mfc0_entrylo1 (void)
642 T0 = (int32_t)env->CP0_EntryLo1;
646 void op_mfc0_context (void)
648 T0 = (int32_t)env->CP0_Context;
652 void op_mfc0_pagemask (void)
654 T0 = env->CP0_PageMask;
658 void op_mfc0_pagegrain (void)
660 T0 = env->CP0_PageGrain;
664 void op_mfc0_wired (void)
670 void op_mfc0_srsconf0 (void)
672 T0 = env->CP0_SRSConf0;
676 void op_mfc0_srsconf1 (void)
678 T0 = env->CP0_SRSConf1;
682 void op_mfc0_srsconf2 (void)
684 T0 = env->CP0_SRSConf2;
688 void op_mfc0_srsconf3 (void)
690 T0 = env->CP0_SRSConf3;
694 void op_mfc0_srsconf4 (void)
696 T0 = env->CP0_SRSConf4;
700 void op_mfc0_hwrena (void)
702 T0 = env->CP0_HWREna;
706 void op_mfc0_badvaddr (void)
708 T0 = (int32_t)env->CP0_BadVAddr;
712 void op_mfc0_count (void)
714 CALL_FROM_TB0(do_mfc0_count);
718 void op_mfc0_entryhi (void)
720 T0 = (int32_t)env->CP0_EntryHi;
724 void op_mftc0_entryhi(void)
726 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
728 T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff);
732 void op_mfc0_compare (void)
734 T0 = env->CP0_Compare;
738 void op_mfc0_status (void)
740 T0 = env->CP0_Status;
744 void op_mftc0_status(void)
746 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
747 uint32_t tcstatus = env->CP0_TCStatus[other_tc];
749 T0 = env->CP0_Status & ~0xf1000018;
750 T0 |= tcstatus & (0xf << CP0TCSt_TCU0);
751 T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
752 T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
756 void op_mfc0_intctl (void)
758 T0 = env->CP0_IntCtl;
762 void op_mfc0_srsctl (void)
764 T0 = env->CP0_SRSCtl;
768 void op_mfc0_srsmap (void)
770 T0 = env->CP0_SRSMap;
774 void op_mfc0_cause (void)
780 void op_mfc0_epc (void)
782 T0 = (int32_t)env->CP0_EPC;
786 void op_mfc0_prid (void)
792 void op_mfc0_ebase (void)
798 void op_mfc0_config0 (void)
800 T0 = env->CP0_Config0;
804 void op_mfc0_config1 (void)
806 T0 = env->CP0_Config1;
810 void op_mfc0_config2 (void)
812 T0 = env->CP0_Config2;
816 void op_mfc0_config3 (void)
818 T0 = env->CP0_Config3;
822 void op_mfc0_config6 (void)
824 T0 = env->CP0_Config6;
828 void op_mfc0_config7 (void)
830 T0 = env->CP0_Config7;
834 void op_mfc0_lladdr (void)
836 T0 = (int32_t)env->CP0_LLAddr >> 4;
840 void op_mfc0_watchlo (void)
842 T0 = (int32_t)env->CP0_WatchLo[PARAM1];
846 void op_mfc0_watchhi (void)
848 T0 = env->CP0_WatchHi[PARAM1];
852 void op_mfc0_xcontext (void)
854 T0 = (int32_t)env->CP0_XContext;
858 void op_mfc0_framemask (void)
860 T0 = env->CP0_Framemask;
864 void op_mfc0_debug (void)
867 if (env->hflags & MIPS_HFLAG_DM)
872 void op_mftc0_debug(void)
874 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
876 /* XXX: Might be wrong, check with EJTAG spec. */
877 T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
878 (env->CP0_Debug_tcstatus[other_tc] &
879 ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
883 void op_mfc0_depc (void)
885 T0 = (int32_t)env->CP0_DEPC;
889 void op_mfc0_performance0 (void)
891 T0 = env->CP0_Performance0;
895 void op_mfc0_taglo (void)
901 void op_mfc0_datalo (void)
903 T0 = env->CP0_DataLo;
907 void op_mfc0_taghi (void)
913 void op_mfc0_datahi (void)
915 T0 = env->CP0_DataHi;
919 void op_mfc0_errorepc (void)
921 T0 = (int32_t)env->CP0_ErrorEPC;
925 void op_mfc0_desave (void)
927 T0 = env->CP0_DESAVE;
931 void op_mtc0_index (void)
934 unsigned int tmp = env->tlb->nb_tlb;
940 env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1));
944 void op_mtc0_mvpcontrol (void)
949 if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
950 mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
952 if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
953 mask |= (1 << CP0MVPCo_STLB);
954 newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask);
956 // TODO: Enable/disable shared TLB, enable/disable VPEs.
958 env->mvp->CP0_MVPControl = newval;
962 void op_mtc0_vpecontrol (void)
967 mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
968 (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
969 newval = (env->CP0_VPEControl & ~mask) | (T0 & mask);
971 /* Yield scheduler intercept not implemented. */
972 /* Gating storage scheduler intercept not implemented. */
974 // TODO: Enable/disable TCs.
976 env->CP0_VPEControl = newval;
980 void op_mtc0_vpeconf0 (void)
985 if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
986 if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
987 mask |= (0xff << CP0VPEC0_XTC);
988 mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
990 newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask);
992 // TODO: TC exclusive handling due to ERL/EXL.
994 env->CP0_VPEConf0 = newval;
998 void op_mtc0_vpeconf1 (void)
1003 if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1004 mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
1005 (0xff << CP0VPEC1_NCP1);
1006 newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask);
1008 /* UDI not implemented. */
1009 /* CP2 not implemented. */
1011 // TODO: Handle FPU (CP1) binding.
1013 env->CP0_VPEConf1 = newval;
1017 void op_mtc0_yqmask (void)
1019 /* Yield qualifier inputs not implemented. */
1020 env->CP0_YQMask = 0x00000000;
1024 void op_mtc0_vpeschedule (void)
1026 env->CP0_VPESchedule = T0;
1030 void op_mtc0_vpeschefback (void)
1032 env->CP0_VPEScheFBack = T0;
1036 void op_mtc0_vpeopt (void)
1038 env->CP0_VPEOpt = T0 & 0x0000ffff;
1042 void op_mtc0_entrylo0 (void)
1044 /* Large physaddr (PABITS) not implemented */
1045 /* 1k pages not implemented */
1046 env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
1050 void op_mtc0_tcstatus (void)
1052 uint32_t mask = env->CP0_TCStatus_rw_bitmask;
1055 newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask);
1057 // TODO: Sync with CP0_Status.
1059 env->CP0_TCStatus[env->current_tc] = newval;
1063 void op_mttc0_tcstatus (void)
1065 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1067 // TODO: Sync with CP0_Status.
1069 env->CP0_TCStatus[other_tc] = T0;
1073 void op_mtc0_tcbind (void)
1075 uint32_t mask = (1 << CP0TCBd_TBE);
1078 if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1079 mask |= (1 << CP0TCBd_CurVPE);
1080 newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask);
1081 env->CP0_TCBind[env->current_tc] = newval;
1085 void op_mttc0_tcbind (void)
1087 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1088 uint32_t mask = (1 << CP0TCBd_TBE);
1091 if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1092 mask |= (1 << CP0TCBd_CurVPE);
1093 newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask);
1094 env->CP0_TCBind[other_tc] = newval;
1098 void op_mtc0_tcrestart (void)
1100 env->PC[env->current_tc] = T0;
1101 env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS);
1102 env->CP0_LLAddr = 0ULL;
1103 /* MIPS16 not implemented. */
1107 void op_mttc0_tcrestart (void)
1109 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1111 env->PC[other_tc] = T0;
1112 env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS);
1113 env->CP0_LLAddr = 0ULL;
1114 /* MIPS16 not implemented. */
1118 void op_mtc0_tchalt (void)
1120 env->CP0_TCHalt[env->current_tc] = T0 & 0x1;
1122 // TODO: Halt TC / Restart (if allocated+active) TC.
1127 void op_mttc0_tchalt (void)
1129 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1131 // TODO: Halt TC / Restart (if allocated+active) TC.
1133 env->CP0_TCHalt[other_tc] = T0;
1137 void op_mtc0_tccontext (void)
1139 env->CP0_TCContext[env->current_tc] = T0;
1143 void op_mttc0_tccontext (void)
1145 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1147 env->CP0_TCContext[other_tc] = T0;
1151 void op_mtc0_tcschedule (void)
1153 env->CP0_TCSchedule[env->current_tc] = T0;
1157 void op_mttc0_tcschedule (void)
1159 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1161 env->CP0_TCSchedule[other_tc] = T0;
1165 void op_mtc0_tcschefback (void)
1167 env->CP0_TCScheFBack[env->current_tc] = T0;
1171 void op_mttc0_tcschefback (void)
1173 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1175 env->CP0_TCScheFBack[other_tc] = T0;
1179 void op_mtc0_entrylo1 (void)
1181 /* Large physaddr (PABITS) not implemented */
1182 /* 1k pages not implemented */
1183 env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
1187 void op_mtc0_context (void)
1189 env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF);
1193 void op_mtc0_pagemask (void)
1195 /* 1k pages not implemented */
1196 env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
1200 void op_mtc0_pagegrain (void)
1202 /* SmartMIPS not implemented */
1203 /* Large physaddr (PABITS) not implemented */
1204 /* 1k pages not implemented */
1205 env->CP0_PageGrain = 0;
1209 void op_mtc0_wired (void)
1211 env->CP0_Wired = T0 % env->tlb->nb_tlb;
1215 void op_mtc0_srsconf0 (void)
1217 env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask;
1221 void op_mtc0_srsconf1 (void)
1223 env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask;
1227 void op_mtc0_srsconf2 (void)
1229 env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask;
1233 void op_mtc0_srsconf3 (void)
1235 env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask;
1239 void op_mtc0_srsconf4 (void)
1241 env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask;
1245 void op_mtc0_hwrena (void)
1247 env->CP0_HWREna = T0 & 0x0000000F;
1251 void op_mtc0_count (void)
1253 CALL_FROM_TB2(cpu_mips_store_count, env, T0);
1257 void op_mtc0_entryhi (void)
1259 target_ulong old, val;
1261 /* 1k pages not implemented */
1262 val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
1263 #if defined(TARGET_MIPS64)
1264 val &= env->SEGMask;
1266 old = env->CP0_EntryHi;
1267 env->CP0_EntryHi = val;
1268 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
1269 uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff;
1270 env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff);
1272 /* If the ASID changes, flush qemu's TLB. */
1273 if ((old & 0xFF) != (val & 0xFF))
1274 CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
1278 void op_mttc0_entryhi(void)
1280 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1282 env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff);
1283 env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff);
1287 void op_mtc0_compare (void)
1289 CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
1293 void op_mtc0_status (void)
1296 uint32_t mask = env->CP0_Status_rw_bitmask;
1299 old = env->CP0_Status;
1300 env->CP0_Status = (env->CP0_Status & ~mask) | val;
1301 CALL_FROM_TB1(compute_hflags, env);
1302 if (loglevel & CPU_LOG_EXEC)
1303 CALL_FROM_TB2(do_mtc0_status_debug, old, val);
1304 CALL_FROM_TB1(cpu_mips_update_irq, env);
1308 void op_mttc0_status(void)
1310 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1311 uint32_t tcstatus = env->CP0_TCStatus[other_tc];
1313 env->CP0_Status = T0 & ~0xf1000018;
1314 tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0));
1315 tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
1316 tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
1317 env->CP0_TCStatus[other_tc] = tcstatus;
1321 void op_mtc0_intctl (void)
1323 /* vectored interrupts not implemented, no performance counters. */
1324 env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0);
1328 void op_mtc0_srsctl (void)
1330 uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
1331 env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask);
1335 void op_mtc0_srsmap (void)
1337 env->CP0_SRSMap = T0;
1341 void op_mtc0_cause (void)
1343 uint32_t mask = 0x00C00300;
1344 uint32_t old = env->CP0_Cause;
1346 if (env->insn_flags & ISA_MIPS32R2)
1347 mask |= 1 << CP0Ca_DC;
1349 env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
1351 if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
1352 if (env->CP0_Cause & (1 << CP0Ca_DC))
1353 CALL_FROM_TB1(cpu_mips_stop_count, env);
1355 CALL_FROM_TB1(cpu_mips_start_count, env);
1358 /* Handle the software interrupt as an hardware one, as they
1360 if (T0 & CP0Ca_IP_mask) {
1361 CALL_FROM_TB1(cpu_mips_update_irq, env);
1366 void op_mtc0_epc (void)
1372 void op_mtc0_ebase (void)
1374 /* vectored interrupts not implemented */
1375 /* Multi-CPU not implemented */
1376 env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
1380 void op_mtc0_config0 (void)
1382 env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007);
1386 void op_mtc0_config2 (void)
1388 /* tertiary/secondary caches not implemented */
1389 env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
1393 void op_mtc0_watchlo (void)
1395 /* Watch exceptions for instructions, data loads, data stores
1397 env->CP0_WatchLo[PARAM1] = (T0 & ~0x7);
1401 void op_mtc0_watchhi (void)
1403 env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8);
1404 env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7);
1408 void op_mtc0_xcontext (void)
1410 target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
1411 env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
1415 void op_mtc0_framemask (void)
1417 env->CP0_Framemask = T0; /* XXX */
1421 void op_mtc0_debug (void)
1423 env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
1424 if (T0 & (1 << CP0DB_DM))
1425 env->hflags |= MIPS_HFLAG_DM;
1427 env->hflags &= ~MIPS_HFLAG_DM;
1431 void op_mttc0_debug(void)
1433 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1435 /* XXX: Might be wrong, check with EJTAG spec. */
1436 env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
1437 env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
1438 (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
1442 void op_mtc0_depc (void)
1448 void op_mtc0_performance0 (void)
1450 env->CP0_Performance0 = T0 & 0x000007ff;
1454 void op_mtc0_taglo (void)
1456 env->CP0_TagLo = T0 & 0xFFFFFCF6;
1460 void op_mtc0_datalo (void)
1462 env->CP0_DataLo = T0; /* XXX */
1466 void op_mtc0_taghi (void)
1468 env->CP0_TagHi = T0; /* XXX */
1472 void op_mtc0_datahi (void)
1474 env->CP0_DataHi = T0; /* XXX */
1478 void op_mtc0_errorepc (void)
1480 env->CP0_ErrorEPC = T0;
1484 void op_mtc0_desave (void)
1486 env->CP0_DESAVE = T0;
1490 #if defined(TARGET_MIPS64)
1491 void op_dmfc0_yqmask (void)
1493 T0 = env->CP0_YQMask;
1497 void op_dmfc0_vpeschedule (void)
1499 T0 = env->CP0_VPESchedule;
1503 void op_dmfc0_vpeschefback (void)
1505 T0 = env->CP0_VPEScheFBack;
1509 void op_dmfc0_entrylo0 (void)
1511 T0 = env->CP0_EntryLo0;
1515 void op_dmfc0_tcrestart (void)
1517 T0 = env->PC[env->current_tc];
1521 void op_dmfc0_tchalt (void)
1523 T0 = env->CP0_TCHalt[env->current_tc];
1527 void op_dmfc0_tccontext (void)
1529 T0 = env->CP0_TCContext[env->current_tc];
1533 void op_dmfc0_tcschedule (void)
1535 T0 = env->CP0_TCSchedule[env->current_tc];
1539 void op_dmfc0_tcschefback (void)
1541 T0 = env->CP0_TCScheFBack[env->current_tc];
1545 void op_dmfc0_entrylo1 (void)
1547 T0 = env->CP0_EntryLo1;
1551 void op_dmfc0_context (void)
1553 T0 = env->CP0_Context;
1557 void op_dmfc0_badvaddr (void)
1559 T0 = env->CP0_BadVAddr;
1563 void op_dmfc0_entryhi (void)
1565 T0 = env->CP0_EntryHi;
1569 void op_dmfc0_epc (void)
1575 void op_dmfc0_lladdr (void)
1577 T0 = env->CP0_LLAddr >> 4;
1581 void op_dmfc0_watchlo (void)
1583 T0 = env->CP0_WatchLo[PARAM1];
1587 void op_dmfc0_xcontext (void)
1589 T0 = env->CP0_XContext;
1593 void op_dmfc0_depc (void)
1599 void op_dmfc0_errorepc (void)
1601 T0 = env->CP0_ErrorEPC;
1604 #endif /* TARGET_MIPS64 */
1606 /* MIPS MT functions */
1607 void op_mftgpr(void)
1609 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1611 T0 = env->gpr[other_tc][PARAM1];
1617 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1619 T0 = env->LO[other_tc][PARAM1];
1625 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1627 T0 = env->HI[other_tc][PARAM1];
1631 void op_mftacx(void)
1633 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1635 T0 = env->ACX[other_tc][PARAM1];
1639 void op_mftdsp(void)
1641 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1643 T0 = env->DSPControl[other_tc];
1647 void op_mttgpr(void)
1649 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1651 T0 = env->gpr[other_tc][PARAM1];
1657 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1659 T0 = env->LO[other_tc][PARAM1];
1665 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1667 T0 = env->HI[other_tc][PARAM1];
1671 void op_mttacx(void)
1673 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1675 T0 = env->ACX[other_tc][PARAM1];
1679 void op_mttdsp(void)
1681 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1683 T0 = env->DSPControl[other_tc];
1724 // TODO: store to TC register
1731 /* No scheduling policy implemented. */
1733 if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
1734 env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) {
1735 env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1736 env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
1737 CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1740 } else if (T0 == 0) {
1741 if (0 /* TODO: TC underflow */) {
1742 env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1743 CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1745 // TODO: Deallocate TC
1747 } else if (T0 > 0) {
1748 /* Yield qualifier inputs not implemented. */
1749 env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1750 env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
1751 CALL_FROM_TB1(do_raise_exception, EXCP_THREAD);
1753 T0 = env->CP0_YQMask;
1759 # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
1761 # define DEBUG_FPU_STATE() do { } while(0)
1766 CALL_FROM_TB1(do_cfc1, PARAM1);
1773 CALL_FROM_TB1(do_ctc1, PARAM1);
1792 void op_dmfc1 (void)
1799 void op_dmtc1 (void)
1806 void op_mfhc1 (void)
1813 void op_mthc1 (void)
1821 Single precition routines have a "s" suffix, double precision a
1822 "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
1823 paired single lowwer "pl", paired single upper "pu". */
1825 #define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)
1829 CALL_FROM_TB0(do_float_cvtd_s);
1835 CALL_FROM_TB0(do_float_cvtd_w);
1841 CALL_FROM_TB0(do_float_cvtd_l);
1847 CALL_FROM_TB0(do_float_cvtl_d);
1853 CALL_FROM_TB0(do_float_cvtl_s);
1866 CALL_FROM_TB0(do_float_cvtps_pw);
1872 CALL_FROM_TB0(do_float_cvtpw_ps);
1878 CALL_FROM_TB0(do_float_cvts_d);
1884 CALL_FROM_TB0(do_float_cvts_w);
1890 CALL_FROM_TB0(do_float_cvts_l);
1896 CALL_FROM_TB0(do_float_cvts_pl);
1902 CALL_FROM_TB0(do_float_cvts_pu);
1908 CALL_FROM_TB0(do_float_cvtw_s);
1914 CALL_FROM_TB0(do_float_cvtw_d);
1921 DT2 = ((uint64_t)WT0 << 32) | WT1;
1927 DT2 = ((uint64_t)WT0 << 32) | WTH1;
1933 DT2 = ((uint64_t)WTH0 << 32) | WT1;
1939 DT2 = ((uint64_t)WTH0 << 32) | WTH1;
1944 #define FLOAT_ROUNDOP(op, ttype, stype) \
1945 FLOAT_OP(op ## ttype, stype) \
1947 CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \
1948 DEBUG_FPU_STATE(); \
1952 FLOAT_ROUNDOP(round, l, d)
1953 FLOAT_ROUNDOP(round, l, s)
1954 FLOAT_ROUNDOP(round, w, d)
1955 FLOAT_ROUNDOP(round, w, s)
1957 FLOAT_ROUNDOP(trunc, l, d)
1958 FLOAT_ROUNDOP(trunc, l, s)
1959 FLOAT_ROUNDOP(trunc, w, d)
1960 FLOAT_ROUNDOP(trunc, w, s)
1962 FLOAT_ROUNDOP(ceil, l, d)
1963 FLOAT_ROUNDOP(ceil, l, s)
1964 FLOAT_ROUNDOP(ceil, w, d)
1965 FLOAT_ROUNDOP(ceil, w, s)
1967 FLOAT_ROUNDOP(floor, l, d)
1968 FLOAT_ROUNDOP(floor, l, s)
1969 FLOAT_ROUNDOP(floor, w, d)
1970 FLOAT_ROUNDOP(floor, w, s)
1971 #undef FLOAR_ROUNDOP
1975 if (!(env->fpu->fcr31 & PARAM1))
1982 if (!(env->fpu->fcr31 & PARAM1))
1989 if (!(env->fpu->fcr31 & PARAM1)) {
1998 if (env->fpu->fcr31 & PARAM1)
2005 if (env->fpu->fcr31 & PARAM1)
2012 if (env->fpu->fcr31 & PARAM1) {
2066 /* operations calling helpers, for s, d and ps */
2067 #define FLOAT_HOP(name) \
2070 CALL_FROM_TB0(do_float_ ## name ## _d); \
2071 DEBUG_FPU_STATE(); \
2076 CALL_FROM_TB0(do_float_ ## name ## _s); \
2077 DEBUG_FPU_STATE(); \
2080 FLOAT_OP(name, ps) \
2082 CALL_FROM_TB0(do_float_ ## name ## _ps); \
2083 DEBUG_FPU_STATE(); \
2096 /* operations calling helpers, for s and d */
2097 #define FLOAT_HOP(name) \
2100 CALL_FROM_TB0(do_float_ ## name ## _d); \
2101 DEBUG_FPU_STATE(); \
2106 CALL_FROM_TB0(do_float_ ## name ## _s); \
2107 DEBUG_FPU_STATE(); \
2114 /* operations calling helpers, for ps */
2115 #define FLOAT_HOP(name) \
2116 FLOAT_OP(name, ps) \
2118 CALL_FROM_TB0(do_float_ ## name ## _ps); \
2119 DEBUG_FPU_STATE(); \
2126 /* ternary operations */
2127 #define FLOAT_TERNOP(name1, name2) \
2128 FLOAT_OP(name1 ## name2, d) \
2130 FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \
2131 FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \
2132 DEBUG_FPU_STATE(); \
2135 FLOAT_OP(name1 ## name2, s) \
2137 FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
2138 FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2139 DEBUG_FPU_STATE(); \
2142 FLOAT_OP(name1 ## name2, ps) \
2144 FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
2145 FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2146 FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2147 FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2148 DEBUG_FPU_STATE(); \
2151 FLOAT_TERNOP(mul, add)
2152 FLOAT_TERNOP(mul, sub)
2155 /* negated ternary operations */
2156 #define FLOAT_NTERNOP(name1, name2) \
2157 FLOAT_OP(n ## name1 ## name2, d) \
2159 FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \
2160 FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \
2161 FDT2 = float64_chs(FDT2); \
2162 DEBUG_FPU_STATE(); \
2165 FLOAT_OP(n ## name1 ## name2, s) \
2167 FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
2168 FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2169 FST2 = float32_chs(FST2); \
2170 DEBUG_FPU_STATE(); \
2173 FLOAT_OP(n ## name1 ## name2, ps) \
2175 FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \
2176 FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
2177 FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \
2178 FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
2179 FST2 = float32_chs(FST2); \
2180 FSTH2 = float32_chs(FSTH2); \
2181 DEBUG_FPU_STATE(); \
2184 FLOAT_NTERNOP(mul, add)
2185 FLOAT_NTERNOP(mul, sub)
2186 #undef FLOAT_NTERNOP
2188 /* unary operations, modifying fp status */
2189 #define FLOAT_UNOP(name) \
2192 FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
2193 DEBUG_FPU_STATE(); \
2198 FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
2199 DEBUG_FPU_STATE(); \
2205 /* unary operations, not modifying fp status */
2206 #define FLOAT_UNOP(name) \
2209 FDT2 = float64_ ## name(FDT0); \
2210 DEBUG_FPU_STATE(); \
2215 FST2 = float32_ ## name(FST0); \
2216 DEBUG_FPU_STATE(); \
2219 FLOAT_OP(name, ps) \
2221 FST2 = float32_ ## name(FST0); \
2222 FSTH2 = float32_ ## name(FSTH0); \
2223 DEBUG_FPU_STATE(); \
2257 #ifdef TARGET_WORDS_BIGENDIAN
2265 default: /* unpredictable */
2272 #ifdef CONFIG_SOFTFLOAT
2273 #define clear_invalid() do { \
2274 int flags = get_float_exception_flags(&env->fpu->fp_status); \
2275 flags &= ~float_flag_invalid; \
2276 set_float_exception_flags(flags, &env->fpu->fp_status); \
2279 #define clear_invalid() do { } while(0)
2282 extern void dump_fpu_s(CPUState *env);
2284 #define CMP_OP(fmt, op) \
2285 void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void) \
2287 CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \
2288 DEBUG_FPU_STATE(); \
2291 void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void) \
2293 CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \
2294 DEBUG_FPU_STATE(); \
2297 #define CMP_OPS(op) \
2323 T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2327 void op_bc1any2f (void)
2329 T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2333 void op_bc1any4f (void)
2335 T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
2342 T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
2346 void op_bc1any2t (void)
2348 T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
2352 void op_bc1any4t (void)
2354 T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
2359 void op_tlbwi (void)
2361 CALL_FROM_TB0(env->tlb->do_tlbwi);
2365 void op_tlbwr (void)
2367 CALL_FROM_TB0(env->tlb->do_tlbwr);
2373 CALL_FROM_TB0(env->tlb->do_tlbp);
2379 CALL_FROM_TB0(env->tlb->do_tlbr);
2384 #if defined (CONFIG_USER_ONLY)
2385 void op_tls_value (void)
2387 T0 = env->tls_value;
2393 CALL_FROM_TB1(do_pmon, PARAM1);
2399 T0 = env->CP0_Status;
2400 env->CP0_Status = T0 & ~(1 << CP0St_IE);
2401 CALL_FROM_TB1(cpu_mips_update_irq, env);
2407 T0 = env->CP0_Status;
2408 env->CP0_Status = T0 | (1 << CP0St_IE);
2409 CALL_FROM_TB1(cpu_mips_update_irq, env);
2416 CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
2421 void op_debug (void)
2423 CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
2427 void debug_pre_eret (void);
2428 void debug_post_eret (void);
2431 if (loglevel & CPU_LOG_EXEC)
2432 CALL_FROM_TB0(debug_pre_eret);
2433 if (env->CP0_Status & (1 << CP0St_ERL)) {
2434 env->PC[env->current_tc] = env->CP0_ErrorEPC;
2435 env->CP0_Status &= ~(1 << CP0St_ERL);
2437 env->PC[env->current_tc] = env->CP0_EPC;
2438 env->CP0_Status &= ~(1 << CP0St_EXL);
2440 CALL_FROM_TB1(compute_hflags, env);
2441 if (loglevel & CPU_LOG_EXEC)
2442 CALL_FROM_TB0(debug_post_eret);
2443 env->CP0_LLAddr = 1;
2447 void op_deret (void)
2449 if (loglevel & CPU_LOG_EXEC)
2450 CALL_FROM_TB0(debug_pre_eret);
2451 env->PC[env->current_tc] = env->CP0_DEPC;
2452 env->hflags &= MIPS_HFLAG_DM;
2453 CALL_FROM_TB1(compute_hflags, env);
2454 if (loglevel & CPU_LOG_EXEC)
2455 CALL_FROM_TB0(debug_post_eret);
2456 env->CP0_LLAddr = 1;
2460 void op_rdhwr_cpunum(void)
2462 if ((env->hflags & MIPS_HFLAG_CP0) ||
2463 (env->CP0_HWREna & (1 << 0)))
2464 T0 = env->CP0_EBase & 0x3ff;
2466 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2470 void op_rdhwr_synci_step(void)
2472 if ((env->hflags & MIPS_HFLAG_CP0) ||
2473 (env->CP0_HWREna & (1 << 1)))
2474 T0 = env->SYNCI_Step;
2476 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2480 void op_rdhwr_cc(void)
2482 if ((env->hflags & MIPS_HFLAG_CP0) ||
2483 (env->CP0_HWREna & (1 << 2)))
2484 T0 = env->CP0_Count;
2486 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2490 void op_rdhwr_ccres(void)
2492 if ((env->hflags & MIPS_HFLAG_CP0) ||
2493 (env->CP0_HWREna & (1 << 3)))
2496 CALL_FROM_TB1(do_raise_exception, EXCP_RI);
2500 void op_save_state (void)
2502 env->hflags = PARAM1;
2509 CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
2513 /* Bitfield operations. */
2516 unsigned int pos = PARAM1;
2517 unsigned int size = PARAM2;
2519 T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
2525 unsigned int pos = PARAM1;
2526 unsigned int size = PARAM2;
2527 target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
2529 T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
2535 T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
2539 #if defined(TARGET_MIPS64)
2542 unsigned int pos = PARAM1;
2543 unsigned int size = PARAM2;
2545 T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
2551 unsigned int pos = PARAM1;
2552 unsigned int size = PARAM2;
2553 target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
2555 T0 = (T0 & ~mask) | ((T1 << pos) & mask);
2561 T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
2567 T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
2568 T0 = (T1 << 32) | (T1 >> 32);