I followed your advice, Gabe, and fixed double-precision
floating-point in MIPS by following the SPARC implementation. With the
attached patch, basic double-precision stuff is fixed. There are a
couple of things that are not yet fixed:
1. floating-point NaN checking.
2. instructions that assume a 64-bit FPU (like most of the Paired
Single format instructions). I don't think that at this time there
is a way to configure M5 to model a 64-bit FPU anyway.
--
Cheers,
Matt
diff --git a/src/arch/mips/isa/base.isa b/src/arch/mips/isa/base.isa
index 4e2b12f..2fa00f2 100644
--- a/src/arch/mips/isa/base.isa
+++ b/src/arch/mips/isa/base.isa
@@ -60,6 +60,81 @@ output header {{
}};
+output header {{
+ union DoubleSingle
+ {
+ double d;
+ uint64_t ui;
+ uint32_t s[2];
+ DoubleSingle(double _d) : d(_d)
+ {}
+ DoubleSingle(uint64_t _ui) : ui(_ui)
+ {}
+ DoubleSingle(uint32_t _s0, uint32_t _s1)
+ {
+ s[0] = _s0;
+ s[1] = _s1;
+ }
+ };
+}};
+
+let {{
+ def filterDoubles(code):
+ assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
+ for opName in ("Fd", "Fs", "Ft", "Fr"):
+ next_pos = 0
+ operandsREString = (r'''
+ (?<![\w\.]) # neg. lookbehind assertion: prevent partial matches
+ ((%s)(?:\.(\w+))?) # match: operand with optional '.' then suffix
+ (?![\w\.]) # neg. lookahead assertion: prevent partial matches
+ ''' % opName)
+ operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE)
+ is_src = False
+ is_dest = False
+ extension = None
+ foundOne = False
+ while 1:
+ match = operandsRE.search(code, next_pos)
+ if not match:
+ break
+ op = match.groups()
+ (op_full, op_base, op_ext) = op
+ # A floating-point operand is 64-bits wide if the
+ # extension is either df (double float) or ud
+ # (uninterpreted doubleword).
+ if not op_ext in ("df", "ud"):
+ break
+ foundOne = True
+ is_dest_local = (assignRE.match(code, match.end()) != None)
+ is_dest = is_dest or is_dest_local
+ is_src = is_src or not is_dest_local
+ if extension and extension != op_ext:
+ raise Exception, "Inconsistent extensions in double filter."
+ extension = op_ext
+ next_pos = match.end()
+ if foundOne:
+ # Get rid of any unwanted extension
+ code = operandsRE.sub(op_base + "_d", code)
+ is_int = False
+ member = "d"
+ if extension in ("ud"):
+ is_int = True
+ member = "ui"
+ if is_src:
+ code = ("%s_d = DoubleSingle(%s_low, %s_high).%s;\n" % \
+ (opName, opName, opName, member)) + code
+ if is_dest:
+ code += '''
+ %s_low = DoubleSingle(%s_d).s[0];
+ %s_high = DoubleSingle(%s_d).s[1];\n''' % \
+ (opName, opName, opName, opName)
+ if is_int:
+ code = ("uint64_t %s_d;\n" % opName) + code
+ else:
+ code = ("double %s_d;\n" % opName) + code
+ return code
+}};
+
//Ouputs to decoder.cc
output decoder {{
diff --git a/src/arch/mips/isa/formats/basic.isa b/src/arch/mips/isa/formats/basic.isa
index 92568c5..653c607 100644
--- a/src/arch/mips/isa/formats/basic.isa
+++ b/src/arch/mips/isa/formats/basic.isa
@@ -91,6 +91,7 @@ def template BasicDecodeWithMnemonic {{
// The most basic instruction format...
def format BasicOp(code, *flags) {{
+ code = filterDoubles(code)
iop = InstObjParams(name, Name, 'MipsStaticInst', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
diff --git a/src/arch/mips/isa/formats/fp.isa b/src/arch/mips/isa/formats/fp.isa
index 72d87f9..b86f240 100644
--- a/src/arch/mips/isa/formats/fp.isa
+++ b/src/arch/mips/isa/formats/fp.isa
@@ -181,7 +181,7 @@ def template FloatingPointExecute {{
%(op_rd)s;
//Check if any FP operand is a NaN value
- if (!fpNanOperands((FPOp*)this, xc, Fd, traceData)) {
+ //if (!fpNanOperands((FPOp*)this, xc, Fd, traceData)) {
%(code)s;
//Change this code for Full-System/Sycall Emulation
@@ -192,14 +192,14 @@ def template FloatingPointExecute {{
//Check for IEEE 754 FP Exceptions
//fault = fpNanOperands((FPOp*)this, xc, Fd, traceData);
if (
-#if FULL_SYSTEM
- !fpInvalidOp((FPOp*)this, xc, Fd, traceData) &&
-#endif
+ //#if FULL_SYSTEM
+ //!fpInvalidOp((FPOp*)this, xc, Fd, traceData) &&
+ //#endif
fault == NoFault)
{
%(op_wb)s;
}
- }
+ //}
return fault;
}
@@ -207,6 +207,7 @@ def template FloatingPointExecute {{
// Primary format for float point operate instructions:
def format FloatOp(code, *flags) {{
+ code = filterDoubles(code)
iop = InstObjParams(name, Name, 'FPOp', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
@@ -246,6 +247,7 @@ def format FloatCompareOp(cond_code, *flags) {{
code += cond_code + '}'
code += 'FCSR = genCCVector(FCSR, CC, cond);\n'
+ code = filterDoubles(code)
iop = InstObjParams(name, Name, 'FPCompareOp', code)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
@@ -297,6 +299,7 @@ def format FloatConvertOp(code, *flags) {{
else:
code += 'val); '
+ code = filterDoubles(code)
iop = InstObjParams(name, Name, 'FPOp', code)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
@@ -305,6 +308,7 @@ def format FloatConvertOp(code, *flags) {{
}};
def format FloatAccOp(code, *flags) {{
+ code = filterDoubles(code)
iop = InstObjParams(name, Name, 'FPOp', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
@@ -314,6 +318,7 @@ def format FloatAccOp(code, *flags) {{
// Primary format for float64 operate instructions:
def format Float64Op(code, *flags) {{
+ code = filterDoubles(code)
iop = InstObjParams(name, Name, 'MipsStaticInst', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa
index 161a52b..7ecc35e 100644
--- a/src/arch/mips/isa/formats/mem.isa
+++ b/src/arch/mips/isa/formats/mem.isa
@@ -534,6 +534,7 @@ def template MiscCompleteAcc {{
def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
mem_flags = [], inst_flags = []) {{
+ memacc_code = filterDoubles(memacc_code)
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
decode_template = ImmNopCheckDecode,
@@ -543,6 +544,7 @@ def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
mem_flags = [], inst_flags = []) {{
+ memacc_code = filterDoubles(memacc_code)
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
exec_template_base = 'Store')
@@ -550,6 +552,7 @@ def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
mem_flags = [], inst_flags = []) {{
+ memacc_code = filterDoubles(memacc_code)
inst_flags += ['IsIndexed']
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
@@ -559,6 +562,7 @@ def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
mem_flags = [], inst_flags = []) {{
+ memacc_code = filterDoubles(memacc_code)
inst_flags += ['IsIndexed']
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
@@ -567,6 +571,7 @@ def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
def format LoadFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
mem_flags = [], inst_flags = []) {{
+ memacc_code = filterDoubles(memacc_code)
inst_flags += ['IsIndexed', 'IsFloating']
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
@@ -576,6 +581,7 @@ def format LoadFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
def format StoreFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
mem_flags = [], inst_flags = []) {{
+ memacc_code = filterDoubles(memacc_code)
inst_flags += ['IsIndexed', 'IsFloating']
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
@@ -585,6 +591,7 @@ def format StoreFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
mem_flags = [], inst_flags = []) {{
+ memacc_code = filterDoubles(memacc_code)
decl_code = 'uint32_t mem_word = Mem.uw;\n'
decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
@@ -602,6 +609,7 @@ def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3;
def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
mem_flags = [], inst_flags = []) {{
+ memacc_code = filterDoubles(memacc_code)
decl_code = 'uint32_t mem_word = 0;\n'
decl_code += 'uint32_t unaligned_addr = Rs + disp;\n'
decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n'
@@ -633,6 +641,7 @@ def format Prefetch(ea_code = {{ EA = Rs + disp; }},
def format StoreCond(memacc_code, postacc_code,
ea_code = {{ EA = Rs + disp; }},
mem_flags = [], inst_flags = []) {{
+ memacc_code = filterDoubles(memacc_code)
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
postacc_code, exec_template_base = 'StoreCond')
diff --git a/src/arch/mips/isa/operands.isa b/src/arch/mips/isa/operands.isa
index 50726cd..ca52265 100644
--- a/src/arch/mips/isa/operands.isa
+++ b/src/arch/mips/isa/operands.isa
@@ -82,9 +82,17 @@ def operands {{
#Floating Point Reg Operands
'Fd': ('FloatReg', 'sf', 'FD', 'IsFloating', 1),
+ 'Fd_low': ('FloatReg', 'uw', 'FD', 'IsFloating', 1),
+ 'Fd_high': ('FloatReg', 'uw', 'FD + 1', 'IsFloating', 1),
'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2),
+ 'Fs_low': ('FloatReg', 'uw', 'FS', 'IsFloating', 2),
+ 'Fs_high': ('FloatReg', 'uw', 'FS + 1', 'IsFloating', 2),
'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3),
+ 'Ft_low': ('FloatReg', 'uw', 'FT', 'IsFloating', 3),
+ 'Ft_high': ('FloatReg', 'uw', 'FT + 1', 'IsFloating', 3),
'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3),
+ 'Fr_low': ('FloatReg', 'uw', 'FR', 'IsFloating', 3),
+ 'Fr_high': ('FloatReg', 'uw', 'FR + 1', 'IsFloating', 3),
#Special Purpose Floating Point Control Reg Operands
'FIR': ('FloatReg', 'uw', 'FLOATREG_FIR', 'IsFloating', 1),
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev