summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/faults.cc10
-rw-r--r--arch/alpha/faults.hh20
-rw-r--r--arch/alpha/isa/decoder.isa2
-rw-r--r--arch/mips/faults.cc10
-rw-r--r--arch/mips/faults.hh20
-rw-r--r--arch/mips/isa/base.isa2
-rw-r--r--arch/mips/isa/bitfields.isa5
-rw-r--r--arch/mips/isa/decoder.isa860
-rw-r--r--arch/mips/isa/formats/branch.isa6
-rw-r--r--arch/mips/isa/formats/fp.isa60
-rw-r--r--arch/mips/isa/operands.isa31
-rw-r--r--arch/mips/isa_traits.cc108
-rw-r--r--arch/mips/isa_traits.hh10
-rw-r--r--arch/mips/regfile/float_regfile.hh159
-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.hh6
-rw-r--r--arch/sparc/faults.cc14
-rw-r--r--arch/sparc/faults.hh26
-rw-r--r--arch/sparc/isa/base.isa6
-rw-r--r--arch/sparc/isa/decoder.isa40
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 = &regs[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 &section);
+ };
+
+ 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 &section);
};
+
+ 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))