X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fmips%2Fmips.igen;h=fece487e10d6a3a9844b8b59fd12fdd57125796e;hb=4c54fc26ed171989615301442435fa4dd3af9755;hp=874b685aa735e6fc40f68b4c298f932345f6b4a9;hpb=ee7254b0cc380b91b93231b21fe5b40247180627;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/mips/mips.igen b/sim/mips/mips.igen index 874b685aa7..fece487e10 100644 --- a/sim/mips/mips.igen +++ b/sim/mips/mips.igen @@ -55,7 +55,10 @@ // (or which pre-date or use different encodings than the standard // instructions) are (for the most part) in separate .igen files. :model:::vr4100:mips4100: // vr.igen +:model:::vr4120:mips4120: :model:::vr5000:mips5000: +:model:::vr5400:mips5400: +:model:::vr5500:mips5500: :model:::r3900:mips3900: // tx.igen // MIPS Application Specific Extensions (ASEs) @@ -63,6 +66,7 @@ // Instructions for the ASEs are in separate .igen files. // ASEs add instructions on to a base ISA. :model:::mips16:mips16: // m16.igen (and m16.dc) +:model:::mips3d:mips3d: // mips3d.igen :model:::mdmx:mdmx: // mdmx.igen // Vendor Extensions @@ -564,10 +568,8 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); if ((signed_word) GPR[RS] == (signed_word) GPR[RT]) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } } @@ -587,10 +589,8 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); if ((signed_word) GPR[RS] == (signed_word) GPR[RT]) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } else @@ -613,10 +613,8 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); if ((signed_word) GPR[RS] >= 0) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } } @@ -637,13 +635,11 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); if (RS == 31) Unpredictable (); RA = (CIA + 8); if ((signed_word) GPR[RS] >= 0) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } } @@ -663,7 +659,6 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); if (RS == 31) Unpredictable (); RA = (CIA + 8); @@ -671,7 +666,6 @@ executed */ if ((signed_word) GPR[RS] >= 0) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } else @@ -693,10 +687,8 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); if ((signed_word) GPR[RS] >= 0) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } else @@ -719,10 +711,8 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); if ((signed_word) GPR[RS] > 0) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } } @@ -742,12 +732,10 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); /* NOTE: The branch occurs AFTER the next instruction has been executed */ if ((signed_word) GPR[RS] > 0) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } else @@ -770,12 +758,10 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); /* NOTE: The branch occurs AFTER the next instruction has been executed */ if ((signed_word) GPR[RS] <= 0) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } } @@ -795,10 +781,8 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); if ((signed_word) GPR[RS] <= 0) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } else @@ -821,10 +805,8 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); if ((signed_word) GPR[RS] < 0) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } } @@ -845,7 +827,6 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); if (RS == 31) Unpredictable (); RA = (CIA + 8); @@ -853,7 +834,6 @@ executed */ if ((signed_word) GPR[RS] < 0) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } } @@ -873,13 +853,11 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); if (RS == 31) Unpredictable (); RA = (CIA + 8); if ((signed_word) GPR[RS] < 0) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } else @@ -901,12 +879,10 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); /* NOTE: The branch occurs AFTER the next instruction has been executed */ if ((signed_word) GPR[RS] < 0) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } else @@ -929,10 +905,8 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); if ((signed_word) GPR[RS] != (signed_word) GPR[RT]) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } } @@ -952,10 +926,8 @@ *r3900: { address_word offset = EXTEND16 (OFFSET) << 2; - check_branch_bug (); if ((signed_word) GPR[RS] != (signed_word) GPR[RT]) { - mark_branch_bug (NIA+offset); DELAY_SLOT (NIA + offset); } else @@ -1009,6 +981,7 @@ "clo r, r" *mips32: *mips64: +*vr5500: { unsigned32 temp = GPR[RS]; unsigned32 i, mask; @@ -1033,6 +1006,7 @@ "clz r, r" *mips32: *mips64: +*vr5500: { unsigned32 temp = GPR[RS]; unsigned32 i, mask; @@ -1142,6 +1116,7 @@ 011100,5.RS,5.RT,5.RD,00000,100101:SPECIAL2:64::DCLO "dclo r, r" *mips64: +*vr5500: { unsigned64 temp = GPR[RS]; unsigned32 i; @@ -1165,6 +1140,7 @@ 011100,5.RS,5.RT,5.RD,00000,100100:SPECIAL2:64::DCLZ "dclz r, r" *mips64: +*vr5500: { unsigned64 temp = GPR[RS]; unsigned32 i; @@ -2188,6 +2164,7 @@ "madd r, r" *mips32: *mips64: +*vr5500: { signed64 temp; check_mult_hilo (SD_, HIHISTORY, LOHISTORY); @@ -2207,6 +2184,7 @@ "maddu r, r" *mips32: *mips64: +*vr5500: { unsigned64 temp; check_mult_hilo (SD_, HIHISTORY, LOHISTORY); @@ -2282,7 +2260,10 @@ *vr5000: { if (GPR[RT] != 0) - GPR[RD] = GPR[RS]; + { + GPR[RD] = GPR[RS]; + TRACE_ALU_RESULT (GPR[RD]); + } } @@ -2296,7 +2277,10 @@ *vr5000: { if (GPR[RT] == 0) - GPR[RD] = GPR[RS]; + { + GPR[RD] = GPR[RS]; + TRACE_ALU_RESULT (GPR[RD]); + } } @@ -2305,6 +2289,7 @@ "msub r, r" *mips32: *mips64: +*vr5500: { signed64 temp; check_mult_hilo (SD_, HIHISTORY, LOHISTORY); @@ -2324,6 +2309,7 @@ "msubu r, r" *mips32: *mips64: +*vr5500: { unsigned64 temp; check_mult_hilo (SD_, HIHISTORY, LOHISTORY); @@ -2381,6 +2367,7 @@ "mul r, r, r" *mips32: *mips64: +*vr5500: { signed64 prod; if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT])) @@ -3438,7 +3425,7 @@ 000001,5.RS,01110,16.IMMEDIATE:REGIMM:32::TNEI -"tne r, " +"tnei r, " *mipsII: *mipsIII: *mipsIV: @@ -3516,16 +3503,7 @@ case fmt_double: return "d"; case fmt_word: return "w"; case fmt_long: return "l"; - default: return "?"; - } -} - -:%s::::X:int x -{ - switch (x) - { - case 0: return "f"; - case 1: return "t"; + case fmt_ps: return "ps"; default: return "?"; } } @@ -3614,13 +3592,9 @@ *mipsV: *mips64: { -#if 0 /* XXX FIXME: FP code doesn't yet support paired single ops. */ if ((fmt != fmt_single) && (fmt != fmt_double) && (fmt != fmt_ps || (UserMode && (SR & (status_UX|status_PX)) == 0))) SignalException (ReservedInstruction, insn); -#else - check_fmt (SD_, fmt, insn); -#endif } @@ -3647,6 +3621,77 @@ } +// Helper: +// +// Load a double word FP value using 2 32-bit memory cycles a la MIPS II +// or MIPS32. do_load cannot be used instead because it returns an +// unsigned_word, which is limited to the size of the machine's registers. +// + +:function:::unsigned64:do_load_double:address_word base, address_word offset +*mipsII: +*mips32: +{ + int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian); + address_word vaddr; + address_word paddr; + int uncached; + unsigned64 memval; + unsigned64 v; + + vaddr = loadstore_ea (SD_, base, offset); + if ((vaddr & AccessLength_DOUBLEWORD) != 0) + { + SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map, + AccessLength_DOUBLEWORD + 1, vaddr, read_transfer, + sim_core_unaligned_signal); + } + AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, + isREAL); + LoadMemory (&memval, NULL, uncached, AccessLength_WORD, paddr, vaddr, + isDATA, isREAL); + v = (unsigned64)memval; + LoadMemory (&memval, NULL, uncached, AccessLength_WORD, paddr + 4, vaddr + 4, + isDATA, isREAL); + return (bigendian ? ((v << 32) | memval) : (v | (memval << 32))); +} + + +// Helper: +// +// Store a double word FP value using 2 32-bit memory cycles a la MIPS II +// or MIPS32. do_load cannot be used instead because it returns an +// unsigned_word, which is limited to the size of the machine's registers. +// + +:function:::void:do_store_double:address_word base, address_word offset, unsigned64 v +*mipsII: +*mips32: +{ + int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian); + address_word vaddr; + address_word paddr; + int uncached; + unsigned64 memval; + + vaddr = loadstore_ea (SD_, base, offset); + if ((vaddr & AccessLength_DOUBLEWORD) != 0) + { + SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, + AccessLength_DOUBLEWORD + 1, vaddr, write_transfer, + sim_core_unaligned_signal); + } + AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, + isREAL); + memval = (bigendian ? (v >> 32) : (v & 0xFFFFFFFF)); + StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr, + isREAL); + memval = (bigendian ? (v & 0xFFFFFFFF) : (v >> 32)); + StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr + 4, vaddr + 4, + isREAL); +} + + 010001,10,3.FMT,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt "abs.%s f, f" *mipsI: @@ -3663,7 +3708,7 @@ int fmt = FMT; check_fpu (SD_); check_fmt_p (SD_, fmt, instruction_0); - StoreFPR(FD,fmt,AbsoluteValue(ValueFPR(FS,fmt),fmt)); + StoreFPR (FD, fmt, AbsoluteValue (ValueFPR (FS, fmt), fmt)); } @@ -3684,10 +3729,36 @@ int fmt = FMT; check_fpu (SD_); check_fmt_p (SD_, fmt, instruction_0); - StoreFPR(FD,fmt,Add(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt)); + StoreFPR (FD, fmt, Add (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt)); } +010011,5.RS,5.FT,5.FS,5.FD,011,110:COP1X:64,f::ALNV.PS +"alnv.ps f, f, f, r" +*mipsV: +*mips64: +{ + unsigned64 fs; + unsigned64 ft; + unsigned64 fd; + check_fpu (SD_); + check_u64 (SD_, instruction_0); + fs = ValueFPR (FS, fmt_ps); + if ((GPR[RS] & 0x3) != 0) + Unpredictable (); + if ((GPR[RS] & 0x4) == 0) + fd = fs; + else + { + ft = ValueFPR (FT, fmt_ps); + if (BigEndianCPU) + fd = PackPS (PSLower (fs), PSUpper (ft)); + else + fd = PackPS (PSLower (ft), PSUpper (fs)); + } + StoreFPR (FD, fmt_ps, fd); +} + // BC1F // BC1FL @@ -3701,13 +3772,11 @@ *mipsIII: { check_fpu (SD_); - check_branch_bug (); TRACE_BRANCH_INPUT (PREVCOC1()); if (PREVCOC1() == TF) { address_word dest = NIA + (EXTEND16 (OFFSET) << 2); TRACE_BRANCH_RESULT (dest); - mark_branch_bug (dest); DELAY_SLOT (dest); } else if (ND) @@ -3733,11 +3802,9 @@ *r3900: { check_fpu (SD_); - check_branch_bug (); if (GETFCC(CC) == TF) { address_word dest = NIA + (EXTEND16 (OFFSET) << 2); - mark_branch_bug (dest); DELAY_SLOT (dest); } else if (ND) @@ -3747,45 +3814,6 @@ } - - - - -// C.EQ.S -// C.EQ.D -// ... - -:function:::void:do_c_cond_fmt:int fmt, int ft, int fs, int cc, int cond, instruction_word insn -{ - int less; - int equal; - int unordered; - int condition; - unsigned64 ofs = ValueFPR (fs, fmt); - unsigned64 oft = ValueFPR (ft, fmt); - if (NaN (ofs, fmt) || NaN (oft, fmt)) - { - if (FCSR & FP_ENABLE (IO)) - { - FCSR |= FP_CAUSE (IO); - SignalExceptionFPE (); - } - less = 0; - equal = 0; - unordered = 1; - } - else - { - less = Less (ofs, oft, fmt); - equal = Equal (ofs, oft, fmt); - unordered = 0; - } - condition = (((cond & (1 << 2)) && less) - || ((cond & (1 << 1)) && equal) - || ((cond & (1 << 0)) && unordered)); - SETFCC (cc, condition); -} - 010001,10,3.FMT,5.FT,5.FS,3.0,00,11,4.COND:COP1:32,f::C.cond.fmta "c.%s.%s f, f" *mipsI: @@ -3795,7 +3823,8 @@ int fmt = FMT; check_fpu (SD_); check_fmt_p (SD_, fmt, instruction_0); - do_c_cond_fmt (SD_, fmt, FT, FS, 0, COND, instruction_0); + Compare (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt, COND, 0); + TRACE_ALU_RESULT (ValueFCR (31)); } 010001,10,3.FMT,5.FT,5.FS,3.CC,00,11,4.COND:COP1:32,f::C.cond.fmtb @@ -3812,7 +3841,8 @@ int fmt = FMT; check_fpu (SD_); check_fmt_p (SD_, fmt, instruction_0); - do_c_cond_fmt (SD_, fmt, FT, FS, CC, COND, instruction_0); + Compare (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt, COND, CC); + TRACE_ALU_RESULT (ValueFCR (31)); } @@ -3829,11 +3859,13 @@ int fmt = FMT; check_fpu (SD_); check_fmt (SD_, fmt, instruction_0); - StoreFPR(FD,fmt_long,Convert(FP_RM_TOPINF,ValueFPR(FS,fmt),fmt,fmt_long)); + StoreFPR (FD, fmt_long, Convert (FP_RM_TOPINF, ValueFPR (FS, fmt), fmt, + fmt_long)); } 010001,10,3.FMT,00000,5.FS,5.FD,001110:COP1:32,f::CEIL.W +"ceil.w.%s f, f" *mipsII: *mipsIII: *mipsIV: @@ -3847,84 +3879,97 @@ int fmt = FMT; check_fpu (SD_); check_fmt (SD_, fmt, instruction_0); - StoreFPR(FD,fmt_word,Convert(FP_RM_TOPINF,ValueFPR(FS,fmt),fmt,fmt_word)); + StoreFPR (FD, fmt_word, Convert (FP_RM_TOPINF, ValueFPR (FS, fmt), fmt, + fmt_word)); } -// CFC1 -// CTC1 -010001,00,X,10,5.RT,5.FS,00000000000:COP1Sa:32,f::CxC1 -"c%sc1 r, f" +010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1a +"cfc1 r, f" *mipsI: *mipsII: *mipsIII: { check_fpu (SD_); - if (X) + if (FS == 0) + PENDING_FILL (RT, EXTEND32 (FCR0)); + else if (FS == 31) + PENDING_FILL (RT, EXTEND32 (FCR31)); + /* else NOP */ +} + +010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1b +"cfc1 r, f" +*mipsIV: +*vr4100: +*vr5000: +*r3900: +{ + check_fpu (SD_); + if (FS == 0 || FS == 31) { - if (FS == 0) - PENDING_FILL(FCR0IDX,VL4_8(GPR[RT])); - else if (FS == 31) - PENDING_FILL(FCR31IDX,VL4_8(GPR[RT])); - /* else NOP */ - PENDING_SCHED(FCSR, FCR31 & (1<<23), 1, 23); - } - else - { /* control from */ - if (FS == 0) - PENDING_FILL(RT, EXTEND32 (FCR0)); - else if (FS == 31) - PENDING_FILL(RT, EXTEND32 (FCR31)); - /* else NOP */ + unsigned_word fcr = ValueFCR (FS); + TRACE_ALU_INPUT1 (fcr); + GPR[RT] = fcr; } + /* else NOP */ + TRACE_ALU_RESULT (GPR[RT]); } -010001,00,X,10,5.RT,5.FS,00000000000:COP1Sb:32,f::CxC1 -"c%sc1 r, f" -*mipsIV: + +010001,00010,5.RT,5.FS,00000000000:COP1:32,f::CFC1c +"cfc1 r, f" *mipsV: *mips32: *mips64: +{ + check_fpu (SD_); + if (FS == 0 || FS == 25 || FS == 26 || FS == 28 || FS == 31) + { + unsigned_word fcr = ValueFCR (FS); + TRACE_ALU_INPUT1 (fcr); + GPR[RT] = fcr; + } + /* else NOP */ + TRACE_ALU_RESULT (GPR[RT]); +} + +010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1a +"ctc1 r, f" +*mipsI: +*mipsII: +*mipsIII: +{ + check_fpu (SD_); + if (FS == 31) + PENDING_FILL (FCRCS_REGNUM, VL4_8 (GPR[RT])); + /* else NOP */ +} + +010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1b +"ctc1 r, f" +*mipsIV: *vr4100: *vr5000: *r3900: { check_fpu (SD_); - if (X) - { - /* control to */ - TRACE_ALU_INPUT1 (GPR[RT]); - if (FS == 0) - { - FCR0 = VL4_8(GPR[RT]); - TRACE_ALU_RESULT (FCR0); - } - else if (FS == 31) - { - FCR31 = VL4_8(GPR[RT]); - SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0)); - TRACE_ALU_RESULT (FCR31); - } - else - { - TRACE_ALU_RESULT0 (); - } - /* else NOP */ - } - else - { /* control from */ - if (FS == 0) - { - TRACE_ALU_INPUT1 (FCR0); - GPR[RT] = EXTEND32 (FCR0); - } - else if (FS == 31) - { - TRACE_ALU_INPUT1 (FCR31); - GPR[RT] = EXTEND32 (FCR31); - } - TRACE_ALU_RESULT (GPR[RT]); - /* else NOP */ - } + TRACE_ALU_INPUT1 (GPR[RT]); + if (FS == 31) + StoreFCR (FS, GPR[RT]); + /* else NOP */ +} + +010001,00110,5.RT,5.FS,00000000000:COP1:32,f::CTC1c +"ctc1 r, f" +*mipsV: +*mips32: +*mips64: +{ + check_fpu (SD_); + TRACE_ALU_INPUT1 (GPR[RT]); + if (FS == 25 || FS == 26 || FS == 28 || FS == 31) + StoreFCR (FS, GPR[RT]); + /* else NOP */ } @@ -3946,12 +3991,10 @@ { int fmt = FMT; check_fpu (SD_); - { - if ((fmt == fmt_double) | 0) - SignalException (ReservedInstruction, instruction_0); - else - StoreFPR(FD,fmt_double,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_double)); - } + if ((fmt == fmt_double) | 0) + SignalException (ReservedInstruction, instruction_0); + StoreFPR (FD, fmt_double, Convert (GETRM (), ValueFPR (FS, fmt), fmt, + fmt_double)); } @@ -3967,19 +4010,29 @@ { int fmt = FMT; check_fpu (SD_); - { - if ((fmt == fmt_long) | ((fmt == fmt_long) || (fmt == fmt_word))) - SignalException (ReservedInstruction, instruction_0); - else - StoreFPR(FD,fmt_long,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_long)); - } + if ((fmt == fmt_long) | ((fmt == fmt_long) || (fmt == fmt_word))) + SignalException (ReservedInstruction, instruction_0); + StoreFPR (FD, fmt_long, Convert (GETRM (), ValueFPR (FS, fmt), fmt, + fmt_long)); +} + + +010001,10,000,5.FT,5.FS,5.FD,100110:COP1:64,f::CVT.PS.S +"cvt.ps.s f, f, f" +*mipsV: +*mips64: +{ + check_fpu (SD_); + check_u64 (SD_, instruction_0); + StoreFPR (FD, fmt_ps, PackPS (ValueFPR (FS, fmt_single), + ValueFPR (FT, fmt_single))); } // // FIXME: Does not correctly differentiate between mips* // -010001,10,3.FMT,00000,5.FS,5.FD,100000:COP1:32,f::CVT.S.fmt +010001,10,3.FMT!6,00000,5.FS,5.FD,100000:COP1:32,f::CVT.S.fmt "cvt.s.%s f, f" *mipsI: *mipsII: @@ -3994,16 +4047,36 @@ { int fmt = FMT; check_fpu (SD_); - { - if ((fmt == fmt_single) | 0) - SignalException (ReservedInstruction, instruction_0); - else - StoreFPR(FD,fmt_single,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_single)); - } + if ((fmt == fmt_single) | 0) + SignalException (ReservedInstruction, instruction_0); + StoreFPR (FD, fmt_single, Convert (GETRM (), ValueFPR (FS, fmt), fmt, + fmt_single)); } -010001,10,3.FMT,00000,5.FS,5.FD,100100:COP1:32,f::CVT.W.fmt +010001,10,110,00000,5.FS,5.FD,101000:COP1:64,f::CVT.S.PL +"cvt.s.pl f, f" +*mipsV: +*mips64: +{ + check_fpu (SD_); + check_u64 (SD_, instruction_0); + StoreFPR (FD, fmt_single, PSLower (ValueFPR (FS, fmt_ps))); +} + + +010001,10,110,00000,5.FS,5.FD,100000:COP1:64,f::CVT.S.PU +"cvt.s.pu f, f" +*mipsV: +*mips64: +{ + check_fpu (SD_); + check_u64 (SD_, instruction_0); + StoreFPR (FD, fmt_single, PSUpper (ValueFPR (FS, fmt_ps))); +} + + +010001,10,3.FMT!6,00000,5.FS,5.FD,100100:COP1:32,f::CVT.W.fmt "cvt.w.%s f, f" *mipsI: *mipsII: @@ -4018,12 +4091,10 @@ { int fmt = FMT; check_fpu (SD_); - { - if ((fmt == fmt_word) | ((fmt == fmt_long) || (fmt == fmt_word))) - SignalException (ReservedInstruction, instruction_0); - else - StoreFPR(FD,fmt_word,Convert(GETRM(),ValueFPR(FS,fmt),fmt,fmt_word)); - } + if ((fmt == fmt_word) | ((fmt == fmt_long) || (fmt == fmt_word))) + SignalException (ReservedInstruction, instruction_0); + StoreFPR (FD, fmt_word, Convert (GETRM (), ValueFPR (FS, fmt), fmt, + fmt_word)); } @@ -4043,46 +4114,29 @@ int fmt = FMT; check_fpu (SD_); check_fmt (SD_, fmt, instruction_0); - StoreFPR(FD,fmt,Divide(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt)); + StoreFPR (FD, fmt, Divide (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt)); } -// DMFC1 -// DMTC1 -010001,00,X,01,5.RT,5.FS,00000000000:COP1Sa:64,f::DMxC1 -"dm%sc1 r, f" +010001,00001,5.RT,5.FS,00000000000:COP1:64,f::DMFC1a +"dmfc1 r, f" *mipsIII: { + unsigned64 v; check_fpu (SD_); check_u64 (SD_, instruction_0); - if (X) - { - if (SizeFGR() == 64) - PENDING_FILL((FS + FGR_BASE),GPR[RT]); - else if ((FS & 0x1) == 0) - { - PENDING_FILL(((FS + 1) + FGR_BASE),VH4_8(GPR[RT])); - PENDING_FILL((FS + FGR_BASE),VL4_8(GPR[RT])); - } - } + if (SizeFGR () == 64) + v = FGR[FS]; + else if ((FS & 0x1) == 0) + v = SET64HI (FGR[FS+1]) | FGR[FS]; else - { - if (SizeFGR() == 64) - PENDING_FILL(RT,FGR[FS]); - else if ((FS & 0x1) == 0) - PENDING_FILL(RT,(SET64HI(FGR[FS+1]) | FGR[FS])); - else - { - if (STATE_VERBOSE_P(SD)) - sim_io_eprintf (SD, - "Warning: PC 0x%lx: semantic_DMxC1_COP1Sa 32-bit use of odd FPR number\n", - (long) CIA); - PENDING_FILL(RT,SET64HI(0xDEADC0DE) | 0xBAD0BAD0); - } - } + v = SET64HI (0xDEADC0DE) | 0xBAD0BAD0; + PENDING_FILL (RT, v); + TRACE_ALU_RESULT (v); } -010001,00,X,01,5.RT,5.FS,00000000000:COP1Sb:64,f::DMxC1 -"dm%sc1 r, f" + +010001,00001,5.RT,5.FS,00000000000:COP1:64,f::DMFC1b +"dmfc1 r, f" *mipsIV: *mipsV: *mips64: @@ -4092,28 +4146,52 @@ { check_fpu (SD_); check_u64 (SD_, instruction_0); - if (X) - { - if (SizeFGR() == 64) - StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]); - else if ((FS & 0x1) == 0) - StoreFPR (FS, fmt_uninterpreted_64, SET64HI (FGR[FS+1]) | FGR[FS]); - } + if (SizeFGR () == 64) + GPR[RT] = FGR[FS]; + else if ((FS & 0x1) == 0) + GPR[RT] = SET64HI (FGR[FS+1]) | FGR[FS]; else + GPR[RT] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0; + TRACE_ALU_RESULT (GPR[RT]); +} + + +010001,00101,5.RT,5.FS,00000000000:COP1:64,f::DMTC1a +"dmtc1 r, f" +*mipsIII: +{ + unsigned64 v; + check_fpu (SD_); + check_u64 (SD_, instruction_0); + if (SizeFGR () == 64) + PENDING_FILL ((FS + FGR_BASE), GPR[RT]); + else if ((FS & 0x1) == 0) { - if (SizeFGR() == 64) - GPR[RT] = FGR[FS]; - else if ((FS & 0x1) == 0) - GPR[RT] = SET64HI (FGR[FS+1]) | FGR[FS]; - else - { - if (STATE_VERBOSE_P(SD)) - sim_io_eprintf (SD, - "Warning: PC 0x%lx: DMxC1 32-bit use of odd FPR number\n", - (long) CIA); - GPR[RT] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0; - } + PENDING_FILL (((FS + 1) + FGR_BASE), VH4_8 (GPR[RT])); + PENDING_FILL ((FS + FGR_BASE), VL4_8 (GPR[RT])); } + else + Unpredictable (); + TRACE_FP_RESULT (GPR[RT]); +} + +010001,00101,5.RT,5.FS,00000000000:COP1:64,f::DMTC1b +"dmtc1 r, f" +*mipsIV: +*mipsV: +*mips64: +*vr4100: +*vr5000: +*r3900: +{ + check_fpu (SD_); + check_u64 (SD_, instruction_0); + if (SizeFGR () == 64) + StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]); + else if ((FS & 0x1) == 0) + StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]); + else + Unpredictable (); } @@ -4130,7 +4208,8 @@ int fmt = FMT; check_fpu (SD_); check_fmt (SD_, fmt, instruction_0); - StoreFPR(FD,fmt_long,Convert(FP_RM_TOMINF,ValueFPR(FS,fmt),fmt,fmt_long)); + StoreFPR (FD, fmt_long, Convert (FP_RM_TOMINF, ValueFPR (FS, fmt), fmt, + fmt_long)); } @@ -4149,17 +4228,26 @@ int fmt = FMT; check_fpu (SD_); check_fmt (SD_, fmt, instruction_0); - StoreFPR(FD,fmt_word,Convert(FP_RM_TOMINF,ValueFPR(FS,fmt),fmt,fmt_word)); + StoreFPR (FD, fmt_word, Convert (FP_RM_TOMINF, ValueFPR (FS, fmt), fmt, + fmt_word)); } -110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1 +110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1a "ldc1 f, (r)" *mipsII: +*mips32: +{ + check_fpu (SD_); + COP_LD (1, FT, do_load_double (SD_, GPR[BASE], EXTEND16 (OFFSET))); +} + + +110101,5.BASE,5.FT,16.OFFSET:COP1:32,f::LDC1b +"ldc1 f, (r)" *mipsIII: *mipsIV: *mipsV: -*mips32: *mips64: *vr4100: *vr5000: @@ -4216,64 +4304,37 @@ -// -// FIXME: Not correct for mips* -// -010011,5.FR,5.FT,5.FS,5.FD,100,001:COP1X:32,f::MADD.D -"madd.d f, f, f, f" -*mipsIV: -*mipsV: -*mips64: -*vr5000: -{ - check_fpu (SD_); - { - StoreFPR(FD,fmt_double,Add(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double)); - } -} - - -010011,5.FR,5.FT,5.FS,5.FD,100,000:COP1X:32,f::MADD.S -"madd.s f, f, f, f" +010011,5.FR,5.FT,5.FS,5.FD,100,3.FMT:COP1X:64,f::MADD.fmt +"madd.%s f, f, f, f" *mipsIV: *mipsV: *mips64: *vr5000: { + int fmt = FMT; check_fpu (SD_); - { - StoreFPR(FD,fmt_single,Add(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single)); - } + check_u64 (SD_, instruction_0); + check_fmt_p (SD_, fmt, instruction_0); + StoreFPR (FD, fmt, MultiplyAdd (ValueFPR (FS, fmt), ValueFPR (FT, fmt), + ValueFPR (FR, fmt), fmt)); } -// MFC1 -// MTC1 -010001,00,X,00,5.RT,5.FS,00000000000:COP1Sa:32,f::MxC1 -"m%sc1 r, f" +010001,00000,5.RT,5.FS,00000000000:COP1:32,f::MFC1a +"mfc1 r, f" *mipsI: *mipsII: *mipsIII: { + unsigned64 v; check_fpu (SD_); - if (X) - { /*MTC1*/ - if (SizeFGR() == 64) - { - if (STATE_VERBOSE_P(SD)) - sim_io_eprintf (SD, - "Warning: PC 0x%lx: MTC1 not DMTC1 with 64 bit regs\n", - (long) CIA); - PENDING_FILL ((FS + FGR_BASE), (SET64HI(0xDEADC0DE) | VL4_8(GPR[RT]))); - } - else - PENDING_FILL ((FS + FGR_BASE), VL4_8(GPR[RT])); - } - else /*MFC1*/ - PENDING_FILL (RT, EXTEND32 (FGR[FS])); + v = EXTEND32 (FGR[FS]); + PENDING_FILL (RT, v); + TRACE_ALU_RESULT (v); } -010001,00,X,00,5.RT,5.FS,00000000000:COP1Sb:32,f::MxC1 -"m%sc1 r, f" + +010001,00000,5.RT,5.FS,00000000000:COP1:32,f::MFC1b +"mfc1 r, f" *mipsIV: *mipsV: *mips32: @@ -4281,14 +4342,10 @@ *vr4100: *vr5000: *r3900: -{ - int fs = FS; +{ check_fpu (SD_); - if (X) - /*MTC1*/ - StoreFPR (FS, fmt_uninterpreted_32, VL4_8 (GPR[RT])); - else /*MFC1*/ - GPR[RT] = EXTEND32 (FGR[FS]); + GPR[RT] = EXTEND32 (FGR[FS]); + TRACE_ALU_RESULT (GPR[RT]); } @@ -4308,7 +4365,7 @@ int fmt = FMT; check_fpu (SD_); check_fmt_p (SD_, fmt, instruction_0); - StoreFPR(FD,fmt,ValueFPR(FS,fmt)); + StoreFPR (FD, fmt, ValueFPR (FS, fmt)); } @@ -4340,12 +4397,22 @@ { int fmt = FMT; check_fpu (SD_); - { - if (GETFCC(CC) == TF) - StoreFPR (FD, fmt, ValueFPR (FS, fmt)); - else - StoreFPR (FD, fmt, ValueFPR (FD, fmt)); - } + if (fmt != fmt_ps) + { + if (GETFCC(CC) == TF) + StoreFPR (FD, fmt, ValueFPR (FS, fmt)); + else + StoreFPR (FD, fmt, ValueFPR (FD, fmt)); /* set fmt */ + } + else + { + unsigned64 fd; + fd = PackPS (PSUpper (ValueFPR ((GETFCC (CC+1) == TF) ? FS : FD, + fmt_ps)), + PSLower (ValueFPR ((GETFCC (CC+0) == TF) ? FS : FD, + fmt_ps))); + StoreFPR (FD, fmt_ps, fd); + } } @@ -4388,35 +4455,51 @@ } -// MSUB.fmt -010011,5.FR,5.FT,5.FS,5.FD,101,001:COP1X:32,f::MSUB.D -"msub.d f, f, f, f" +010011,5.FR,5.FT,5.FS,5.FD,101,3.FMT:COP1X:64,f::MSUB.fmt +"msub.%s f, f, f, f" *mipsIV: *mipsV: *mips64: *vr5000: { + int fmt = FMT; check_fpu (SD_); - StoreFPR(FD,fmt_double,Sub(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double)); + check_u64 (SD_, instruction_0); + check_fmt_p (SD_, fmt, instruction_0); + StoreFPR (FD, fmt, MultiplySub (ValueFPR (FS, fmt), ValueFPR (FT, fmt), + ValueFPR (FR, fmt), fmt)); } -// MSUB.fmt -010011,5.FR,5.FT,5.FS,5.FD,101000:COP1X:32,f::MSUB.S -"msub.s f, f, f, f" +010001,00100,5.RT,5.FS,00000000000:COP1:32,f::MTC1a +"mtc1 r, f" +*mipsI: +*mipsII: +*mipsIII: +{ + check_fpu (SD_); + if (SizeFGR () == 64) + PENDING_FILL ((FS + FGR_BASE), (SET64HI (0xDEADC0DE) | VL4_8 (GPR[RT]))); + else + PENDING_FILL ((FS + FGR_BASE), VL4_8 (GPR[RT])); + TRACE_FP_RESULT (GPR[RT]); +} + +010001,00100,5.RT,5.FS,00000000000:COP1:32,f::MTC1b +"mtc1 r, f" *mipsIV: *mipsV: +*mips32: *mips64: +*vr4100: *vr5000: +*r3900: { - check_fpu (SD_); - StoreFPR(FD,fmt_single,Sub(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single)); + check_fpu (SD_); + StoreFPR (FS, fmt_uninterpreted_32, VL4_8 (GPR[RT])); } -// MTC1 see MxC1 - - 010001,10,3.FMT,5.FT,5.FS,5.FD,000010:COP1:32,f::MUL.fmt "mul.%s f, f, f" *mipsI: @@ -4433,7 +4516,7 @@ int fmt = FMT; check_fpu (SD_); check_fmt_p (SD_, fmt, instruction_0); - StoreFPR(FD,fmt,Multiply(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt)); + StoreFPR (FD, fmt, Multiply (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt)); } @@ -4453,59 +4536,63 @@ int fmt = FMT; check_fpu (SD_); check_fmt_p (SD_, fmt, instruction_0); - StoreFPR(FD,fmt,Negate(ValueFPR(FS,fmt),fmt)); + StoreFPR (FD, fmt, Negate (ValueFPR (FS, fmt), fmt)); } -// NMADD.fmt -010011,5.FR,5.FT,5.FS,5.FD,110001:COP1X:32,f::NMADD.D -"nmadd.d f, f, f, f" +010011,5.FR,5.FT,5.FS,5.FD,110,3.FMT:COP1X:64,f::NMADD.fmt +"nmadd.%s f, f, f, f" *mipsIV: *mipsV: *mips64: *vr5000: { + int fmt = FMT; check_fpu (SD_); - StoreFPR(FD,fmt_double,Negate(Add(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double),fmt_double)); + check_u64 (SD_, instruction_0); + check_fmt_p (SD_, fmt, instruction_0); + StoreFPR (FD, fmt, NegMultiplyAdd (ValueFPR (FS, fmt), ValueFPR (FT, fmt), + ValueFPR (FR, fmt), fmt)); } -// NMADD.fmt -010011,5.FR,5.FT,5.FS,5.FD,110000:COP1X:32,f::NMADD.S -"nmadd.s f, f, f, f" +010011,5.FR,5.FT,5.FS,5.FD,111,3.FMT:COP1X:64,f::NMSUB.fmt +"nmsub.%s f, f, f, f" *mipsIV: *mipsV: *mips64: *vr5000: { + int fmt = FMT; check_fpu (SD_); - StoreFPR(FD,fmt_single,Negate(Add(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single),fmt_single)); + check_u64 (SD_, instruction_0); + check_fmt_p (SD_, fmt, instruction_0); + StoreFPR (FD, fmt, NegMultiplySub (ValueFPR (FS, fmt), ValueFPR (FT, fmt), + ValueFPR (FR, fmt), fmt)); } -// NMSUB.fmt -010011,5.FR,5.FT,5.FS,5.FD,111001:COP1X:32,f::NMSUB.D -"nmsub.d f, f, f, f" -*mipsIV: +010001,10,110,5.FT,5.FS,5.FD,101100:COP1:64,f::PLL.PS +"pll.ps f, f, f" *mipsV: *mips64: -*vr5000: { check_fpu (SD_); - StoreFPR(FD,fmt_double,Negate(Sub(Multiply(ValueFPR(FS,fmt_double),ValueFPR(FT,fmt_double),fmt_double),ValueFPR(FR,fmt_double),fmt_double),fmt_double)); + check_u64 (SD_, instruction_0); + StoreFPR (FD, fmt_ps, PackPS (PSLower (ValueFPR (FS, fmt_ps)), + PSLower (ValueFPR (FT, fmt_ps)))); } -// NMSUB.fmt -010011,5.FR,5.FT,5.FS,5.FD,111000:COP1X:32,f::NMSUB.S -"nmsub.s f, f, f, f" -*mipsIV: +010001,10,110,5.FT,5.FS,5.FD,101101:COP1:64,f::PLU.PS +"plu.ps f, f, f" *mipsV: *mips64: -*vr5000: { check_fpu (SD_); - StoreFPR(FD,fmt_single,Negate(Sub(Multiply(ValueFPR(FS,fmt_single),ValueFPR(FT,fmt_single),fmt_single),ValueFPR(FR,fmt_single),fmt_single),fmt_single)); + check_u64 (SD_, instruction_0); + StoreFPR (FD, fmt_ps, PackPS (PSLower (ValueFPR (FS, fmt_ps)), + PSUpper (ValueFPR (FT, fmt_ps)))); } @@ -4527,6 +4614,31 @@ } } + +010001,10,110,5.FT,5.FS,5.FD,101110:COP1:64,f::PUL.PS +"pul.ps f, f, f" +*mipsV: +*mips64: +{ + check_fpu (SD_); + check_u64 (SD_, instruction_0); + StoreFPR (FD, fmt_ps, PackPS (PSUpper (ValueFPR (FS, fmt_ps)), + PSLower (ValueFPR (FT, fmt_ps)))); +} + + +010001,10,110,5.FT,5.FS,5.FD,101111:COP1:64,f::PUU.PS +"puu.ps f, f, f" +*mipsV: +*mips64: +{ + check_fpu (SD_); + check_u64 (SD_, instruction_0); + StoreFPR (FD, fmt_ps, PackPS (PSUpper (ValueFPR (FS, fmt_ps)), + PSUpper (ValueFPR (FT, fmt_ps)))); +} + + 010001,10,3.FMT,00000,5.FS,5.FD,010101:COP1:32,f::RECIP.fmt "recip.%s f, f" *mipsIV: @@ -4537,7 +4649,7 @@ int fmt = FMT; check_fpu (SD_); check_fmt (SD_, fmt, instruction_0); - StoreFPR(FD,fmt,Recip(ValueFPR(FS,fmt),fmt)); + StoreFPR (FD, fmt, Recip (ValueFPR (FS, fmt), fmt)); } @@ -4554,7 +4666,8 @@ int fmt = FMT; check_fpu (SD_); check_fmt (SD_, fmt, instruction_0); - StoreFPR(FD,fmt_long,Convert(FP_RM_NEAREST,ValueFPR(FS,fmt),fmt,fmt_long)); + StoreFPR (FD, fmt_long, Convert (FP_RM_NEAREST, ValueFPR (FS, fmt), fmt, + fmt_long)); } @@ -4573,31 +4686,40 @@ int fmt = FMT; check_fpu (SD_); check_fmt (SD_, fmt, instruction_0); - StoreFPR(FD,fmt_word,Convert(FP_RM_NEAREST,ValueFPR(FS,fmt),fmt,fmt_word)); + StoreFPR (FD, fmt_word, Convert (FP_RM_NEAREST, ValueFPR (FS, fmt), fmt, + fmt_word)); } 010001,10,3.FMT,00000,5.FS,5.FD,010110:COP1:32,f::RSQRT.fmt +"rsqrt.%s f, f" *mipsIV: *mipsV: *mips64: -"rsqrt.%s f, f" *vr5000: { int fmt = FMT; check_fpu (SD_); check_fmt (SD_, fmt, instruction_0); - StoreFPR(FD,fmt,Recip(SquareRoot(ValueFPR(FS,fmt),fmt),fmt)); + StoreFPR (FD, fmt, RSquareRoot (ValueFPR (FS, fmt), fmt)); } -111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1 +111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1a "sdc1 f, (r)" *mipsII: +*mips32: +{ + check_fpu (SD_); + do_store_double (SD_, GPR[BASE], EXTEND16 (OFFSET), COP_SD (1, FT)); +} + + +111101,5.BASE,5.FT,16.OFFSET:COP1:32,f::SDC1b +"sdc1 f, (r)" *mipsIII: *mipsIV: *mipsV: -*mips32: *mips64: *vr4100: *vr5000: @@ -4636,7 +4758,7 @@ int fmt = FMT; check_fpu (SD_); check_fmt (SD_, fmt, instruction_0); - StoreFPR(FD,fmt,(SquareRoot(ValueFPR(FS,fmt),fmt))); + StoreFPR (FD, fmt, (SquareRoot (ValueFPR (FS, fmt), fmt))); } @@ -4656,7 +4778,7 @@ int fmt = FMT; check_fpu (SD_); check_fmt_p (SD_, fmt, instruction_0); - StoreFPR(FD,fmt,Sub(ValueFPR(FS,fmt),ValueFPR(FT,fmt),fmt)); + StoreFPR (FD, fmt, Sub (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt)); } @@ -4758,7 +4880,8 @@ int fmt = FMT; check_fpu (SD_); check_fmt (SD_, fmt, instruction_0); - StoreFPR(FD,fmt_long,Convert(FP_RM_TOZERO,ValueFPR(FS,fmt),fmt,fmt_long)); + StoreFPR (FD, fmt_long, Convert (FP_RM_TOZERO, ValueFPR (FS, fmt), fmt, + fmt_long)); } @@ -4777,7 +4900,8 @@ int fmt = FMT; check_fpu (SD_); check_fmt (SD_, fmt, instruction_0); - StoreFPR(FD,fmt_word,Convert(FP_RM_TOZERO,ValueFPR(FS,fmt),fmt,fmt_word)); + StoreFPR (FD, fmt_word, Convert (FP_RM_TOZERO, ValueFPR (FS, fmt), fmt, + fmt_word)); } @@ -5063,6 +5187,7 @@ :include:::m16.igen :include:::mdmx.igen +:include:::mips3d.igen :include:::sb1.igen :include:::tx.igen :include:::vr.igen