Use lower two bits of FCSR reg to determine rounding mode (may want to move this out of decoder.isa and into a template)
Have FP conversion instructions use re-defined convert_and_round() function
arch/mips/isa/decoder.isa:
Use lower two bits of FCSR reg to determine rounding mode (may want to move this out of decoder.isa and into a template)
Have FP conversion instructions to use re-defined convert_and_round() function
arch/mips/isa/formats/util.isa:
Remove convert_and_round function from here
arch/mips/isa_traits.cc:
Define convert_and_round function here
arch/mips/isa_traits.hh:
Use "enums" to define FP conversion types & Round Modes
Declare convert_and_round function here
--HG--
extra : convert_revision : 0f4f8c1732a53b277361559ea71af2a1feb4fc64
This commit is contained in:
@@ -511,19 +511,40 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
}
|
||||
|
||||
0x1: decode FUNCTION_LO {
|
||||
//only legal for 64 bit-FP
|
||||
format Float64Op {
|
||||
0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}});
|
||||
0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}});
|
||||
0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}});
|
||||
0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}});
|
||||
0x0: round_l_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_NEAREST);
|
||||
}});
|
||||
|
||||
0x1: trunc_l_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_ZERO);
|
||||
}});
|
||||
|
||||
0x2: ceil_l_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_UP);
|
||||
}});
|
||||
|
||||
0x3: floor_l_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_DOWN);
|
||||
}});
|
||||
}
|
||||
|
||||
format FloatOp {
|
||||
0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}});
|
||||
0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}});
|
||||
0x6: ceil_w_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}});
|
||||
0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}});
|
||||
0x4: round_w_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_NEAREST);
|
||||
}});
|
||||
|
||||
0x5: trunc_w_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_ZERO);
|
||||
}});
|
||||
|
||||
0x6: ceil_w_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_UP);
|
||||
}});
|
||||
|
||||
0x7: floor_w_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_DOWN);
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -550,26 +571,25 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
|
||||
format FloatOp {
|
||||
0x1: cvt_d_s({{
|
||||
//int rnd_mode = xc->readMiscReg(FCSR);
|
||||
Fd = convert_and_round(,DOUBLE_TO_SINGLE);
|
||||
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
|
||||
Fd.uw = convert_and_round(Fs.ud, SINGLE_TO_DOUBLE, rnd_mode);
|
||||
}});
|
||||
|
||||
0x4: cvt_w_s({{
|
||||
//int rnd_mode = xc->readMiscReg(FCSR);
|
||||
Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE);
|
||||
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
|
||||
Fd.uw = convert_and_round(Fs.uw, SINGLE_TO_WORD, rnd_mode);
|
||||
}});
|
||||
}
|
||||
|
||||
//only legal for 64 bit
|
||||
format Float64Op {
|
||||
0x5: cvt_l_s({{
|
||||
//int rnd_mode = xc->readMiscReg(FCSR);
|
||||
Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE);
|
||||
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
|
||||
Fd.uw = convert_and_round(Fs.ud, SINGLE_TO_LONG, rnd_mode);
|
||||
}});
|
||||
|
||||
0x6: cvt_ps_s({{
|
||||
//int rnd_mode = xc->readMiscReg(FCSR);
|
||||
/*Fd.df = Fs.df<31:0> | Ft.df<31:0>;*/
|
||||
0x6: cvt_ps_st({{
|
||||
Fd.ud = (uint64_t)Fs.uw << 32 | (uint64_t)Ft.uw;
|
||||
}});
|
||||
}
|
||||
}
|
||||
@@ -591,19 +611,40 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
}
|
||||
|
||||
0x1: decode FUNCTION_LO {
|
||||
//only legal for 64 bit
|
||||
format Float64Op {
|
||||
0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
|
||||
0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}});
|
||||
0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}});
|
||||
0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}});
|
||||
0x0: round_l_d({{
|
||||
Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_NEAREST);
|
||||
}});
|
||||
|
||||
0x1: trunc_l_d({{
|
||||
Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_ZERO);
|
||||
}});
|
||||
|
||||
0x2: ceil_l_d({{
|
||||
Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_UP);
|
||||
}});
|
||||
|
||||
0x3: floor_l_d({{
|
||||
Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_DOWN);
|
||||
}});
|
||||
}
|
||||
|
||||
format FloatOp {
|
||||
0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
|
||||
0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }});
|
||||
0x6: ceil_w_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }});
|
||||
0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }});
|
||||
0x4: round_w_d({{
|
||||
Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_NEAREST);
|
||||
}});
|
||||
|
||||
0x5: trunc_w_d({{
|
||||
Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_ZERO);
|
||||
}});
|
||||
|
||||
0x6: ceil_w_d({{
|
||||
Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_UP);
|
||||
}});
|
||||
|
||||
0x7: floor_w_d({{
|
||||
Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_DOWN);
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,21 +670,21 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
0x4: decode FUNCTION_LO {
|
||||
format FloatOp {
|
||||
0x0: cvt_s_d({{
|
||||
int rnd_mode = xc->readMiscReg(FCSR);
|
||||
Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE);
|
||||
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
|
||||
Fd = convert_and_round(Fs.ud, DOUBLE_TO_SINGLE, rnd_mode);
|
||||
}});
|
||||
|
||||
0x4: cvt_w_d({{
|
||||
int rnd_mode = xc->readMiscReg(FCSR);
|
||||
Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE);
|
||||
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
|
||||
Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, rnd_mode);
|
||||
}});
|
||||
}
|
||||
|
||||
//only legal for 64 bit
|
||||
format Float64Op {
|
||||
0x5: cvt_l_d({{
|
||||
int rnd_mode = xc->readMiscReg(FCSR);
|
||||
Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE);
|
||||
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
|
||||
Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, rnd_mode);
|
||||
}});
|
||||
}
|
||||
}
|
||||
@@ -652,14 +693,14 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
//Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
|
||||
0x4: decode FUNCTION {
|
||||
format FloatOp {
|
||||
0x20: cvt_s({{
|
||||
int rnd_mode = xc->readMiscReg(FCSR);
|
||||
Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD);
|
||||
0x20: cvt_s_w({{
|
||||
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
|
||||
Fd = convert_and_round(Fs.uw, WORD_TO_SINGLE, rnd_mode);
|
||||
}});
|
||||
|
||||
0x21: cvt_d({{
|
||||
int rnd_mode = xc->readMiscReg(FCSR);
|
||||
Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD);
|
||||
0x21: cvt_d_w({{
|
||||
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
|
||||
Fd = convert_and_round(Fs.uw, WORD_TO_DOUBLE, rnd_mode);
|
||||
}});
|
||||
}
|
||||
}
|
||||
@@ -668,15 +709,15 @@ 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 FloatOp {
|
||||
format Float64Op {
|
||||
0x10: cvt_s_l({{
|
||||
int rnd_mode = xc->readMiscReg(FCSR);
|
||||
Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG);
|
||||
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
|
||||
Fd = convert_and_round(Fs.ud, LONG_TO_SINGLE, rnd_mode);
|
||||
}});
|
||||
|
||||
0x11: cvt_d_l({{
|
||||
int rnd_mode = xc->readMiscReg(FCSR);
|
||||
Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG);
|
||||
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
|
||||
Fd = convert_and_round(Fs.ud, LONG_TO_DOUBLE, rnd_mode);
|
||||
}});
|
||||
}
|
||||
}
|
||||
@@ -736,21 +777,23 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
|
||||
0x4: decode FUNCTION_LO {
|
||||
0x0: Float64Op::cvt_s_pu({{
|
||||
int rnd_mode = xc->readMiscReg(FCSR);
|
||||
Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI);
|
||||
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
|
||||
Fd = convert_and_round(Fs.ud, PUPPER_TO_SINGLE, rnd_mode);
|
||||
}});
|
||||
}
|
||||
|
||||
0x5: decode FUNCTION_LO {
|
||||
format Float64Op {
|
||||
0x0: cvt_s_pl({{
|
||||
int rnd_mode = xc->readMiscReg(FCSR);
|
||||
Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO);
|
||||
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
|
||||
Fd = convert_and_round(Fs.ud, PLOWER_TO_SINGLE,
|
||||
rnd_mode);
|
||||
}});
|
||||
0x4: pll({{ /*Fd.df = Fs<31:0> | Ft<31:0>*/}});
|
||||
0x5: plu({{ /*Fd.df = Fs<31:0> | Ft<63:32>*/}});
|
||||
0x6: pul({{ /*Fd.df = Fs<63:32> | Ft<31:0>*/}});
|
||||
0x7: puu({{ /*Fd.df = Fs<63:32 | Ft<63:32>*/}});
|
||||
|
||||
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>;}});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,9 +95,6 @@ output exec {{
|
||||
|
||||
using namespace MipsISA;
|
||||
|
||||
|
||||
|
||||
|
||||
/// CLEAR ALL CPU INST/EXE HAZARDS
|
||||
inline void
|
||||
clear_exe_inst_hazards()
|
||||
@@ -126,25 +123,7 @@ output exec {{
|
||||
}
|
||||
#endif
|
||||
|
||||
double convert_and_round(float w, int x, int y, int z)
|
||||
{
|
||||
double temp = .34000;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
enum FPTypes{
|
||||
FP_SINGLE,
|
||||
FP_DOUBLE,
|
||||
FP_LONG,
|
||||
FP_PS_LO,
|
||||
FP_PS_HI,
|
||||
FP_WORD,
|
||||
RND_NEAREST,
|
||||
RND_ZERO,
|
||||
RND_UP,
|
||||
RND_DOWN
|
||||
};
|
||||
}};
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,38 @@
|
||||
|
||||
using namespace MipsISA;
|
||||
|
||||
uint64_t
|
||||
MipsISA::convert_and_round(uint64_t fp_val, ConvertType cvt_type, int rnd_mode)
|
||||
{
|
||||
uint64_t ret_val = 0;
|
||||
|
||||
switch (cvt_type)
|
||||
{
|
||||
case SINGLE_TO_DOUBLE:
|
||||
break;
|
||||
|
||||
case SINGLE_TO_WORD:
|
||||
break;
|
||||
|
||||
case SINGLE_TO_LONG:
|
||||
break;
|
||||
|
||||
case DOUBLE_TO_SINGLE:
|
||||
|
||||
break;
|
||||
|
||||
case LONG_TO_SINGLE:
|
||||
break;
|
||||
|
||||
case WORD_TO_SINGLE:
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("Invalid Floating Point Conversion type being used.\n");
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
void
|
||||
MipsISA::copyRegs(ExecContext *src, ExecContext *dest)
|
||||
|
||||
@@ -315,13 +315,41 @@ namespace MipsISA
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
enum ConvertType{
|
||||
SINGLE_TO_DOUBLE,
|
||||
SINGLE_TO_WORD,
|
||||
SINGLE_TO_LONG,
|
||||
|
||||
DOUBLE_TO_SINGLE,
|
||||
DOUBLE_TO_WORD,
|
||||
DOUBLE_TO_LONG,
|
||||
|
||||
LONG_TO_SINGLE,
|
||||
LONG_TO_DOUBLE,
|
||||
LONG_TO_WORD,
|
||||
|
||||
WORD_TO_SINGLE,
|
||||
WORD_TO_DOUBLE,
|
||||
WORD_TO_LONG,
|
||||
|
||||
PLOWER_TO_SINGLE,
|
||||
PUPPER_TO_SINGLE
|
||||
};
|
||||
|
||||
enum RoundMode{
|
||||
RND_ZERO,
|
||||
RND_DOWN,
|
||||
RND_UP,
|
||||
RND_NEAREST
|
||||
};
|
||||
|
||||
uint64_t convert_and_round(uint64_t fp_val,ConvertType cvt_type, int rnd_mode = 0);
|
||||
|
||||
|
||||
void copyRegs(ExecContext *src, ExecContext *dest);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user