diff options
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/isa/decoder.isa | 291 | ||||
-rw-r--r-- | arch/mips/isa/formats/fp.isa | 4 | ||||
-rw-r--r-- | arch/mips/isa/formats/mem.isa | 26 | ||||
-rw-r--r-- | arch/mips/isa/formats/util.isa | 21 | ||||
-rw-r--r-- | arch/mips/isa_traits.cc | 31 | ||||
-rw-r--r-- | arch/mips/isa_traits.hh | 170 |
6 files changed, 376 insertions, 167 deletions
diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 077f0afd0..6feaec7cb 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -394,36 +394,82 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode RS_HI { 0x0: decode RS_LO { - format WarnUnimpl { - 0x0: mfc1();//{{ /*Rt.uw = Fs.ud<31:0>;*/ }} - 0x3: mfhc1();// /*Rt.uw = Fs.ud<63:32>*/; - 0x4: mtc1();// /*Fs = Rt.uw*/ - 0x7: mthc1();//{{/*Fs<63:32> = Rt.uw*/}} + format FloatOp { + 0x0: mfc1 ({{ Rt.uw = Fs.uw<31:0>; }}); + 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_lo = Fs.ud & 0x0000FFFF; + Fs.ud = fs_hi & fs_lo; + }}); } format System { 0x2: cfc1({{ uint32_t fcsr_reg = xc->readMiscReg(FCSR); - if (Fs == 0){ + switch (FS) + { + case 0: Rt = xc->readMiscReg(FIR); - } else if (Fs == 25) { + break; + case 25: Rt = 0 | (fcsr_reg & 0xFE000000) >> 24 | (fcsr_reg & 0x00800000) >> 23; - } else if (Fs == 26) { + break; + case 26: Rt = 0 | (fcsr_reg & 0x0003F07C); - } else if (Fs == 28) { + break; + case 28: Rt = 0 | (fcsr_reg); - } else if (Fs == 31) { + break; + case 31: Rt = fcsr_reg; - } else { + break; + default: panic("FP Control Value (%d) Not Available. Ignoring Access to" "Floating Control Status Register",fcsr_reg); } - }}); 0x6: ctc1({{ - /*xc->setMiscReg(FPCR[Fs],Rt);*/ + 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 + break; + + case 26: + temp = 0 | (fcsr_reg & 0xFFFC0000) // move 31...18 + | Rt.uw<17:12> << 12 // bit 17...12 + | (fcsr_reg & 0x00000F80) << 7// bit 11...7 + | Rt.uw<6:2> << 2 // bit 6...2 + | (fcsr_reg & 0x00000002); // bit 1...0 + break; + + case 28: + temp = 0 | (fcsr_reg & 0xFE000000) // move 31...25 + | Rt.uw<2:2> << 24 // bit 24 + | (fcsr_reg & 0x00FFF000) << 23// bit 23...12 + | Rt.uw<11:7> << 7 // bit 24 + | (fcsr_reg & 0x000007E) + | Rt.uw<1:0>;// bit 22...0 + break; + + case 31: + temp = Rt.uw; + break; + + default: + panic("FP Control Value (%d) Not Available. Ignoring Access to" + "Floating Control Status Register",fcsr_reg); + } + + xc->setMiscReg(FCSR,temp); }}); } } @@ -450,8 +496,8 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S //(( single-word )) - 0x0: decode RS_HI { - 0x0: decode RS_LO { + 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;}}); @@ -464,24 +510,45 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x1: decode RS_LO { - //only legal for 64 bit-FP + 0x1: decode FUNCTION_LO { 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); + }}); } } - 0x2: decode RS_LO { + 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { format FloatOp { 0x0: movfs({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }}); @@ -500,32 +567,37 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x4: decode RS_LO { + 0x4: decode FUNCTION_LO { format FloatOp { - 0x1: cvt_d_s({{ int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE); + 0x1: cvt_d_s({{ + 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); + 0x4: cvt_w_s({{ + 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); + 0x5: cvt_l_s({{ + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd.uw = convert_and_round(Fs.ud, SINGLE_TO_LONG, rnd_mode); }}); - 0x6: cvt_ps_s({{ /*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; + }}); } } } //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D - 0x1: decode RS_HI { - 0x0: decode RS_LO { + 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;}}); @@ -538,24 +610,45 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x1: decode RS_LO { - //only legal for 64 bit + 0x1: decode FUNCTION_LO { 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); + }}); } } - 0x2: decode RS_LO { + 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { format FloatOp { 0x0: movfd({{if (xc->readMiscReg(FPCR) != CC) Fd.df = Fs.df; }}); @@ -574,24 +667,24 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x4: decode RS_LO { + 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); }}); } } @@ -600,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); }}); } } @@ -616,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); }}); } } @@ -632,8 +725,8 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1 //Note: "1. Format type PS is legal only if 64-bit floating point operations //are enabled. " - 0x6: decode RS_HI { - 0x0: decode RS_LO { + 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 @@ -667,7 +760,7 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x2: decode RS_LO { + 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { format Float64Op { 0x0: movfps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs;}}); @@ -682,23 +775,25 @@ decode OPCODE_HI default Unknown::unknown() { } - 0x4: decode RS_LO { + 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 RS_LO { + 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>;}}); } } } @@ -743,24 +838,24 @@ decode OPCODE_HI default Unknown::unknown() { //operations are enabled." 0x3: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { - format LoadMemory2 { - 0x0: lwxc1({{ EA = Rs + Rt; }},{{ /*F_t<31:0> = Mem.sf; */}}); - 0x1: ldxc1({{ EA = Rs + Rt; }},{{ /*F_t<63:0> = Mem.df;*/ }}); - 0x5: luxc1({{ //Need to make EA<2:0> = 0 - EA = Rs + Rt; - }}, - {{ /*F_t<31:0> = Mem.df; */}}); + 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; + }}); } } 0x1: decode FUNCTION_LO { - format StoreMemory2 { - 0x0: swxc1({{ EA = Rs + Rt; }},{{ /*Mem.sf = Ft<31:0>; */}}); - 0x1: sdxc1({{ EA = Rs + Rt; }},{{ /*Mem.df = Ft<63:0> */}}); - 0x5: suxc1({{ //Need to make EA<2:0> = 0 - EA = Rs + Rt; - }}, - {{ /*Mem.df = F_t<63:0>;*/}}); + 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; + }}); } 0x7: WarnUnimpl::prefx(); @@ -1180,9 +1275,9 @@ decode OPCODE_HI default Unknown::unknown() { 0x6: decode OPCODE_LO default FailUnimpl::reserved() { 0x0: FailUnimpl::ll(); - format LoadMemory { - 0x1: lwc1({{ /*F_t<31:0> = Mem.sf; */}}); - 0x5: ldc1({{ /*F_t<63:0> = Mem.df; */}}); + format LoadFloatMemory { + 0x1: lwc1({{ Ft.uw = Mem.uw; }}); + 0x5: ldc1({{ Ft.ud = Mem.ud; }}); } } @@ -1190,9 +1285,9 @@ decode OPCODE_HI default Unknown::unknown() { 0x7: decode OPCODE_LO default FailUnimpl::reserved() { 0x0: FailUnimpl::sc(); - format StoreMemory { - 0x1: swc1({{ //Mem.sf = Ft<31:0>; }}); - 0x5: sdc1({{ //Mem.df = Ft<63:0>; }}); + format StoreFloatMemory { + 0x1: swc1({{ Mem.uw = Ft.uw; }}); + 0x5: sdc1({{ Mem.ud = Ft.ud; }}); } } } diff --git a/arch/mips/isa/formats/fp.isa b/arch/mips/isa/formats/fp.isa index 34b71acf7..65b259e20 100644 --- a/arch/mips/isa/formats/fp.isa +++ b/arch/mips/isa/formats/fp.isa @@ -30,7 +30,7 @@ output decoder {{ }}; -// Primary format for integer operate instructions: +// Primary format for float operate instructions: def format FloatOp(code, *flags) {{ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) @@ -39,7 +39,7 @@ def format FloatOp(code, *flags) {{ exec_output = BasicExecute.subst(iop) }}; -// Primary format for integer operate instructions: +// Primary format for float64 operate instructions: def format Float64Op(code, *flags) {{ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) diff --git a/arch/mips/isa/formats/mem.isa b/arch/mips/isa/formats/mem.isa index df1dca4e1..e2afc7252 100644 --- a/arch/mips/isa/formats/mem.isa +++ b/arch/mips/isa/formats/mem.isa @@ -446,30 +446,28 @@ def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, exec_template_base = 'Store') }}; -def format UnalignedStore(memacc_code, postacc_code, - ea_code = {{ EA = Rb + disp; }}, +//FP loads are offloaded to these formats for now ... +def format LoadFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, mem_flags = [], inst_flags = []) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, - postacc_code, exec_template_base = 'Store') + decode_template = BasicDecode, + exec_template_base = 'Load') }}; -//FP loads are offloaded to these formats for now ... -def format LoadMemory2(ea_code = {{ EA = Rs + disp; }}, memacc_code = {{ }}, - mem_flags = [], inst_flags = []) {{ + +def format StoreFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, + mem_flags = [], inst_flags = []) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, - decode_template = LoadNopCheckDecode, - exec_template_base = 'Load') + exec_template_base = 'Store') }}; -//FP stores are offloaded to these formats for now ... -def format StoreMemory2(ea_code = {{ EA = Rs + disp; }},memacc_code = {{ }}, - mem_flags = [], inst_flags = []) {{ +def format UnalignedStore(memacc_code, postacc_code, + ea_code = {{ EA = Rb + disp; }}, + mem_flags = [], inst_flags = []) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, - decode_template = LoadNopCheckDecode, - exec_template_base = 'Store') + postacc_code, exec_template_base = 'Store') }}; - diff --git a/arch/mips/isa/formats/util.isa b/arch/mips/isa/formats/util.isa index dcdf46757..615160931 100644 --- a/arch/mips/isa/formats/util.isa +++ b/arch/mips/isa/formats/util.isa @@ -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 - }; }}; diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc index c6cfb2a0f..d23cdf367 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -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) diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 1f4ccbd90..3ea72bde2 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -30,8 +30,10 @@ #define __ARCH_MIPS_ISA_TRAITS_HH__ //#include "arch/mips/misc_regfile.hh" +#include "arch/mips/faults.hh" #include "base/misc.hh" #include "config/full_system.hh" +#include "sim/byteswap.hh" #include "sim/host.hh" #include "sim/faults.hh" @@ -105,7 +107,7 @@ namespace MipsISA const int NumPALShadowRegs = 8; const int NumFloatArchRegs = 32; // @todo: Figure out what this number really should be. - const int NumMiscArchRegs = 32; + const int NumMiscArchRegs = 265; const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs; const int NumFloatRegs = NumFloatArchRegs; @@ -189,63 +191,166 @@ namespace MipsISA typedef double FloatReg; typedef uint64_t FloatRegBits; + + const int SingleWidth = 32; + const int SingleBytes = SingleWidth / 4; + + const int DoubleWidth = 64; + const int DoubleBytes = DoubleWidth / 4; + + const int QuadWidth = 128; + const int QuadBytes = QuadWidth / 4; + + const int FloatRegSize = SingleWidth / SingleBytes; + const int DoubleRegSize = FloatRegSize * 2; + class FloatRegFile { protected: - FloatRegBits q[NumFloatRegs]; // integer qword view - double d[NumFloatRegs]; // double-precision floating point view + //Since the floating point registers overlap each other, + //A generic storage space is used. The float to be returned is + //pulled from the appropriate section of this region. + char regSpace[FloatRegSize * NumFloatRegs]; public: - FloatReg readReg(int floatReg) + void clear() { - return d[floatReg]; + bzero(regSpace, sizeof(regSpace)); } FloatReg readReg(int floatReg, int width) { - return readReg(floatReg); - } + //In each of these cases, we have to copy the value into a temporary + //variable. This is because we may otherwise try to access an + //unaligned portion of memory. + switch(width) + { + case SingleWidth: + float result32; + memcpy(&result32, regSpace + 4 * floatReg, FloatRegSize); + return htog(result32); - FloatRegBits readRegBits(int floatReg) - { - return q[floatReg]; + case DoubleWidth: + double result64; + memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize); + return htog(result64); + + default: + panic("Attempted to read a %d bit floating point register!", width); + } } FloatRegBits readRegBits(int floatReg, int width) { - return readRegBits(floatReg); - } + //In each of these cases, we have to copy the value into a temporary + //variable. This is because we may otherwise try to access an + //unaligned portion of memory. + switch(width) + { + case SingleWidth: + uint32_t result32; + memcpy(&result32, regSpace + 4 * floatReg, FloatRegSize); + return htog(result32); - Fault setReg(int floatReg, const FloatReg &val) - { - d[floatReg] = val; - return NoFault; - } + case DoubleWidth: + uint64_t result64; + memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize); + return htog(result64); - Fault setReg(int floatReg, const FloatReg &val, int width) - { - return setReg(floatReg, val); + default: + panic("Attempted to read a %d bit floating point register!", width); + } } - Fault setRegBits(int floatReg, const FloatRegBits &val) + Fault setReg(int floatReg, const FloatReg &val, int width) { - q[floatReg] = val; + //In each of these cases, we have to copy the value into a temporary + //variable. This is because we may otherwise try to access an + //unaligned portion of memory. + switch(width) + { + case SingleWidth: + uint32_t result32; + result32 = gtoh((uint32_t)val); + memcpy(regSpace + 4 * floatReg, &result32, FloatRegSize); + break; + + case DoubleWidth: + uint64_t result64; + result64 = gtoh((uint64_t)val); + memcpy(regSpace + 4 * floatReg, &result64, DoubleRegSize); + break; + + + default: + panic("Attempted to read a %d bit floating point register!", width); + } return NoFault; } Fault setRegBits(int floatReg, const FloatRegBits &val, int width) { - return setRegBits(floatReg, val); + //In each of these cases, we have to copy the value into a temporary + //variable. This is because we may otherwise try to access an + //unaligned portion of memory. + switch(width) + { + case SingleWidth: + uint32_t result32; + result32 = gtoh((uint32_t)val); + memcpy(regSpace + 4 * floatReg, &result32, FloatRegSize); + break; + + case DoubleWidth: + uint64_t result64; + result64 = gtoh((uint64_t)val); + memcpy(regSpace + 4 * floatReg, &result64, DoubleRegSize); + break; + + default: + panic("Attempted to read a %d bit floating point register!", width); + } + return NoFault; } void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); - }; + enum 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); // cop-0/cop-1 system control register file @@ -532,44 +637,45 @@ extern const Addr PageOffset; return miscRegFile.setRegWithEffect(miscReg, val, xc); } + FloatReg readFloatReg(int floatReg) { - return floatRegFile.readReg(floatReg); + return floatRegFile.readReg(floatReg,SingleWidth); } FloatReg readFloatReg(int floatReg, int width) { - return readFloatReg(floatReg); + return floatRegFile.readReg(floatReg,width); } FloatRegBits readFloatRegBits(int floatReg) { - return floatRegFile.readRegBits(floatReg); + return floatRegFile.readRegBits(floatReg,SingleWidth); } FloatRegBits readFloatRegBits(int floatReg, int width) { - return readFloatRegBits(floatReg); + return floatRegFile.readRegBits(floatReg,width); } Fault setFloatReg(int floatReg, const FloatReg &val) { - return floatRegFile.setReg(floatReg, val); + return floatRegFile.setReg(floatReg, val, SingleWidth); } Fault setFloatReg(int floatReg, const FloatReg &val, int width) { - return setFloatReg(floatReg, val); + return floatRegFile.setReg(floatReg, val, width); } Fault setFloatRegBits(int floatReg, const FloatRegBits &val) { - return floatRegFile.setRegBits(floatReg, val); + return floatRegFile.setRegBits(floatReg, val, SingleWidth); } Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width) { - return setFloatRegBits(floatReg, val); + return floatRegFile.setRegBits(floatReg, val, width); } IntReg readIntReg(int intReg) |