Start working on more complex FP tests
Debug FP instructions to handle these FP insts
arch/mips/isa/bitfields.isa:
add Bitfield for Floating Point Condition Codes
arch/mips/isa/decoder.isa:
Follow instruction naming style with FP single insts
Send the float value to the convert&round functions in single FP
add ll inst support
add 'token' sc support
arch/mips/isa_traits.cc:
Add SINGLE->WORD, WORD->SINGLE, & WORD->DOUBLE conversions
arch/mips/regfile.hh:
update header files
arch/mips/regfile/float_regfile.hh:
Add more FP registers
--HG--
rename : arch/mips/int_regfile.hh => arch/mips/regfile/int_regfile.hh
rename : arch/mips/misc_regfile.hh => arch/mips/regfile/misc_regfile.hh
extra : convert_revision : 92faf0bfd8542ade762ac569ec158d198f6a9c7e
This commit is contained in:
@@ -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>;
|
||||
|
||||
|
||||
@@ -500,51 +500,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 = convert_and_round(Fs.sf, SINGLE_TO_LONG, RND_NEAREST);
|
||||
}});
|
||||
|
||||
0x1: trunc_l_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_ZERO);
|
||||
Fd.ud = convert_and_round(Fs.sf, SINGLE_TO_LONG, RND_ZERO);
|
||||
}});
|
||||
|
||||
0x2: ceil_l_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_UP);
|
||||
Fd.ud = convert_and_round(Fs.sf, SINGLE_TO_LONG, RND_UP);
|
||||
}});
|
||||
|
||||
0x3: floor_l_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_DOWN);
|
||||
Fd.ud = convert_and_round(Fs.sf, SINGLE_TO_LONG, RND_DOWN);
|
||||
}});
|
||||
}
|
||||
|
||||
format FloatOp {
|
||||
0x4: round_w_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_NEAREST);
|
||||
Fd.uw = convert_and_round(Fs.sf, SINGLE_TO_WORD, RND_NEAREST);
|
||||
}});
|
||||
|
||||
0x5: trunc_w_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_ZERO);
|
||||
Fd.uw = convert_and_round(Fs.sf, SINGLE_TO_WORD, RND_ZERO);
|
||||
}});
|
||||
|
||||
0x6: ceil_w_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_UP);
|
||||
Fd.uw = convert_and_round(Fs.sf, SINGLE_TO_WORD, RND_UP);
|
||||
}});
|
||||
|
||||
0x7: floor_w_s({{
|
||||
Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_DOWN);
|
||||
Fd.uw = convert_and_round(Fs.sf, SINGLE_TO_WORD, RND_DOWN);
|
||||
}});
|
||||
}
|
||||
}
|
||||
@@ -578,7 +578,7 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
|
||||
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 = convert_and_round(Fs.sf, SINGLE_TO_WORD, rnd_mode);
|
||||
}});
|
||||
}
|
||||
|
||||
@@ -586,7 +586,7 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
format Float64Op {
|
||||
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 = convert_and_round(Fs.sf, SINGLE_TO_LONG, rnd_mode);
|
||||
}});
|
||||
|
||||
0x6: cvt_ps_st({{
|
||||
@@ -696,12 +696,12 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
format FloatOp {
|
||||
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 = convert_and_round(Fs.sf, WORD_TO_SINGLE, rnd_mode);
|
||||
}});
|
||||
|
||||
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 = convert_and_round(Fs.sf, WORD_TO_DOUBLE, rnd_mode);
|
||||
}});
|
||||
}
|
||||
}
|
||||
@@ -1033,8 +1033,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 +1058,6 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
panic("lwl: bad offset");
|
||||
}
|
||||
#elif BYTE_ORDER == LITTLE_ENDIAN
|
||||
std::cout << "Little Endian Byte Order\n";
|
||||
|
||||
switch(offset)
|
||||
{
|
||||
case 0:
|
||||
@@ -1274,7 +1270,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 +1280,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; }});
|
||||
|
||||
@@ -122,16 +122,35 @@ MipsISA::convert_and_round(uint64_t fp_val, ConvertType cvt_type, int rnd_mode)
|
||||
uint64_t
|
||||
MipsISA::convert_and_round(double fp_val, ConvertType cvt_type, int rnd_mode)
|
||||
{
|
||||
|
||||
switch (cvt_type)
|
||||
{
|
||||
case SINGLE_TO_DOUBLE:
|
||||
double double_val = fp_val;
|
||||
void *double_ptr = &double_val;
|
||||
uint64_t dp_bits = *(uint64_t *) double_ptr ;
|
||||
return dp_bits;
|
||||
double sdouble_val = fp_val;
|
||||
void *sdouble_ptr = &sdouble_val;
|
||||
uint64_t sdp_bits = *(uint64_t *) sdouble_ptr ;
|
||||
return sdp_bits;
|
||||
|
||||
case SINGLE_TO_WORD:
|
||||
int32_t sword_val = (int32_t) fp_val;
|
||||
void *sword_ptr = &sword_val;
|
||||
uint64_t sword_bits= *(uint32_t *) sword_ptr ;
|
||||
return sword_bits;
|
||||
|
||||
case WORD_TO_SINGLE:
|
||||
float wfloat_val = fp_val;
|
||||
void *wfloat_ptr = &wfloat_val;
|
||||
uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr ;
|
||||
return wfloat_bits;
|
||||
|
||||
case WORD_TO_DOUBLE:
|
||||
double wdouble_val = fp_val;
|
||||
void *wdouble_ptr = &wdouble_val;
|
||||
uint64_t wdp_bits = *(uint64_t *) wdouble_ptr ;
|
||||
return wdp_bits;
|
||||
|
||||
default:
|
||||
panic("Invalid Floating Point Conversion Type (%d) being used.\n",cvt_type);
|
||||
panic("Invalid Floating Point Conversion Type (%d). See types.hh for Conversion List\n",cvt_type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
187
arch/mips/regfile/float_regfile.hh
Normal file
187
arch/mips/regfile/float_regfile.hh
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_MIPS_FLOAT_REGFILE_HH__
|
||||
#define __ARCH_MIPS_FLOAT_REGFILE_HH__
|
||||
|
||||
#include "arch/mips/types.hh"
|
||||
#include "arch/mips/constants.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "config/full_system.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
#include "sim/faults.hh"
|
||||
#include "sim/host.hh"
|
||||
|
||||
class Checkpoint;
|
||||
class ExecContext;
|
||||
class Regfile;
|
||||
|
||||
namespace MipsISA
|
||||
{
|
||||
class FloatRegFile
|
||||
{
|
||||
protected:
|
||||
FloatReg32 regs[NumFloatRegs];
|
||||
FloatReg32 fir;
|
||||
FloatReg32 fcsr;
|
||||
|
||||
FloatReg32 fpcr;
|
||||
|
||||
FloatReg32 fccr;
|
||||
FloatReg32 fexr;
|
||||
FloatReg32 fenr;
|
||||
|
||||
public:
|
||||
|
||||
void clear()
|
||||
{
|
||||
bzero(regs, sizeof(regs));
|
||||
}
|
||||
|
||||
double readReg(int floatReg, int width)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
switch(width)
|
||||
{
|
||||
case SingleWidth:
|
||||
void *float_ptr = ®s[floatReg];
|
||||
return *(float *) float_ptr;
|
||||
|
||||
case DoubleWidth:
|
||||
uint64_t double_val = (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg];
|
||||
void *double_ptr = &double_val;
|
||||
return *(double *) double_ptr;
|
||||
|
||||
default:
|
||||
panic("Attempted to read a %d bit floating point register!", width);
|
||||
}
|
||||
}
|
||||
|
||||
FloatRegBits readRegBits(int floatReg, int width)
|
||||
{
|
||||
switch(width)
|
||||
{
|
||||
case SingleWidth:
|
||||
return regs[floatReg];
|
||||
|
||||
case DoubleWidth:
|
||||
return (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg];
|
||||
|
||||
default:
|
||||
panic("Attempted to read a %d bit floating point register!", width);
|
||||
}
|
||||
}
|
||||
|
||||
Fault setReg(int floatReg, const FloatReg &val, int width)
|
||||
{
|
||||
|
||||
switch(width)
|
||||
{
|
||||
case SingleWidth:
|
||||
float temp = val;
|
||||
void *float_ptr = &temp;
|
||||
regs[floatReg] = *(FloatReg32 *) float_ptr;
|
||||
break;
|
||||
|
||||
case DoubleWidth:
|
||||
const void *double_ptr = &val;
|
||||
FloatReg64 temp_double = *(FloatReg64 *) double_ptr;
|
||||
regs[floatReg + 1] = temp_double >> 32;
|
||||
regs[floatReg] = temp_double;
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("Attempted to read a %d bit floating point register!", width);
|
||||
}
|
||||
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
switch(width)
|
||||
{
|
||||
case SingleWidth:
|
||||
regs[floatReg] = val;
|
||||
break;
|
||||
|
||||
case DoubleWidth:
|
||||
regs[floatReg + 1] = val >> 32;
|
||||
regs[floatReg] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("Attempted to read a %d bit floating point register!", width);
|
||||
}
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
MiscReg readFIR()
|
||||
{
|
||||
return fir;
|
||||
}
|
||||
|
||||
Fault setFIR(const MiscReg &val)
|
||||
{
|
||||
fir = val;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
MiscReg readFCSR()
|
||||
{
|
||||
return fcsr;
|
||||
}
|
||||
|
||||
Fault setFCSR(const MiscReg &val)
|
||||
{
|
||||
fcsr = val;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
MiscReg readFPCR()
|
||||
{
|
||||
return fpcr;
|
||||
}
|
||||
|
||||
Fault setFPCR(const MiscReg &val)
|
||||
{
|
||||
fpcr = val;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
} // namespace MipsISA
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user