diff options
-rw-r--r-- | arch/mips/isa/bitfields.isa | 5 | ||||
-rw-r--r-- | arch/mips/isa/decoder.isa | 520 | ||||
-rw-r--r-- | arch/mips/isa_traits.cc | 103 | ||||
-rw-r--r-- | arch/mips/isa_traits.hh | 10 | ||||
-rw-r--r-- | arch/mips/regfile.hh | 6 | ||||
-rw-r--r-- | arch/mips/regfile/float_regfile.hh | 187 | ||||
-rw-r--r-- | arch/mips/regfile/int_regfile.hh (renamed from arch/mips/int_regfile.hh) | 0 | ||||
-rw-r--r-- | arch/mips/regfile/misc_regfile.hh (renamed from arch/mips/misc_regfile.hh) | 0 |
8 files changed, 666 insertions, 165 deletions
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..285ac21ae 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(CC) == 0) Rd = Rs}}); + 1: movt({{ if (getFPConditionCode(CC) == 1) Rd = Rs}}); } } @@ -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); } @@ -478,15 +476,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(CC) == 0); }}); + 0x1: bc1t({{ cond = (getFPConditionCode(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(CC) == 0); }}); + 0x1: bc1tl({{ cond = (getFPConditionCode(CC) == 1); }}); } } } @@ -500,51 +498,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), 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), 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 +550,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(CC) == 0) Fd = Fs;}}); + 0x1: movt_s({{if (getFPConditionCode(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 +585,167 @@ decode OPCODE_HI default Unknown::unknown() { }}); } } + + 0x6: decode FUNCTION_LO { + format FloatCompareOp { + 0x0: c_f_s({{ cond = 0; }}); + + 0x1: c_un_s({{ + if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + cond = 1; + else + cond = 0; + }}); + + 0x2: c_eq_s({{ + if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + cond = 0; + else + cond = (Fs.sf == Ft.sf); + }}); + + 0x3: c_ueq_s({{ + if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + cond = 1; + else + cond = (Fs.sf == Ft.sf); + }}); + + 0x4: c_olt_s({{ + if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + cond = 0; + else + cond = (Fs.sf < Ft.sf); + }}); + + 0x5: c_ult_s({{ + if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + cond = 1; + else + cond = (Fs.sf < Ft.sf); + }}); + + 0x6: c_ole_s({{ + if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + cond = 0; + else + cond = (Fs.sf <= Ft.sf); + }}); + + 0x7: c_ule_s({{ + if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + 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 (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + cond = 1; + else + cond = 0; + }}); + + 0x2: c_seq_s({{ + if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + cond = 0; + else + cond = (Fs.sf == Ft.sf); + }}); + + 0x3: c_ngl_s({{ + if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + cond = 1; + else + cond = (Fs.sf == Ft.sf); + }}); + + 0x4: c_lt_s({{ + if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + cond = 0; + else + cond = (Fs.sf < Ft.sf); + }}); + + 0x5: c_nge_s({{ + if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + cond = 1; + else + cond = (Fs.sf < Ft.sf); + }}); + + 0x6: c_le_s({{ + if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + cond = 0; + else + cond = (Fs.sf <= Ft.sf); + }}); + + 0x7: c_ngt_s({{ + if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + 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.ud), DOUBLE_TO_LONG); }}); 0x1: trunc_l_d({{ - Fd.ud = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_ZERO); + Fd.ud = fpConvert(truncFP(Fs.ud), DOUBLE_TO_LONG); }}); 0x2: ceil_l_d({{ - Fd.ud = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_UP); + Fd.ud = fpConvert(ceil(Fs.ud), DOUBLE_TO_LONG); }}); 0x3: floor_l_d({{ - Fd.ud = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_DOWN); + Fd.ud = fpConvert(floor(Fs.ud), 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.ud), DOUBLE_TO_WORD); }}); 0x5: trunc_w_d({{ - Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_ZERO); + Fd.uw = fpConvert(truncFP(Fs.ud), DOUBLE_TO_WORD); }}); 0x6: ceil_w_d({{ - Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_UP); + Fd.uw = fpConvert(ceil(Fs.ud), DOUBLE_TO_WORD); }}); 0x7: floor_w_d({{ - Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_DOWN); + Fd.uw = fpConvert(floor(Fs.ud), DOUBLE_TO_WORD); }}); } } @@ -652,56 +753,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(CC) == 0) Fd.df = Fs.df; }}); + 0x1: movt_d({{if (getFPConditionCode(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.ud, 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.ud, 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.ud, DOUBLE_TO_LONG); }}); } } + + 0x6: decode FUNCTION_LO { + format FloatCompareOp { + 0x0: c_f_d({{ cond = 0; }}); + + 0x1: c_un_d({{ + if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + cond = 1; + else + cond = 0; + }}); + + 0x2: c_eq_d({{ + if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + cond = 0; + else + cond = (Fs.df == Ft.df); + }}); + + 0x3: c_ueq_d({{ + if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + cond = 1; + else + cond = (Fs.df == Ft.df); + }}); + + 0x4: c_olt_d({{ + if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + cond = 0; + else + cond = (Fs.df < Ft.df); + }}); + + 0x5: c_ult_d({{ + if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + cond = 1; + else + cond = (Fs.df < Ft.df); + }}); + + 0x6: c_ole_d({{ + if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + cond = 0; + else + cond = (Fs.df <= Ft.df); + }}); + + 0x7: c_ule_d({{ + if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + 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 (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + cond = 1; + else + cond = 0; + }}); + + 0x2: c_seq_d({{ + if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + cond = 0; + else + cond = (Fs.df == Ft.df); + }}); + + 0x3: c_ngl_d({{ + if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + cond = 1; + else + cond = (Fs.df == Ft.df); + }}); + + 0x4: c_lt_d({{ + if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + cond = 0; + else + cond = (Fs.df < Ft.df); + }}); + + 0x5: c_nge_d({{ + if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + cond = 1; + else + cond = (Fs.df < Ft.df); + }}); + + 0x6: c_le_d({{ + if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + cond = 0; + else + cond = (Fs.df <= Ft.df); + }}); + + 0x7: c_ngt_d({{ + if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + 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 +919,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); + }}); + + 0x21: cvt_d_l({{ + Fd.ud = fpConvert(Fs.ud, LONG_TO_DOUBLE); }}); - 0x11: cvt_d_l({{ - int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.ud = convert_and_round(Fs.ud, LONG_TO_DOUBLE, rnd_mode); + 0x26: cvt_ps_l({{ + Fd.ud = fpConvert(Fs.ud, LONG_TO_PS); }}); } } @@ -729,33 +940,27 @@ 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 + 0x0: add_ps({{ Fd.df = Fs.df + Ft.df; }}); - 0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut + 0x1: sub_ps({{ Fd.df = Fs.df - Ft.df; }}); - 0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut + 0x2: mul_ps({{ Fd.df = Fs.df * Ft.df; }}); - 0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut + 0x5: abs_ps({{ Fd.df = fabs(Fs.df); }}); - 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({{ + Fd.df = Fs | Ft; }}); - 0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut + 0x7: neg_ps({{ Fd.df = -1 * Fs.df; }}); } @@ -764,31 +969,28 @@ 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(CC) == 0) Fd = Fs;}}); + 0x1: movt_ps({{if (getFPConditionCode(CC) == 1) Fd = Fs;}}); } } - 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(CC) == 0) Fd = Fs; }}); + 0x3: movn_ps({{if (getFPConditionCode(CC) == 1) Fd = Fs; }}); } } 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(Fs.ud, 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(Fs.ud, PL_TO_SINGLE); }}); 0x4: pll({{ Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<31:0>; }}); @@ -797,6 +999,33 @@ decode OPCODE_HI default Unknown::unknown() { 0x7: puu({{ Fd.ud = Fs.ud<63:32> << 32 | Ft.ud<63:32>;}}); } } + + 0x6: decode FUNCTION_LO { + format FloatOp { + 0x0: c_f_ps({{ ; }}); + 0x1: c_un_ps({{ ; }}); + 0x2: c_eq_ps({{ ; }}); + 0x3: c_ueq_ps({{ ; }}); + 0x4: c_olt_ps({{ ; }}); + 0x5: c_ult_ps({{ ; }}); + 0x6: c_ole_ps({{ ; }}); + 0x7: c_ule_ps({{ ; }}); + } + } + + 0x7: decode FUNCTION_LO { + format FloatOp { + 0x0: c_sf_ps({{ ; }}); + 0x1: c_ngle_ps({{ ; }}); + 0x2: c_seq_ps({{ ; }}); + 0x3: c_ngl_ps({{ ; }}); + 0x4: c_lt_ps({{ ; }}); + 0x5: c_nge_ps({{ ; }}); + 0x6: c_le_ps({{ ; }}); + 0x7: c_ngt_ps({{ ; }}); + } + } + } } } @@ -840,23 +1069,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(); @@ -870,8 +1093,6 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }}); 0x1: madd_d({{ Fd.df = (Fs.df * Fs.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; }}); } @@ -880,8 +1101,6 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }}); 0x1: msub_d({{ Fd.df = (Fs.df * Fs.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; }}); } @@ -890,8 +1109,6 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }}); 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.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; }}); } @@ -900,8 +1117,6 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }}); 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.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; }}); } @@ -909,7 +1124,6 @@ decode OPCODE_HI default Unknown::unknown() { } } - //MIPS obsolete instructions format BranchLikely { 0x4: beql({{ cond = (Rs.sw == 0); }}); 0x5: bnel({{ cond = (Rs.sw != 0); }}); @@ -960,25 +1174,29 @@ decode OPCODE_HI default Unknown::unknown() { 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; }}); } } @@ -1033,8 +1251,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 +1276,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: @@ -1274,7 +1488,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 +1498,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_traits.cc b/arch/mips/isa_traits.cc index fcc3007ca..4eb14c66d 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -122,20 +122,113 @@ MipsISA::convert_and_round(uint64_t fp_val, ConvertType cvt_type, int rnd_mode) uint64_t MipsISA::convert_and_round(double fp_val, ConvertType cvt_type, int rnd_mode) { + 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; + 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); + panic("Invalid Floating Point Conversion Type (%d). See types.hh for Conversion List\n",cvt_type); return 0; } } +uint64_t +MipsISA::fpConvert(double fp_val, ConvertType cvt_type) +{ + + switch (cvt_type) + { + case SINGLE_TO_DOUBLE: + 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). See \"types.hh\" for List of Conversions\n",cvt_type); + return 0; + } +} + +double +MipsISA::roundFP(double val) +{ + double trunc_val = trunc(val); + double fraction = val - trunc_val; + + if (fraction < 0.5) + return val; + else + return val + 1; +} + +inline double +MipsISA::truncFP(double val) +{ + int trunc_val = (int) val; + return (double) trunc_val; +} + +bool +MipsISA::unorderedFP(uint32_t val) +{ +} + +bool +MipsISA::unorderedFP(uint64_t val) +{ +} + +bool +MipsISA::getConditionCode(int cc) +{ +} + +void +MipsISA::setConditionCode(int num, bool val) +{ +} #if FULL_SYSTEM diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 33c490dcc..d009bbea5 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -137,9 +137,13 @@ 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); + inline double truncFP(double val); + bool unorderedFP(uint32_t val); + bool unorderedFP(uint64_t val); + bool getConditionCode(int cc); + void setConditionCode(int num, bool val); // Machine operations diff --git a/arch/mips/regfile.hh b/arch/mips/regfile.hh index 3dcf8ef18..bd825d479 100644 --- a/arch/mips/regfile.hh +++ b/arch/mips/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; diff --git a/arch/mips/regfile/float_regfile.hh b/arch/mips/regfile/float_regfile.hh new file mode 100644 index 000000000..308d418a0 --- /dev/null +++ b/arch/mips/regfile/float_regfile.hh @@ -0,0 +1,187 @@ +/* + * 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]; + FloatReg32 fir; + FloatReg32 fcsr; + + FloatReg32 fpcr; + + FloatReg32 fccr; + FloatReg32 fexr; + FloatReg32 fenr; + + public: + + void clear() + { + bzero(regs, sizeof(regs)); + } + + double readReg(int floatReg, int width) + { + using namespace std; + + 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) + { + 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); + } + } + + 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; + } + + MiscReg readFIR() + { + return fir; + } + + Fault setFIR(const MiscReg &val) + { + fir = val; + return NoFault; + } + + MiscReg readFCSR() + { + return fcsr; + } + + Fault setFCSR(const MiscReg &val) + { + fcsr = val; + return NoFault; + } + + MiscReg readFPCR() + { + return fpcr; + } + + Fault setFPCR(const MiscReg &val) + { + fpcr = val; + return NoFault; + } + + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); + }; + +} // namespace MipsISA + +#endif diff --git a/arch/mips/int_regfile.hh b/arch/mips/regfile/int_regfile.hh index cff9eb0d2..cff9eb0d2 100644 --- a/arch/mips/int_regfile.hh +++ b/arch/mips/regfile/int_regfile.hh 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 |