diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/alpha/faults.cc | 10 | ||||
-rw-r--r-- | arch/alpha/faults.hh | 20 | ||||
-rw-r--r-- | arch/alpha/isa/decoder.isa | 2 | ||||
-rw-r--r-- | arch/mips/faults.cc | 10 | ||||
-rw-r--r-- | arch/mips/faults.hh | 20 | ||||
-rw-r--r-- | arch/mips/isa/base.isa | 2 | ||||
-rw-r--r-- | arch/mips/isa/bitfields.isa | 5 | ||||
-rw-r--r-- | arch/mips/isa/decoder.isa | 860 | ||||
-rw-r--r-- | arch/mips/isa/formats/branch.isa | 6 | ||||
-rw-r--r-- | arch/mips/isa/formats/fp.isa | 60 | ||||
-rw-r--r-- | arch/mips/isa/operands.isa | 31 | ||||
-rw-r--r-- | arch/mips/isa_traits.cc | 108 | ||||
-rw-r--r-- | arch/mips/isa_traits.hh | 10 | ||||
-rw-r--r-- | arch/mips/regfile/float_regfile.hh | 159 | ||||
-rw-r--r-- | arch/mips/regfile/int_regfile.hh (renamed from arch/mips/int_regfile.hh) | 31 | ||||
-rw-r--r-- | arch/mips/regfile/misc_regfile.hh (renamed from arch/mips/misc_regfile.hh) | 0 | ||||
-rw-r--r-- | arch/mips/regfile/regfile.hh (renamed from arch/mips/regfile.hh) | 58 | ||||
-rw-r--r-- | arch/mips/types.hh | 6 | ||||
-rw-r--r-- | arch/sparc/faults.cc | 14 | ||||
-rw-r--r-- | arch/sparc/faults.hh | 26 | ||||
-rw-r--r-- | arch/sparc/isa/base.isa | 6 | ||||
-rw-r--r-- | arch/sparc/isa/decoder.isa | 40 |
22 files changed, 987 insertions, 497 deletions
diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index c8cb9124e..0083aa9f3 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -105,10 +105,6 @@ FaultName IntegerOverflowFault::_name = "intover"; FaultVect IntegerOverflowFault::_vect = 0x0501; FaultStat IntegerOverflowFault::_count; -FaultName UnimpFault::_name = "Unimplemented Simulator feature"; -FaultVect UnimpFault::_vect = 0x0001; -FaultStat UnimpFault::_count; - #if FULL_SYSTEM void AlphaFault::invoke(ExecContext * xc) @@ -174,12 +170,6 @@ void ItbFault::invoke(ExecContext * xc) AlphaFault::invoke(xc); } -void UnimpFault::invoke(ExecContext * xc) -{ - FaultBase::invoke(xc); - panic("Unimpfault: %s\n", panicStr.c_str()); -} - #endif } // namespace AlphaISA diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index 5024c124b..e8ccc6b79 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -347,26 +347,6 @@ class IntegerOverflowFault : public AlphaFault FaultStat & countStat() {return _count;} }; -class UnimpFault : public AlphaFault -{ - private: - std::string panicStr; - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - UnimpFault(std::string _str) - : panicStr(_str) - { } - - FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ExecContext * xc); -#endif -}; - } // AlphaISA namespace #endif // __FAULTS_HH__ diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index 3d38e91f9..1adcfb948 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -810,7 +810,7 @@ decode OPCODE default Unknown::unknown() { AlphaPseudo::addsymbol(xc->xcBase(), R16, R17); }}, IsNonSpeculative); 0x54: m5panic({{ - panic("M5 panic instruction called."); + panic("M5 panic instruction called at pc=%#x.", xc->readPC()); }}, IsNonSpeculative); } diff --git a/arch/mips/faults.cc b/arch/mips/faults.cc index a31856f07..1b31dfa69 100644 --- a/arch/mips/faults.cc +++ b/arch/mips/faults.cc @@ -98,10 +98,6 @@ FaultName IntegerOverflowFault::_name = "intover"; FaultVect IntegerOverflowFault::_vect = 0x0501; FaultStat IntegerOverflowFault::_count; -FaultName UnimpFault::_name = "Unimplemented Simulator feature"; -FaultVect UnimpFault::_vect = 0x0001; -FaultStat UnimpFault::_count; - #if FULL_SYSTEM void MipsFault::invoke(ExecContext * xc) @@ -129,12 +125,6 @@ void ArithmeticFault::invoke(ExecContext * xc) panic("Arithmetic traps are unimplemented!"); } -void UnimpFault::invoke(ExecContext * xc) -{ - FaultBase::invoke(xc); - panic("Unimpfault: %s\n", panicStr.c_str()); -} - #endif } // namespace MipsISA diff --git a/arch/mips/faults.hh b/arch/mips/faults.hh index b0d228090..0bdabe29e 100644 --- a/arch/mips/faults.hh +++ b/arch/mips/faults.hh @@ -264,26 +264,6 @@ class IntegerOverflowFault : public MipsFault FaultStat & countStat() {return _count;} }; -class UnimpFault : public MipsFault -{ - private: - std::string panicStr; - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - UnimpFault(std::string _str) - : panicStr(_str) - { } - - FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ExecContext * xc); -#endif -}; - } // MipsISA namespace #endif // __FAULTS_HH__ diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa index 9ed9651d2..b2a31c018 100644 --- a/arch/mips/isa/base.isa +++ b/arch/mips/isa/base.isa @@ -8,8 +8,6 @@ //Outputs to decoder.hh output header {{ -#define R31 31 - using namespace MipsISA; diff --git a/arch/mips/isa/bitfields.isa b/arch/mips/isa/bitfields.isa index eb917595c..e1124a591 100644 --- a/arch/mips/isa/bitfields.isa +++ b/arch/mips/isa/bitfields.isa @@ -39,7 +39,6 @@ def bitfield FT <20:16>; def bitfield FS <15:11>; def bitfield FD <10:6>; -def bitfield CC <20:18>; def bitfield ND <17:17>; def bitfield TF <16:16>; def bitfield MOVCI <16:16>; @@ -48,6 +47,10 @@ def bitfield SRL <21:21>; def bitfield SRLV < 6: 6>; def bitfield SA <10: 6>; +// Floating Point Condition Codes +def bitfield CC <10:8>; +def bitfield BRANCH_CC <20:18>; + // CP0 Register Select def bitfield SEL < 2: 0>; diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 53bbb94a4..1454aba39 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -1,4 +1,4 @@ -// -*- mode:c++ -*- + // -*- mode:c++ -*- //////////////////////////////////////////////////////////////////// // @@ -20,8 +20,8 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode FUNCTION_LO { 0x1: decode MOVCI { format BasicOp { - 0: movf({{ if (xc->readMiscReg(FPCR) != CC) Rd = Rs}}); - 1: movt({{ if (xc->readMiscReg(FPCR) == CC) Rd = Rs}}); + 0: movf({{ if (getFPConditionCode(FCSR, CC) == 0) Rd = Rs}}); + 1: movt({{ if (getFPConditionCode(FCSR, CC) == 1) Rd = Rs}}); } } @@ -127,10 +127,10 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode FUNCTION_LO { format BasicOp { - 0x0: mfhi({{ Rd = xc->readMiscReg(Hi); }}); - 0x1: mthi({{ xc->setMiscReg(Hi,Rs); }}); - 0x2: mflo({{ Rd = xc->readMiscReg(Lo); }}); - 0x3: mtlo({{ xc->setMiscReg(Lo,Rs); }}); + 0x0: mfhi({{ Rd = HI; }}); + 0x1: mthi({{ HI = Rs; }}); + 0x2: mflo({{ Rd = LO; }}); + 0x3: mtlo({{ LO = Rs; }}); } } @@ -138,24 +138,24 @@ decode OPCODE_HI default Unknown::unknown() { format IntOp { 0x0: mult({{ int64_t temp1 = Rs.sd * Rt.sd; - xc->setMiscReg(Hi,temp1<63:32>); - xc->setMiscReg(Lo,temp1<31:0>); + HI = temp1<63:32>; + LO = temp1<31:0>; }}); 0x1: multu({{ uint64_t temp1 = Rs.ud * Rt.ud; - xc->setMiscReg(Hi,temp1<63:32>); - xc->setMiscReg(Lo,temp1<31:0>); + HI = temp1<63:32>; + LO = temp1<31:0>; }}); 0x2: div({{ - xc->setMiscReg(Hi,Rs.sd % Rt.sd); - xc->setMiscReg(Lo,Rs.sd / Rt.sd); + HI = Rs.sd % Rt.sd; + LO = Rs.sd / Rt.sd; }}); 0x3: divu({{ - xc->setMiscReg(Hi,Rs.ud % Rt.ud); - xc->setMiscReg(Lo,Rs.ud / Rt.ud); + HI = Rs.ud % Rt.ud; + LO = Rs.ud / Rt.ud; }}); } } @@ -163,9 +163,9 @@ decode OPCODE_HI default Unknown::unknown() { 0x4: decode HINT { 0x0: decode FUNCTION_LO { format IntOp { - 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;/*Trap on Overflow*/}}); + 0x0: add({{ Rd.sw = Rs.sw + Rt.sw; /*Trap on Overflow*/}}); 0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}}); - 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}}); + 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}}); 0x3: subu({{ Rd.sw = Rs.sw - Rt.sw;}}); 0x4: and({{ Rd = Rs & Rt;}}); 0x5: or({{ Rd = Rs | Rt;}}); @@ -204,7 +204,6 @@ decode OPCODE_HI default Unknown::unknown() { } format BranchLikely { - //MIPS obsolete instructions 0x2: bltzl({{ cond = (Rs.sw < 0); }}); 0x3: bgezl({{ cond = (Rs.sw >= 0); }}); } @@ -228,7 +227,6 @@ decode OPCODE_HI default Unknown::unknown() { } format BranchLikely { - //Will be removed in future MIPS releases 0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsCall, IsReturn); 0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsCall, IsReturn); } @@ -301,6 +299,7 @@ decode OPCODE_HI default Unknown::unknown() { //sel field. In those instances, the sel field must be zero. //MT Code Needed Here + }}); 0xC: mttr({{ @@ -399,78 +398,71 @@ decode OPCODE_HI default Unknown::unknown() { 0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}}); 0x4: mtc1 ({{ Fs.uw = Rt.uw; }}); 0x7: mthc1({{ - uint64_t fs_hi = Rt.ud << 32; + uint64_t fs_hi = Rt.uw; uint64_t fs_lo = Fs.ud & 0x0000FFFF; - Fs.ud = fs_hi & fs_lo; + Fs.ud = fs_hi << 32 | fs_lo; }}); } format System { 0x2: cfc1({{ - uint32_t fcsr_reg = xc->readMiscReg(FCSR); - switch (FS) { case 0: - Rt = xc->readMiscReg(FIR); + Rt = FIR; break; case 25: - Rt = 0 | (fcsr_reg & 0xFE000000) >> 24 | (fcsr_reg & 0x00800000) >> 23; + Rt = 0 | (FCSR & 0xFE000000) >> 24 | (FCSR & 0x00800000) >> 23; break; case 26: - Rt = 0 | (fcsr_reg & 0x0003F07C); + Rt = 0 | (FCSR & 0x0003F07C); break; case 28: - Rt = 0 | (fcsr_reg); + Rt = 0 | (FCSR & 0x00000F80) | (FCSR & 0x01000000) >> 21 | (FCSR & 0x00000003); break; case 31: - Rt = fcsr_reg; + Rt = FCSR; break; default: panic("FP Control Value (%d) Not Available. Ignoring Access to" - "Floating Control Status Register",fcsr_reg); + "Floating Control Status Register",FS); } }}); 0x6: ctc1({{ - uint32_t fcsr_reg = xc->readMiscReg(FCSR); - uint32_t temp; - switch (FS) { case 25: - temp = 0 | (Rt.uw<7:1> << 25) // move 31...25 - | (fcsr_reg & 0x01000000) // bit 24 - | (fcsr_reg & 0x004FFFFF);// bit 22...0 + FCSR = 0 | (Rt.uw<7:1> << 25) // move 31...25 + | (FCSR & 0x01000000) // bit 24 + | (FCSR & 0x004FFFFF);// bit 22...0 break; case 26: - temp = 0 | (fcsr_reg & 0xFFFC0000) // move 31...18 + FCSR = 0 | (FCSR & 0xFFFC0000) // move 31...18 | Rt.uw<17:12> << 12 // bit 17...12 - | (fcsr_reg & 0x00000F80) << 7// bit 11...7 + | (FCSR & 0x00000F80) << 7// bit 11...7 | Rt.uw<6:2> << 2 // bit 6...2 - | (fcsr_reg & 0x00000002); // bit 1...0 + | (FCSR & 0x00000002); // bit 1...0 break; case 28: - temp = 0 | (fcsr_reg & 0xFE000000) // move 31...25 + FCSR = 0 | (FCSR & 0xFE000000) // move 31...25 | Rt.uw<2:2> << 24 // bit 24 - | (fcsr_reg & 0x00FFF000) << 23// bit 23...12 + | (FCSR & 0x00FFF000) << 23// bit 23...12 | Rt.uw<11:7> << 7 // bit 24 - | (fcsr_reg & 0x000007E) + | (FCSR & 0x000007E) | Rt.uw<1:0>;// bit 22...0 break; case 31: - temp = Rt.uw; + FCSR = Rt.uw; break; default: panic("FP Control Value (%d) Not Available. Ignoring Access to" - "Floating Control Status Register",fcsr_reg); + "Floating Control Status Register", FS); } - - xc->setMiscReg(FCSR,temp); }}); } } @@ -478,15 +470,15 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: decode ND { 0x0: decode TF { format Branch { - 0x0: bc1f({{ cond = (xc->readMiscReg(FPCR) == 0); }}); - 0x1: bc1t({{ cond = (xc->readMiscReg(FPCR) == 1); }}); + 0x0: bc1f({{ cond = (getFPConditionCode(FCSR,CC) == 0); }}); + 0x1: bc1t({{ cond = (getFPConditionCode(FCSR,CC) == 1); }}); } } 0x1: decode TF { format BranchLikely { - 0x0: bc1fl({{ cond = (xc->readMiscReg(FPCR) == 0); }}); - 0x1: bc1tl({{ cond = (xc->readMiscReg(FPCR) == 1); }}); + 0x0: bc1fl({{ cond = (getFPConditionCode(FCSR,CC) == 0); }}); + 0x1: bc1tl({{ cond = (getFPConditionCode(FCSR,CC) == 1); }}); } } } @@ -500,51 +492,51 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { format FloatOp { - 0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}}); - 0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}}); - 0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}}); - 0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}}); - 0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}}); - 0x5: abss({{ Fd.sf = fabs(Fs.sf);}}); - 0x6: movs({{ Fd.sf = Fs.sf;}}); - 0x7: negs({{ Fd.sf = -1 * Fs.sf;}}); + 0x0: add_s({{ Fd.sf = Fs.sf + Ft.sf;}}); + 0x1: sub_s({{ Fd.sf = Fs.sf - Ft.sf;}}); + 0x2: mul_s({{ Fd.sf = Fs.sf * Ft.sf;}}); + 0x3: div_s({{ Fd.sf = Fs.sf / Ft.sf;}}); + 0x4: sqrt_s({{ Fd.sf = sqrt(Fs.sf);}}); + 0x5: abs_s({{ Fd.sf = fabs(Fs.sf);}}); + 0x6: mov_s({{ Fd.sf = Fs.sf;}}); + 0x7: neg_s({{ Fd.sf = -1 * Fs.sf;}}); } } 0x1: decode FUNCTION_LO { format Float64Op { 0x0: round_l_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_NEAREST); + Fd.ud = fpConvert(roundFP(Fs.sf,0), SINGLE_TO_LONG); }}); 0x1: trunc_l_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_ZERO); + Fd.ud = fpConvert(truncFP(Fs.sf), SINGLE_TO_LONG); }}); 0x2: ceil_l_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_UP); + Fd.ud = fpConvert(ceil(Fs.sf), SINGLE_TO_LONG); }}); 0x3: floor_l_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_DOWN); + Fd.ud = fpConvert(floor(Fs.sf), SINGLE_TO_LONG); }}); } format FloatOp { 0x4: round_w_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_NEAREST); + Fd.uw = fpConvert(roundFP(Fs.sf,0), SINGLE_TO_WORD); }}); 0x5: trunc_w_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_ZERO); + Fd.uw = fpConvert(truncFP(Fs.sf), SINGLE_TO_WORD); }}); 0x6: ceil_w_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_UP); + Fd.uw = fpConvert(ceil(Fs.sf), SINGLE_TO_WORD); }}); 0x7: floor_w_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_DOWN); + Fd.uw = fpConvert(floor(Fs.sf), SINGLE_TO_WORD); }}); } } @@ -552,41 +544,34 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { format FloatOp { - 0x0: movfs({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }}); - 0x1: movts({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs;}}); + 0x0: movf_s({{if (getFPConditionCode(FCSR,CC) == 0) Fd = Fs;}}); + 0x1: movt_s({{if (getFPConditionCode(FCSR,CC) == 1) Fd = Fs;}}); } } - format BasicOp { - 0x2: movzs({{ if (Rt == 0) Fd = Fs; }}); - 0x3: movns({{ if (Rt != 0) Fd = Fs; }}); - } - - format Float64Op { - 0x5: recips({{ Fd = 1 / Fs; }}); - 0x6: rsqrts({{ Fd = 1 / sqrt((double)Fs.ud);}}); + format FloatOp { + 0x2: movz_s({{ if (Rt == 0) Fd = Fs; }}); + 0x3: movn_s({{ if (Rt != 0) Fd = Fs; }}); + 0x5: recip_s({{ Fd = 1 / Fs; }}); + 0x6: rsqrt_s({{ Fd = 1 / sqrt(Fs);}}); } } 0x4: decode FUNCTION_LO { - format FloatOp { + format FloatConvertOp { 0x1: cvt_d_s({{ - int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.ud = convert_and_round(Fs.sf, SINGLE_TO_DOUBLE, rnd_mode); + Fd.ud = fpConvert(Fs.sf, SINGLE_TO_DOUBLE); }}); 0x4: cvt_w_s({{ - int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.uw = convert_and_round(Fs.uw, SINGLE_TO_WORD, rnd_mode); + Fd.uw = fpConvert(Fs.sf, SINGLE_TO_WORD); }}); } - //only legal for 64 bit - format Float64Op { + format FloatConvertOp { 0x5: cvt_l_s({{ - int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.ud = convert_and_round(Fs.uw, SINGLE_TO_LONG, rnd_mode); + Fd.ud = fpConvert(Fs.sf, SINGLE_TO_LONG); }}); 0x6: cvt_ps_st({{ @@ -594,57 +579,167 @@ decode OPCODE_HI default Unknown::unknown() { }}); } } + + 0x6: decode FUNCTION_LO { + format FloatCompareOp { + 0x0: c_f_s({{ cond = 0; }}); + + 0x1: c_un_s({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond = 1; + else + cond = 0; + }}); + + 0x2: c_eq_s({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond = 0; + else + cond = (Fs.sf == Ft.sf); + }}); + + 0x3: c_ueq_s({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond = 1; + else + cond = (Fs.sf == Ft.sf); + }}); + + 0x4: c_olt_s({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond = 0; + else + cond = (Fs.sf < Ft.sf); + }}); + + 0x5: c_ult_s({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond = 1; + else + cond = (Fs.sf < Ft.sf); + }}); + + 0x6: c_ole_s({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond = 0; + else + cond = (Fs.sf <= Ft.sf); + }}); + + 0x7: c_ule_s({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond = 1; + else + cond = (Fs.sf <= Ft.sf); + }}); + } + } + + 0x7: decode FUNCTION_LO { + format FloatCompareWithXcptOp { + 0x0: c_sf_s({{ cond = 0; }}); + + 0x1: c_ngle_s({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond = 1; + else + cond = 0; + }}); + + 0x2: c_seq_s({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond = 0; + else + cond = (Fs.sf == Ft.sf); + }}); + + 0x3: c_ngl_s({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond = 1; + else + cond = (Fs.sf == Ft.sf); + }}); + + 0x4: c_lt_s({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond = 0; + else + cond = (Fs.sf < Ft.sf); + }}); + + 0x5: c_nge_s({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond = 1; + else + cond = (Fs.sf < Ft.sf); + }}); + + 0x6: c_le_s({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond = 0; + else + cond = (Fs.sf <= Ft.sf); + }}); + + 0x7: c_ngt_s({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond = 1; + else + cond = (Fs.sf <= Ft.sf); + }}); + } + } } //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D 0x1: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { format FloatOp { - 0x0: addd({{ Fd.df = Fs.df + Ft.df;}}); - 0x1: subd({{ Fd.df = Fs.df - Ft.df;}}); - 0x2: muld({{ Fd.df = Fs.df * Ft.df;}}); - 0x3: divd({{ Fd.df = Fs.df / Ft.df;}}); - 0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}}); - 0x5: absd({{ Fd.df = fabs(Fs.df);}}); - 0x6: movd({{ Fd.ud = Fs.ud;}}); - 0x7: negd({{ Fd.df = -1 * Fs.df;}}); + 0x0: add_d({{ Fd.df = Fs.df + Ft.df;}}); + 0x1: sub_d({{ Fd.df = Fs.df - Ft.df;}}); + 0x2: mul_d({{ Fd.df = Fs.df * Ft.df;}}); + 0x3: div_d({{ Fd.df = Fs.df / Ft.df;}}); + 0x4: sqrt_d({{ Fd.df = sqrt(Fs.df);}}); + 0x5: abs_d({{ Fd.df = fabs(Fs.df);}}); + 0x6: mov_d({{ Fd.ud = Fs.ud;}}); + 0x7: neg_d({{ Fd.df = -1 * Fs.df;}}); } } 0x1: decode FUNCTION_LO { - format Float64Op { + format FloatOp { 0x0: round_l_d({{ - Fd.ud = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_NEAREST); + Fd.ud = fpConvert(roundFP(Fs.df,0), DOUBLE_TO_LONG); }}); 0x1: trunc_l_d({{ - Fd.ud = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_ZERO); + Fd.ud = fpConvert(truncFP(Fs.df), DOUBLE_TO_LONG); }}); 0x2: ceil_l_d({{ - Fd.ud = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_UP); + Fd.ud = fpConvert(ceil(Fs.df), DOUBLE_TO_LONG); }}); 0x3: floor_l_d({{ - Fd.ud = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_DOWN); + Fd.ud = fpConvert(floor(Fs.df), DOUBLE_TO_LONG); }}); } format FloatOp { 0x4: round_w_d({{ - Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_NEAREST); + Fd.uw = fpConvert(roundFP(Fs.df,0), DOUBLE_TO_WORD); }}); 0x5: trunc_w_d({{ - Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_ZERO); + Fd.uw = fpConvert(truncFP(Fs.df), DOUBLE_TO_WORD); }}); 0x6: ceil_w_d({{ - Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_UP); + Fd.uw = fpConvert(ceil(Fs.df), DOUBLE_TO_WORD); }}); 0x7: floor_w_d({{ - Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_DOWN); + Fd.uw = fpConvert(floor(Fs.df), DOUBLE_TO_WORD); }}); } } @@ -652,56 +747,164 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { format FloatOp { - 0x0: movfd({{if (xc->readMiscReg(FPCR) != CC) Fd.df = Fs.df; }}); - 0x1: movtd({{if (xc->readMiscReg(FPCR) == CC) Fd.df = Fs.df; }}); + 0x0: movf_d({{if (getFPConditionCode(FCSR,CC) == 0) Fd.df = Fs.df; }}); + 0x1: movt_d({{if (getFPConditionCode(FCSR,CC) == 1) Fd.df = Fs.df; }}); } } format BasicOp { - 0x2: movzd({{ if (Rt == 0) Fd.df = Fs.df; }}); - 0x3: movnd({{ if (Rt != 0) Fd.df = Fs.df; }}); + 0x2: movz_d({{ if (Rt == 0) Fd.df = Fs.df; }}); + 0x3: movn_d({{ if (Rt != 0) Fd.df = Fs.df; }}); } - format Float64Op { - 0x5: recipd({{ Fd.df = 1 / Fs.df}}); - 0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }}); + format FloatOp { + 0x5: recip_d({{ Fd.df = 1 / Fs.df}}); + 0x6: rsqrt_d({{ Fd.df = 1 / sqrt(Fs.df) }}); } } 0x4: decode FUNCTION_LO { format FloatOp { 0x0: cvt_s_d({{ - int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_SINGLE, rnd_mode); + Fd.uw = fpConvert(Fs.df, DOUBLE_TO_SINGLE); }}); 0x4: cvt_w_d({{ - int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_WORD, rnd_mode); + Fd.uw = fpConvert(Fs.df, DOUBLE_TO_WORD); }}); - } - //only legal for 64 bit - format Float64Op { 0x5: cvt_l_d({{ - int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.ud = convert_and_round(Fs.ud, DOUBLE_TO_LONG, rnd_mode); + Fd.ud = fpConvert(Fs.df, DOUBLE_TO_LONG); + }}); + } + } + + 0x6: decode FUNCTION_LO { + format FloatCompareOp { + 0x0: c_f_d({{ cond = 0; }}); + + 0x1: c_un_d({{ + if (isnan(Fs.df) || isnan(Ft.df)) + cond = 1; + else + cond = 0; }}); + + 0x2: c_eq_d({{ + if (isnan(Fs.df) || isnan(Ft.df)) + cond = 0; + else + cond = (Fs.df == Ft.df); + }}); + + 0x3: c_ueq_d({{ + if (isnan(Fs.df) || isnan(Ft.df)) + cond = 1; + else + cond = (Fs.df == Ft.df); + }}); + + 0x4: c_olt_d({{ + if (isnan(Fs.df) || isnan(Ft.df)) + cond = 0; + else + cond = (Fs.df < Ft.df); + }}); + + 0x5: c_ult_d({{ + if (isnan(Fs.df) || isnan(Ft.df)) + cond = 1; + else + cond = (Fs.df < Ft.df); + }}); + + 0x6: c_ole_d({{ + if (isnan(Fs.df) || isnan(Ft.df)) + cond = 0; + else + cond = (Fs.df <= Ft.df); + }}); + + 0x7: c_ule_d({{ + if (isnan(Fs.df) || isnan(Ft.df)) + cond = 1; + else + cond = (Fs.df <= Ft.df); + }}); + } + } + + 0x7: decode FUNCTION_LO { + format FloatCompareWithXcptOp { + 0x0: c_sf_d({{ cond = 0; }}); + + 0x1: c_ngle_d({{ + if (isnan(Fs.df) || isnan(Ft.df)) + cond = 1; + else + cond = 0; + }}); + + 0x2: c_seq_d({{ + if (isnan(Fs.df) || isnan(Ft.df)) + cond = 0; + else + cond = (Fs.df == Ft.df); + }}); + + 0x3: c_ngl_d({{ + if (isnan(Fs.df) || isnan(Ft.df)) + cond = 1; + else + cond = (Fs.df == Ft.df); + }}); + + 0x4: c_lt_d({{ + if (isnan(Fs.df) || isnan(Ft.df)) + cond = 0; + else + cond = (Fs.df < Ft.df); + }}); + + 0x5: c_nge_d({{ + if (isnan(Fs.df) || isnan(Ft.df)) + cond = 1; + else + cond = (Fs.df < Ft.df); + }}); + + 0x6: c_le_d({{ + if (isnan(Fs.df) || isnan(Ft.df)) + cond = 0; + else + cond = (Fs.df <= Ft.df); + }}); + + 0x7: c_ngt_d({{ + if (isnan(Fs.df) || isnan(Ft.df)) + cond = 1; + else + cond = (Fs.df <= Ft.df); + }}); } } } //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W 0x4: decode FUNCTION { - format FloatOp { + format FloatConvertOp { 0x20: cvt_s_w({{ - int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.uw = convert_and_round(Fs.uw, WORD_TO_SINGLE, rnd_mode); + Fd.uw = fpConvert(Fs.sf, WORD_TO_SINGLE); }}); 0x21: cvt_d_w({{ - int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.ud = convert_and_round(Fs.uw, WORD_TO_DOUBLE, rnd_mode); + Fd.ud = fpConvert(Fs.sf, WORD_TO_DOUBLE); + }}); + } + + format Float64ConvertOp { + 0x26: cvt_ps_pw({{ + Fd.ud = fpConvert(Fs.ud, WORD_TO_PS); }}); } } @@ -710,15 +913,17 @@ decode OPCODE_HI default Unknown::unknown() { //Note: "1. Format type L is legal only if 64-bit floating point operations //are enabled." 0x5: decode FUNCTION_HI { - format Float64Op { - 0x10: cvt_s_l({{ - int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.uw = convert_and_round(Fs.ud, LONG_TO_SINGLE, rnd_mode); + format Float64ConvertOp { + 0x20: cvt_s_l({{ + Fd.uw = fpConvert(Fs.ud, LONG_TO_SINGLE); }}); - 0x11: cvt_d_l({{ - int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.ud = convert_and_round(Fs.ud, LONG_TO_DOUBLE, rnd_mode); + 0x21: cvt_d_l({{ + Fd.ud = fpConvert(Fs.ud, LONG_TO_DOUBLE); + }}); + + 0x26: cvt_ps_l({{ + Fd.ud = fpConvert(Fs.ud, LONG_TO_PS); }}); } } @@ -729,34 +934,34 @@ decode OPCODE_HI default Unknown::unknown() { 0x6: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { format Float64Op { - 0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = Fs.df + Ft.df; + 0x0: add_ps({{ + Fd1.sf = Fs1.sf + Ft2.sf; + Fd2.sf = Fs2.sf + Ft2.sf; }}); - 0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = Fs.df - Ft.df; + 0x1: sub_ps({{ + Fd1.sf = Fs1.sf - Ft2.sf; + Fd2.sf = Fs2.sf - Ft2.sf; }}); - 0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = Fs.df * Ft.df; + 0x2: mul_ps({{ + Fd1.sf = Fs1.sf * Ft2.sf; + Fd2.sf = Fs2.sf * Ft2.sf; }}); - 0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = fabs(Fs.df); + 0x5: abs_ps({{ + Fd1.sf = fabs(Fs1.sf); + Fd2.sf = fabs(Fs2.sf); }}); - 0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - //Fd.df = Fs<31:0> | Ft<31:0>; + 0x6: mov_ps({{ + Fd1.sf = Fs1.sf; + Fd2.sf = Fs2.sf; }}); - 0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = -1 * Fs.df; + 0x7: neg_ps({{ + Fd1.sf = -1 * Fs1.sf; + Fd2.sf = -1 * Fs2.sf; }}); } } @@ -764,37 +969,237 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { format Float64Op { - 0x0: movfps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs;}}); - 0x1: movtps({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs;}}); + 0x0: movf_ps({{ + if (getFPConditionCode(FCSR, CC) == 0) + Fd1 = Fs1; + if (getFPConditionCode(FCSR, CC+1) == 0) + Fd2 = Fs2; + }}); + + 0x1: movt_ps({{ + if (getFPConditionCode(FCSR, CC) == 1) + Fd1 = Fs1; + if (getFPConditionCode(FCSR, CC+1) == 1) + Fd2 = Fs2; + }}); } } - format BasicOp { - 0x2: movzps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }}); - 0x3: movnps({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs; }}); + format Float64Op { + 0x2: movz_ps({{ + if (getFPConditionCode(FCSR, CC) == 0) + Fd1 = Fs1; + if (getFPConditionCode(FCSR, CC) == 0) + Fd2 = Fs2; + }}); + + 0x3: movn_ps({{ + if (getFPConditionCode(FCSR, CC) == 1) + Fd1 = Fs1; + if (getFPConditionCode(FCSR, CC) == 1) + Fd2 = Fs2; + }}); } } 0x4: decode FUNCTION_LO { 0x0: Float64Op::cvt_s_pu({{ - int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.uw = convert_and_round(Fs.ud, PUPPER_TO_SINGLE, rnd_mode); + Fd.uw = fpConvert(Fs2.uw, PU_TO_SINGLE); }}); } 0x5: decode FUNCTION_LO { format Float64Op { 0x0: cvt_s_pl({{ - int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.uw = convert_and_round(Fs.ud, PLOWER_TO_SINGLE, - rnd_mode); + Fd.uw = fpConvert(Fs1.uw, PL_TO_SINGLE); + }}); + + 0x4: pll({{ Fd.ud = (uint64_t) Fs1.uw << 32 | Ft1.uw; }}); + 0x5: plu({{ Fd.ud = (uint64_t) Fs1.uw << 32 | Ft2.uw; }}); + 0x6: pul({{ Fd.ud = (uint64_t) Fs2.uw << 32 | Ft1.uw; }}); + 0x7: puu({{ Fd.ud = (uint64_t) Fs2.uw << 32 | Ft2.uw; }}); + } + } + + 0x6: decode FUNCTION_LO { + format FloatPSCompareOp { + 0x0: c_f_ps({{ cond1 = 0; cond2 = 0; }}); + + 0x1: c_un_ps({{ + if (isnan(Fs1.sf) || isnan(Ft1.sf)) + cond1 = 1; + else + cond1 = 0; + + if (isnan(Fs2.sf) || isnan(Ft2.sf)) + cond2 = 1; + else + cond2 = 0; + + }}); + + 0x2: c_eq_ps({{ + if (isnan(Fs1.sf) || isnan(Ft1.sf)) + cond1 = 0; + else + cond1 = (Fs1.sf == Ft1.sf); + + if (isnan(Fs2.sf) || isnan(Ft2.sf)) + cond2 = 0; + else + cond2 = (Fs2.sf == Ft2.sf); + }}); + + 0x3: c_ueq_ps({{ + if (isnan(Fs1.sf) || isnan(Ft1.sf)) + cond1 = 1; + else + cond1 = (Fs1.sf == Ft1.sf); + + if (isnan(Fs2.sf) || isnan(Ft2.sf)) + cond2 = 1; + else + cond2 = (Fs2.sf == Ft2.sf); + }}); + + 0x4: c_olt_ps({{ + if (isnan(Fs1.sf) || isnan(Ft1.sf)) + cond1 = 0; + else + cond1 = (Fs1.sf < Ft1.sf); + + if (isnan(Fs2.sf) || isnan(Ft2.sf)) + cond2 = 0; + else + cond2 = (Fs2.sf < Ft2.sf); }}); - 0x4: pll({{ Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<31:0>; }}); - 0x5: plu({{ Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<63:32>;}}); - 0x6: pul({{ Fd.ud = Fs.ud<63:32> << 32 | Ft.ud<31:0>; }}); - 0x7: puu({{ Fd.ud = Fs.ud<63:32> << 32 | Ft.ud<63:32>;}}); + 0x5: c_ult_ps({{ + if (isnan(Fs1.sf) || isnan(Ft1.sf)) + cond1 = 1; + else + cond1 = (Fs.sf < Ft.sf); + + if (isnan(Fs2.sf) || isnan(Ft2.sf)) + cond2 = 1; + else + cond2 = (Fs2.sf < Ft2.sf); + }}); + + 0x6: c_ole_ps({{ + if (isnan(Fs.sf) || isnan(Ft.sf)) + cond1 = 0; + else + cond1 = (Fs.sf <= Ft.sf); + + if (isnan(Fs2.sf) || isnan(Ft2.sf)) + cond2 = 0; + else + cond2 = (Fs2.sf <= Ft2.sf); + }}); + + 0x7: c_ule_ps({{ + if (isnan(Fs1.sf) || isnan(Ft1.sf)) + cond1 = 1; + else + cond1 = (Fs1.sf <= Ft1.sf); + + if (isnan(Fs2.sf) || isnan(Ft2.sf)) + cond2 = 1; + else + cond2 = (Fs2.sf <= Ft2.sf); + }}); + } + } + + 0x7: decode FUNCTION_LO { + format FloatPSCompareWithXcptOp { + 0x0: c_sf_ps({{ cond1 = 0; cond2 = 0; }}); + + 0x1: c_ngle_ps({{ + if (isnan(Fs1.sf) || isnan(Ft1.sf)) + cond1 = 1; + else + cond1 = 0; + + if (isnan(Fs2.sf) || isnan(Ft2.sf)) + cond2 = 1; + else + cond2 = 0; + }}); + + 0x2: c_seq_ps({{ + if (isnan(Fs1.sf) || isnan(Ft1.sf)) + cond1 = 0; + else + cond1 = (Fs1.sf == Ft1.sf); + + if (isnan(Fs2.sf) || isnan(Ft2.sf)) + cond2 = 0; + else + cond2 = (Fs2.sf == Ft2.sf); + }}); + + 0x3: c_ngl_ps({{ + if (isnan(Fs1.sf) || isnan(Ft1.sf)) + cond1 = 1; + else + cond1 = (Fs1.sf == Ft1.sf); + + if (isnan(Fs2.sf) || isnan(Ft2.sf)) + cond2 = 1; + else + cond2 = (Fs2.sf == Ft2.sf); + }}); + + 0x4: c_lt_ps({{ + if (isnan(Fs1.sf) || isnan(Ft1.sf)) + cond1 = 0; + else + cond1 = (Fs1.sf < Ft1.sf); + + if (isnan(Fs2.sf) || isnan(Ft2.sf)) + cond2 = 0; + else + cond2 = (Fs2.sf < Ft2.sf); + }}); + + 0x5: c_nge_ps({{ + if (isnan(Fs1.sf) || isnan(Ft1.sf)) + cond1 = 1; + else + cond1 = (Fs1.sf < Ft1.sf); + + if (isnan(Fs2.sf) || isnan(Ft2.sf)) + cond2 = 1; + else + cond2 = (Fs2.sf < Ft2.sf); + }}); + + 0x6: c_le_ps({{ + if (isnan(Fs1.sf) || isnan(Ft1.sf)) + cond1 = 0; + else + cond1 = (Fs1.sf <= Ft1.sf); + + if (isnan(Fs2.sf) || isnan(Ft2.sf)) + cond2 = 0; + else + cond2 = (Fs2.sf <= Ft2.sf); + }}); + + 0x7: c_ngt_ps({{ + if (isnan(Fs1.sf) || isnan(Ft1.sf)) + cond1 = 1; + else + cond1 = (Fs1.sf <= Ft1.sf); + + if (isnan(Fs2.sf) || isnan(Ft2.sf)) + cond2 = 1; + else + cond2 = (Fs2.sf <= Ft2.sf); + }}); } } } @@ -840,23 +1245,17 @@ decode OPCODE_HI default Unknown::unknown() { 0x3: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { format LoadFloatMemory { - 0x0: lwxc1({{ /*F_t<31:0> = Mem.sf; */}}, {{ EA = Rs + Rt; }}); - 0x1: ldxc1({{ /*F_t<63:0> = Mem.df;*/ }}, {{ EA = Rs + Rt; }}); - 0x5: luxc1({{ /*F_t<31:0> = Mem.df; */}}, - {{ //Need to make EA<2:0> = 0 - EA = Rs + Rt; - }}); + 0x0: lwxc1({{ Ft.uw = Mem.uw;}}, {{ EA = Rs + Rt; }}); + 0x1: ldxc1({{ Ft.ud = Mem.ud;}}, {{ EA = Rs + Rt; }}); + 0x5: luxc1({{ Ft.uw = Mem.ud;}}, {{ EA = Rs + Rt; }}); } } 0x1: decode FUNCTION_LO { format StoreFloatMemory { - 0x0: swxc1({{ /*Mem.sf = Ft<31:0>; */}},{{ EA = Rs + Rt; }}); - 0x1: sdxc1({{ /*Mem.df = Ft<63:0> */}}, {{ EA = Rs + Rt; }}); - 0x5: suxc1({{ /*Mem.df = F_t<63:0>;*/}}, - {{ //Need to make sure EA<2:0> = 0 - EA = Rs + Rt; - }}); + 0x0: swxc1({{ Mem.uw = Ft.uw;}}, {{ EA = Rs + Rt; }}); + 0x1: sdxc1({{ Mem.ud = Ft.ud;}}, {{ EA = Rs + Rt; }}); + 0x5: suxc1({{ Mem.ud = Ft.ud;}}, {{ EA = Rs + Rt; }}); } 0x7: WarnUnimpl::prefx(); @@ -867,49 +1266,44 @@ decode OPCODE_HI default Unknown::unknown() { format BasicOp { 0x4: decode FUNCTION_LO { - 0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }}); - 0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }}); + 0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }}); + 0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }}); 0x6: madd_ps({{ - //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = (Fs.df * Fs.df) + Fr.df; + Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df; + Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df; }}); } 0x5: decode FUNCTION_LO { - 0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }}); - 0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }}); + 0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }}); + 0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }}); 0x6: msub_ps({{ - //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = (Fs.df * Fs.df) - Fr.df; + Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df; + Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df; }}); } 0x6: decode FUNCTION_LO { - 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }}); - 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }}); + 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }}); + 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }}); 0x6: nmadd_ps({{ - //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; + Fd1.sf = -1 * ((Fs1.df * Ft1.df) + Fr1.df); + Fd2.sf = -1 * ((Fs2.df * Ft2.df) + Fr2.df); }}); } 0x7: decode FUNCTION_LO { - 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }}); - 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }}); + 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }}); + 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }}); 0x6: nmsub_ps({{ - //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; + Fd1.sf = -1 * ((Fs1.df * Ft1.df) - Fr1.df); + Fd2.sf = -1 * ((Fs2.df * Ft2.df) - Fr2.df); }}); } } } } - //MIPS obsolete instructions format BranchLikely { 0x4: beql({{ cond = (Rs.sw == 0); }}); 0x5: bnel({{ cond = (Rs.sw != 0); }}); @@ -926,59 +1320,63 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode FUNCTION_LO { format IntOp { 0x0: madd({{ - int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32; + int64_t temp1 = (int64_t) HI << 32 | LO; temp1 = temp1 + (Rs.sw * Rt.sw); - xc->setMiscReg(Hi,temp1<63:32>); - xc->setMiscReg(Lo,temp1<31:0>); - }}); + HI = temp1<63:32>; + LO = temp1<31:0>; + }}); 0x1: maddu({{ - int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32; + int64_t temp1 = (int64_t) HI << 32 | LO; temp1 = temp1 + (Rs.uw * Rt.uw); - xc->setMiscReg(Hi,temp1<63:32>); - xc->setMiscReg(Lo,temp1<31:0>); - }}); + HI = temp1<63:32>; + LO = temp1<31:0>; + }}); 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); 0x4: msub({{ - int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32; + int64_t temp1 = (int64_t) HI << 32 | LO; temp1 = temp1 - (Rs.sw * Rt.sw); - xc->setMiscReg(Hi,temp1<63:32>); - xc->setMiscReg(Lo,temp1<31:0>); - }}); + HI = temp1<63:32>; + LO = temp1<31:0>; + }}); 0x5: msubu({{ - int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32; + int64_t temp1 = (int64_t) HI << 32 | LO; temp1 = temp1 - (Rs.uw * Rt.uw); - xc->setMiscReg(Hi,temp1<63:32>); - xc->setMiscReg(Lo,temp1<31:0>); - }}); + HI = temp1<63:32>; + LO = temp1<31:0>; + }}); } } 0x4: decode FUNCTION_LO { format BasicOp { 0x0: clz({{ - /*int cnt = 0; - int idx = 0; - while ( Rs.uw<idx> != 1) { - cnt++; - idx--; + int cnt = 0; + uint32_t mask = 0x80000000; + for (int i=0; i < 32; i++) { + if( (Rs & mask) == 0) { + cnt++; + } else { + break; + } } - - Rd.uw = cnt;*/ + Rd.uw = cnt; }}); 0x1: clo({{ - /*int cnt = 0; - int idx = 0; - while ( Rs.uw<idx> != 0) { - cnt++; - idx--; + int cnt = 0; + uint32_t mask = 0x80000000; + for (int i=0; i < 32; i++) { + if( (Rs & mask) != 0) { + cnt++; + } else { + break; + } } - - Rd.uw = cnt;*/ + Rd.uw = cnt; }}); } } @@ -1012,8 +1410,8 @@ decode OPCODE_HI default Unknown::unknown() { 0x02: FailUnimpl::wsbh(); format BasicOp { - 0x10: seb({{ Rd.sw = Rt<7:0>}}); - 0x18: seh({{ Rd.sw = Rt<15:0>}}); + 0x10: seb({{ Rd.sw = Rt.sw<7:0>}}); + 0x18: seh({{ Rd.sw = Rt.sw<15:0>}}); } } @@ -1033,8 +1431,6 @@ decode OPCODE_HI default Unknown::unknown() { uint32_t unalign_addr = Rs + disp; uint32_t offset = unalign_addr & 0x00000003; #if BYTE_ORDER == BIG_ENDIAN - std::cout << "Big Endian Byte Order\n"; - switch(offset) { case 0: @@ -1060,8 +1456,6 @@ decode OPCODE_HI default Unknown::unknown() { panic("lwl: bad offset"); } #elif BYTE_ORDER == LITTLE_ENDIAN - std::cout << "Little Endian Byte Order\n"; - switch(offset) { case 0: @@ -1119,8 +1513,6 @@ decode OPCODE_HI default Unknown::unknown() { }}, {{ EA = (Rs + disp) & ~3; }}); } - - 0x7: FailUnimpl::reserved(); } 0x5: decode OPCODE_LO default FailUnimpl::reserved() { @@ -1274,7 +1666,7 @@ decode OPCODE_HI default Unknown::unknown() { } 0x6: decode OPCODE_LO default FailUnimpl::reserved() { - 0x0: FailUnimpl::ll(); + 0x0: LoadMemory::ll({{Rt.uw = Mem.uw}},mem_flags=LOCKED); format LoadFloatMemory { 0x1: lwc1({{ Ft.uw = Mem.uw; }}); @@ -1284,7 +1676,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x7: decode OPCODE_LO default FailUnimpl::reserved() { - 0x0: FailUnimpl::sc(); + 0x0: StoreMemory::sc({{ Mem.uw = Rt.uw; Rt.uw = 1; }}); format StoreFloatMemory { 0x1: swc1({{ Mem.uw = Ft.uw; }}); diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index 39db88c23..8cfa37a20 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -261,7 +261,7 @@ def format Branch(code,*flags) {{ #Add Link Code if Link instruction strlen = len(name) if name[strlen-2:] == 'al': - code += 'r31 = NNPC;\n' + code += 'R31 = NNPC;\n' #Condition code code = 'bool cond;\n' + code @@ -285,7 +285,7 @@ def format BranchLikely(code,*flags) {{ #Add Link Code if Link instruction strlen = len(name) if name[strlen-3:] == 'all': - code += 'r31 = NNPC;\n' + code += 'R31 = NNPC;\n' #Condition code code = 'bool cond;\n' + code @@ -307,7 +307,7 @@ def format Jump(code,*flags) {{ #Add Link Code if Link instruction strlen = len(name) if strlen > 1 and name[1:] == 'al': - code = 'r31 = NNPC;\n' + code + code = 'R31 = NNPC;\n' + code iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),\ diff --git a/arch/mips/isa/formats/fp.isa b/arch/mips/isa/formats/fp.isa index 65b259e20..9f2c24755 100644 --- a/arch/mips/isa/formats/fp.isa +++ b/arch/mips/isa/formats/fp.isa @@ -39,6 +39,34 @@ def format FloatOp(code, *flags) {{ exec_output = BasicExecute.subst(iop) }}; +def format FloatCompareOp(code, *flags) {{ + code = 'bool cond;\n' + code + code += 'FCSR = makeCCVector(FCSR, CC,cond);\n' + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format FloatCompareWithXcptOp(code, *flags) {{ + code = 'bool cond;\n' + code + code += 'FCSR = makeCCVector(FCSR, CC,cond);\n' + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format FloatConvertOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + // Primary format for float64 operate instructions: def format Float64Op(code, *flags) {{ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) @@ -47,3 +75,35 @@ def format Float64Op(code, *flags) {{ decode_block = BasicDecode.subst(iop) exec_output = BasicExecute.subst(iop) }}; + +def format Float64ConvertOp(code, *flags) {{ + code = 'bool cond;\n' + code + code += 'FCSR = makeCCVector(FCSR, CC,cond);\n' + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format FloatPSCompareOp(code, *flags) {{ + code = 'bool cond1;\nbool cond2;\n' + code + code += 'FCSR = makeCCVector(FCSR, CC+1, cond1);\n' + code += 'FCSR = makeCCVector(FCSR, CC, cond2);\n' + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format FloatPSCompareWithXcptOp(code, *flags) {{ + code = 'bool cond1;\nbool cond2;\n' + code + code += 'FCSR = makeCCVector(FCSR, CC+1, cond1);\n' + code += 'FCSR = makeCCVector(FCSR, CC, cond2);\n' + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/arch/mips/isa/operands.isa b/arch/mips/isa/operands.isa index 2fa3238dc..0f9c74b48 100644 --- a/arch/mips/isa/operands.isa +++ b/arch/mips/isa/operands.isa @@ -13,22 +13,49 @@ def operand_types {{ }}; def operands {{ + #General Purpose Integer Reg Operands 'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1), 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2), 'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 3), - 'r31': ('IntReg', 'uw','R31','IsInteger', 4), - 'R0': ('IntReg', 'uw','R0', 'IsInteger', 5), + + #Operands used for Link or Syscall Insts + 'R31': ('IntReg', 'uw','31','IsInteger', 4), 'R2': ('IntReg', 'uw','2', 'IsInteger', 5), + #Special Integer Reg operands + 'HI': ('IntReg', 'uw','32', 'IsInteger', 6), + 'LO': ('IntReg', 'uw','33', 'IsInteger', 7), + + #Immediate Value operand 'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3), + #Floating Point Reg Operands 'Fd': ('FloatReg', 'sf', 'FD', 'IsFloating', 1), 'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2), 'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3), 'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3), + #Special Floating Point Control Reg Operands + 'FIR': ('FloatReg', 'uw', '32', 'IsFloating', 1), + 'FCCR': ('FloatReg', 'uw', '33', 'IsFloating', 2), + 'FEXR': ('FloatReg', 'uw', '34', 'IsFloating', 3), + 'FENR': ('FloatReg', 'uw', '35', 'IsFloating', 3), + 'FCSR': ('FloatReg', 'uw', '36', 'IsFloating', 3), + + #Operands For Paired Singles FP Operations + 'Fd1': ('FloatReg', 'sf', 'FD', 'IsFloating', 4), + 'Fd2': ('FloatReg', 'sf', 'FD+1', 'IsFloating', 4), + 'Fs1': ('FloatReg', 'sf', 'FS', 'IsFloating', 5), + 'Fs2': ('FloatReg', 'sf', 'FS+1', 'IsFloating', 5), + 'Ft1': ('FloatReg', 'sf', 'FT', 'IsFloating', 6), + 'Ft2': ('FloatReg', 'sf', 'FT+1', 'IsFloating', 6), + 'Fr1': ('FloatReg', 'sf', 'FR', 'IsFloating', 7), + 'Fr2': ('FloatReg', 'sf', 'FR+1', 'IsFloating', 7), + + #Memory Operand 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), + #Program Counter Operands 'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4), 'NNPC':('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4) }}; diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc index fcc3007ca..216a6e2ec 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -61,81 +61,75 @@ MipsISA::MiscRegFile::copyMiscRegs(ExecContext *xc) } uint64_t -MipsISA::convert_and_round(uint32_t fp_val, ConvertType cvt_type, int rnd_mode) +MipsISA::fpConvert(double fp_val, ConvertType cvt_type) { - uint64_t ret_val = 0; - switch (cvt_type) { case SINGLE_TO_DOUBLE: - uint64_t single_sign = fp_val & 0x80000000; - - uint64_t single_exp = (fp_val & 0x7F800000) >> 22; - single_exp -= 127; - - uint64_t single_mantissa = fp_val & 0x007FFFFF; - - uint64_t double_exp = single_exp + 1023; - double_exp = double_exp << 51; - - uint64_t double_val = single_sign << 63 | double_exp | single_mantissa; - - return double_val; + double sdouble_val = fp_val; + void *sdouble_ptr = &sdouble_val; + uint64_t sdp_bits = *(uint64_t *) sdouble_ptr; + return sdp_bits; + + case SINGLE_TO_WORD: + int32_t sword_val = (int32_t) fp_val; + void *sword_ptr = &sword_val; + uint64_t sword_bits= *(uint32_t *) sword_ptr; + return sword_bits; + + case WORD_TO_SINGLE: + float wfloat_val = fp_val; + void *wfloat_ptr = &wfloat_val; + uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr; + return wfloat_bits; + + case WORD_TO_DOUBLE: + double wdouble_val = fp_val; + void *wdouble_ptr = &wdouble_val; + uint64_t wdp_bits = *(uint64_t *) wdouble_ptr; + return wdp_bits; default: - panic("Invalid Floating Point Conversion Type (%d) being used.\n",cvt_type); - return ret_val; + panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type); + return 0; } } -uint64_t -MipsISA::convert_and_round(uint64_t fp_val, ConvertType cvt_type, int rnd_mode) +double +MipsISA::roundFP(double val, int digits) { + double digit_offset = pow(10.0,digits); + val = val * digit_offset; + val = val + 0.5; + val = floor(val); + val = val / digit_offset; + return val; +} - uint64_t ret_val = 0; - - switch (cvt_type) - { - case SINGLE_TO_DOUBLE: - uint64_t single_sign = fp_val & 0x80000000; - - uint64_t single_exp = (fp_val & 0x7F800000) >> 22; - single_exp -= 127; - - uint64_t single_mantissa = fp_val & 0x007FFFFF; - - uint64_t double_exp = single_exp + 1023; - double_exp = double_exp << 51; - - uint64_t double_val = single_sign << 63 | double_exp | single_mantissa; - - return double_val; - - default: - panic("Invalid Floating Point Conversion Type (%d) being used.\n",cvt_type); - return ret_val; - } +double +MipsISA::truncFP(double val) +{ + int trunc_val = (int) val; + return (double) trunc_val; } +bool +MipsISA::getFPConditionCode(uint32_t fcsr_reg, int cc) +{ + //uint32_t cc_bits = xc->readFloatReg(35); + return false;//regFile.floatRegfile.getConditionCode(cc); +} -uint64_t -MipsISA::convert_and_round(double fp_val, ConvertType cvt_type, int rnd_mode) +uint32_t +MipsISA::makeCCVector(uint32_t fcsr, int num, bool val) { - switch (cvt_type) - { - case SINGLE_TO_DOUBLE: - double double_val = fp_val; - void *double_ptr = &double_val; - uint64_t dp_bits = *(uint64_t *) double_ptr ; - return dp_bits; + int shift = (num == 0) ? 22 : num + 23; - default: - panic("Invalid Floating Point Conversion Type (%d) being used.\n",cvt_type); - return 0; - } -} + fcsr = fcsr | (val << shift); + return fcsr; +} #if FULL_SYSTEM diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 33c490dcc..148c405df 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -31,7 +31,7 @@ #include "arch/mips/constants.hh" #include "arch/mips/types.hh" -#include "arch/mips/regfile.hh" +#include "arch/mips/regfile/regfile.hh" #include "arch/mips/faults.hh" #include "arch/mips/utility.hh" #include "base/misc.hh" @@ -137,9 +137,11 @@ namespace MipsISA void copyRegs(ExecContext *src, ExecContext *dest); - uint64_t convert_and_round(uint32_t fp_val, ConvertType cvt_type, int rnd_mode = 0); - uint64_t convert_and_round(uint64_t fp_val, ConvertType cvt_type, int rnd_mode = 0); - uint64_t convert_and_round(double fp_val, ConvertType cvt_type, int rnd_mode = 0); + uint64_t fpConvert(double fp_val, ConvertType cvt_type); + double roundFP(double val, int digits); + double truncFP(double val); + bool getFPConditionCode(uint32_t fcsr_reg, int cc); + uint32_t makeCCVector(uint32_t fcsr, int num, bool val); // Machine operations diff --git a/arch/mips/regfile/float_regfile.hh b/arch/mips/regfile/float_regfile.hh new file mode 100644 index 000000000..15c6f97f4 --- /dev/null +++ b/arch/mips/regfile/float_regfile.hh @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_MIPS_FLOAT_REGFILE_HH__ +#define __ARCH_MIPS_FLOAT_REGFILE_HH__ + +#include "arch/mips/types.hh" +#include "arch/mips/constants.hh" +#include "base/misc.hh" +#include "config/full_system.hh" +#include "sim/byteswap.hh" +#include "sim/faults.hh" +#include "sim/host.hh" + +class Checkpoint; +class ExecContext; +class Regfile; + +namespace MipsISA +{ + class FloatRegFile + { + protected: + FloatReg32 regs[NumFloatRegs]; + + public: + + void clear() + { + bzero(regs, sizeof(regs)); + } + + double readReg(int floatReg, int width) + { + switch(width) + { + case SingleWidth: + void *float_ptr = ®s[floatReg]; + return *(float *) float_ptr; + + case DoubleWidth: + uint64_t double_val = (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg]; + void *double_ptr = &double_val; + return *(double *) double_ptr; + + default: + panic("Attempted to read a %d bit floating point register!", width); + } + } + + FloatRegBits readRegBits(int floatReg, int width) + { + if (floatReg < NumFloatArchRegs - 1) { + switch(width) + { + case SingleWidth: + return regs[floatReg]; + + case DoubleWidth: + return (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg]; + + default: + panic("Attempted to read a %d bit floating point register!", width); + } + } else { + if (width > SingleWidth) + assert("Control Regs are only 32 bits wide"); + + return regs[floatReg]; + } + } + + Fault setReg(int floatReg, const FloatReg &val, int width) + { + + switch(width) + { + case SingleWidth: + float temp = val; + void *float_ptr = &temp; + regs[floatReg] = *(FloatReg32 *) float_ptr; + break; + + case DoubleWidth: + const void *double_ptr = &val; + FloatReg64 temp_double = *(FloatReg64 *) double_ptr; + regs[floatReg + 1] = temp_double >> 32; + regs[floatReg] = temp_double; + break; + + default: + panic("Attempted to read a %d bit floating point register!", width); + } + + return NoFault; + } + + Fault setRegBits(int floatReg, const FloatRegBits &val, int width) + { + using namespace std; + + switch(width) + { + case SingleWidth: + regs[floatReg] = val; + break; + + case DoubleWidth: + regs[floatReg + 1] = val >> 32; + regs[floatReg] = val; + break; + + default: + panic("Attempted to read a %d bit floating point register!", width); + } + return NoFault; + } + + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); + }; + + enum MiscFloatRegNums { + FIR = NumFloatArchRegs, + FCCR, + FEXR, + FENR, + FCSR + }; + +} // namespace MipsISA + +#endif diff --git a/arch/mips/int_regfile.hh b/arch/mips/regfile/int_regfile.hh index cff9eb0d2..3cd87734d 100644 --- a/arch/mips/int_regfile.hh +++ b/arch/mips/regfile/int_regfile.hh @@ -31,6 +31,7 @@ #include "arch/mips/types.hh" #include "arch/mips/constants.hh" +#include "base/misc.hh" #include "sim/faults.hh" class Checkpoint; @@ -43,8 +44,6 @@ namespace MipsISA { protected: IntReg regs[NumIntRegs]; - IntReg hi; - IntReg lo; public: IntReg readReg(int intReg) @@ -58,33 +57,17 @@ namespace MipsISA return NoFault; } - IntReg readHi() - { - return hi; - } - - Fault setHi(const IntReg &val) - { - hi = val; - return NoFault; - } - - IntReg readLo() - { - return lo; - } - - Fault setLo(const IntReg &val) - { - lo = val; - return NoFault; - } - void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); }; + + enum MiscIntRegNums { + HI = NumIntArchRegs, + LO + }; + } // namespace MipsISA #endif diff --git a/arch/mips/misc_regfile.hh b/arch/mips/regfile/misc_regfile.hh index 9f054e5f7..9f054e5f7 100644 --- a/arch/mips/misc_regfile.hh +++ b/arch/mips/regfile/misc_regfile.hh diff --git a/arch/mips/regfile.hh b/arch/mips/regfile/regfile.hh index 3dcf8ef18..e77571b33 100644 --- a/arch/mips/regfile.hh +++ b/arch/mips/regfile/regfile.hh @@ -31,9 +31,9 @@ #include "arch/mips/types.hh" #include "arch/mips/constants.hh" -#include "arch/mips/int_regfile.hh" -#include "arch/mips/float_regfile.hh" -#include "arch/mips/misc_regfile.hh" +#include "arch/mips/regfile/int_regfile.hh" +#include "arch/mips/regfile/float_regfile.hh" +#include "arch/mips/regfile/misc_regfile.hh" #include "sim/faults.hh" class Checkpoint; @@ -58,31 +58,7 @@ namespace MipsISA MiscReg readMiscReg(int miscReg) { - if (miscReg < CtrlReg_DepTag) - return miscRegFile.readReg(miscReg); - else { - switch (miscReg) - { - case Hi: - return intRegFile.readHi(); - - case Lo: - return intRegFile.readLo(); - - case FIR: - return floatRegFile.readFIR(); - - case FCSR: - return floatRegFile.readFCSR(); - - case FPCR: - return floatRegFile.readFPCR(); - - default: - panic("Invalid Misc. Reg. Access\n"); - return 0; - } - } + return miscRegFile.readReg(miscReg); } MiscReg readMiscRegWithEffect(int miscReg, @@ -94,31 +70,7 @@ namespace MipsISA Fault setMiscReg(int miscReg, const MiscReg &val) { - if (miscReg < CtrlReg_DepTag) - return miscRegFile.setReg(miscReg, val); - else { - switch (miscReg) - { - case Hi: - return intRegFile.setHi(val); - - case Lo: - return intRegFile.setLo(val); - - case FIR: - return floatRegFile.setFIR(val); - - case FCSR: - return floatRegFile.setFCSR(val); - - case FPCR: - return floatRegFile.setFPCR(val); - - default: - panic("Invalid Misc. Reg. Access\n"); - return 0; - } - } + return miscRegFile.setReg(miscReg, val); } Fault setMiscRegWithEffect(int miscReg, const MiscReg &val, diff --git a/arch/mips/types.hh b/arch/mips/types.hh index 021ecad1c..4d5fb3456 100644 --- a/arch/mips/types.hh +++ b/arch/mips/types.hh @@ -68,13 +68,15 @@ namespace MipsISA LONG_TO_SINGLE, LONG_TO_DOUBLE, LONG_TO_WORD, + LONG_TO_PS, WORD_TO_SINGLE, WORD_TO_DOUBLE, WORD_TO_LONG, + WORD_TO_PS, - PLOWER_TO_SINGLE, - PUPPER_TO_SINGLE + PL_TO_SINGLE, + PU_TO_SINGLE }; //used in FP convert & round function diff --git a/arch/sparc/faults.cc b/arch/sparc/faults.cc index e83bba800..67a89ab0e 100644 --- a/arch/sparc/faults.cc +++ b/arch/sparc/faults.cc @@ -215,11 +215,6 @@ TrapType TrapInstruction::_baseTrapType = 0x100; FaultPriority TrapInstruction::_priority = 16; FaultStat TrapInstruction::_count; -FaultName UnimpFault::_name = "Unimplemented Simulator feature"; -TrapType UnimpFault::_trapType = 0x000; -FaultPriority UnimpFault::_priority = 0; -FaultStat UnimpFault::_count; - #if FULL_SYSTEM void SparcFault::invoke(ExecContext * xc) @@ -245,12 +240,15 @@ void SparcFault::invoke(ExecContext * xc) xc->regs.npc = xc->regs.pc + sizeof(MachInst);*/ } -void UnimpFault::invoke(ExecContext * xc) +#endif + +#if !FULL_SYSTEM + +void TrapInstruction::invoke(ExecContext * xc) { - panic("Unimpfault: %s\n", panicStr.c_str()); + xc->syscall(syscall_num); } - #endif } // namespace SparcISA diff --git a/arch/sparc/faults.hh b/arch/sparc/faults.hh index 87de8daaa..e8fb8dfc5 100644 --- a/arch/sparc/faults.hh +++ b/arch/sparc/faults.hh @@ -573,37 +573,19 @@ class TrapInstruction : public EnumeratedFault static TrapType _baseTrapType; static FaultPriority _priority; static FaultStat _count; + uint64_t syscall_num; TrapType baseTrapType() {return _baseTrapType;} public: - TrapInstruction(uint32_t n) : EnumeratedFault(n) {;} + TrapInstruction(uint32_t n, uint64_t syscall) : + EnumeratedFault(n), syscall_num(syscall) {;} FaultName name() {return _name;} FaultPriority priority() {return _priority;} FaultStat & countStat() {return _count;} -}; - -class UnimpFault : public SparcFault -{ - private: - static FaultName _name; - static TrapType _trapType; - static FaultPriority _priority; - static FaultStat _count; - std::string panicStr; - public: - UnimpFault(std::string _str) - : panicStr(_str) - { } - - FaultName name() {return _name;} - TrapType trapType() {return _trapType;} - FaultPriority priority() {return _priority;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM +#if !FULL_SYSTEM void invoke(ExecContext * xc); #endif }; - } // SparcISA namespace #endif // __FAULTS_HH__ diff --git a/arch/sparc/isa/base.isa b/arch/sparc/isa/base.isa index cb370a3e7..8ea11b40e 100644 --- a/arch/sparc/isa/base.isa +++ b/arch/sparc/isa/base.isa @@ -99,14 +99,16 @@ def template ROrImmDecode {{ let {{ def splitOutImm(code): - matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)') + matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?') rOrImmMatch = matcher.search(code) if (rOrImmMatch == None): return (False, code, '', '', '') rString = rOrImmMatch.group("rNum") + if (rOrImmMatch.group("typeQual") != None): + rString += rOrImmMatch.group("typeQual") iString = rOrImmMatch.group("iNum") orig_code = code - code = matcher.sub('Rs' + rOrImmMatch.group("rNum"), orig_code) + code = matcher.sub('Rs' + rString, orig_code) imm_code = matcher.sub('imm', orig_code) return (True, code, imm_code, rString, iString) }}; diff --git a/arch/sparc/isa/decoder.isa b/arch/sparc/isa/decoder.isa index b9e83afd6..52ca5d7cd 100644 --- a/arch/sparc/isa/decoder.isa +++ b/arch/sparc/isa/decoder.isa @@ -119,11 +119,11 @@ decode OP default Unknown::unknown() } }}); 0x0F: sdiv({{ - if(Rs2_or_imm13 == 0) + if(Rs2_or_imm13.sdw == 0) fault = new DivisionByZero; else { - Rd.udw = ((YValue << 32) | Rs1.sdw<31:0>) / Rs2_or_imm13; + Rd.udw = ((int64_t)((YValue << 32) | Rs1.sdw<31:0>)) / Rs2_or_imm13.sdw; if(Rd.udw<63:31> != 0) Rd.udw = 0x7FFFFFFF; else if(Rd.udw<63:> && Rd.udw<62:31> != 0xFFFFFFFF) @@ -166,13 +166,13 @@ decode OP default Unknown::unknown() {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} ); 0x1A: umulcc({{ - uint64_t resTemp, val2 = Rs2_or_imm13; - Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; + uint64_t resTemp; + Rd = resTemp = Rs1.udw<31:0> * Rs2_or_imm13.udw<31:0>; YValue = resTemp<63:32>;}}, {{0}},{{0}},{{0}},{{0}}); 0x1B: smulcc({{ - int64_t resTemp, val2 = Rs2_or_imm13; - Rd = resTemp = Rs1.sdw<31:0> * val2<31:0>; + int64_t resTemp; + Rd = resTemp = Rs1.sdw<31:0> * Rs2_or_imm13.sdw<31:0>; YValue = resTemp<63:32>;}}, {{0}},{{0}},{{0}},{{0}}); 0x1C: subccc({{ @@ -185,11 +185,11 @@ decode OP default Unknown::unknown() {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} ); 0x1D: udivxcc({{ - if(Rs2_or_imm13 == 0) fault = new DivisionByZero; - else Rd = Rs1.udw / Rs2_or_imm13;}} + if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero; + else Rd = Rs1.udw / Rs2_or_imm13.udw;}} ,{{0}},{{0}},{{0}},{{0}}); 0x1E: udivcc({{ - uint32_t resTemp, val2 = Rs2_or_imm13; + uint32_t resTemp, val2 = Rs2_or_imm13.udw; int32_t overflow; if(val2 == 0) fault = new DivisionByZero; else @@ -205,7 +205,7 @@ decode OP default Unknown::unknown() {{0}} ); 0x1F: sdivcc({{ - int32_t resTemp, val2 = Rs2_or_imm13; + int32_t resTemp, val2 = Rs2_or_imm13.sdw; int32_t overflow, underflow; if(val2 == 0) fault = new DivisionByZero; else @@ -363,8 +363,8 @@ decode OP default Unknown::unknown() } } 0x2D: sdivx({{ - if(Rs2_or_imm13 == 0) fault = new DivisionByZero; - else Rd.sdw = Rs1.sdw / Rs2_or_imm13; + if(Rs2_or_imm13.sdw == 0) fault = new DivisionByZero; + else Rd.sdw = Rs1.sdw / Rs2_or_imm13.sdw; }}); 0x2E: decode RS1 { 0x0: IntOp::popc({{ @@ -382,12 +382,12 @@ decode OP default Unknown::unknown() } 0x2F: decode RCOND3 { - 0x1: movreq({{Rd = (Rs1 == 0) ? Rs2_or_imm10 : Rd;}}); - 0x2: movrle({{Rd = (Rs1 <= 0) ? Rs2_or_imm10 : Rd;}}); - 0x3: movrl({{Rd = (Rs1 < 0) ? Rs2_or_imm10 : Rd;}}); - 0x5: movrne({{Rd = (Rs1 != 0) ? Rs2_or_imm10 : Rd;}}); - 0x6: movrg({{Rd = (Rs1 > 0) ? Rs2_or_imm10 : Rd;}}); - 0x7: movrge({{Rd = (Rs1 >= 0) ? Rs2_or_imm10 : Rd;}}); + 0x1: movreq({{Rd = (Rs1.sdw == 0) ? Rs2_or_imm10 : Rd;}}); + 0x2: movrle({{Rd = (Rs1.sdw <= 0) ? Rs2_or_imm10 : Rd;}}); + 0x3: movrl({{Rd = (Rs1.sdw < 0) ? Rs2_or_imm10 : Rd;}}); + 0x5: movrne({{Rd = (Rs1.sdw != 0) ? Rs2_or_imm10 : Rd;}}); + 0x6: movrg({{Rd = (Rs1.sdw > 0) ? Rs2_or_imm10 : Rd;}}); + 0x7: movrge({{Rd = (Rs1.sdw >= 0) ? Rs2_or_imm10 : Rd;}}); } 0x30: decode RD { 0x0: wry({{Y = Rs1 ^ Rs2_or_imm13;}}); @@ -492,10 +492,6 @@ decode OP default Unknown::unknown() xc->syscall(R1); #endif } - else - { - DPRINTF(Sparc, "Didn't fire on %s\n", CondTestAbbrev[machInst<25:28>]); - } }}); 0x2: Trap::tccx({{ if(passesCondition(CcrXcc, COND2)) |