From d06064c38613662dfbf68a701052278b4018de8c Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Tue, 18 Jun 2013 16:36:08 +0200 Subject: x86: Add support for maintaining the x87 tag word The current implementation of the x87 never updates the x87 tag word. This is currently not a big issue since the simulated x87 never checks for stack overflows, however this becomes an issue when switching between a virtualized CPU and a simulated CPU. This changeset adds support, which is enabled by default, for updating the tag register to every floating point microop that updates the stack top using the spm mechanism. The new tag words is generated by the helper function X86ISA::genX87Tags(). This function is currently limited to flagging a stack position as valid or invalid and does not try to distinguish between the valid, zero, and special states. --- src/arch/x86/isa/microops/fpop.isa | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'src/arch/x86/isa') diff --git a/src/arch/x86/isa/microops/fpop.isa b/src/arch/x86/isa/microops/fpop.isa index 22d6fbcda..142138fb2 100644 --- a/src/arch/x86/isa/microops/fpop.isa +++ b/src/arch/x86/isa/microops/fpop.isa @@ -57,6 +57,7 @@ def template MicroFpOpExecute {{ { %(code)s; %(flag_code)s; + %(tag_code)s; %(top_code)s; } else @@ -128,11 +129,20 @@ let {{ base = "X86ISA::FpOp" # Get everything ready for the substitution + iop_tag = InstObjParams(name, Name + suffix + "TopTag", base, + {"code" : code, + "flag_code" : flag_code, + "cond_check" : cond_check, + "else_code" : else_code, + "tag_code" : "FTW = genX87Tags(FTW, TOP, spm);", + "top_code" : "TOP = (TOP + spm + 8) % 8;", + "op_class" : op_class}) iop_top = InstObjParams(name, Name + suffix + "Top", base, {"code" : code, "flag_code" : flag_code, "cond_check" : cond_check, "else_code" : else_code, + "tag_code" : ";", "top_code" : "TOP = (TOP + spm + 8) % 8;", "op_class" : op_class}) iop = InstObjParams(name, Name + suffix, base, @@ -140,10 +150,14 @@ let {{ "flag_code" : flag_code, "cond_check" : cond_check, "else_code" : else_code, + "tag_code" : ";", "top_code" : ";", "op_class" : op_class}) # Generate the actual code (finally!) + header_output += MicroFpOpDeclare.subst(iop_tag) + decoder_output += MicroFpOpConstructor.subst(iop_tag) + exec_output += MicroFpOpExecute.subst(iop_tag) header_output += MicroFpOpDeclare.subst(iop_top) decoder_output += MicroFpOpConstructor.subst(iop_top) exec_output += MicroFpOpExecute.subst(iop_top) @@ -191,7 +205,7 @@ let {{ op_class = "FloatAddOp" def __init__(self, dest, src1, spm=0, \ - SetStatus=False, dataSize="env.dataSize"): + SetStatus=False, UpdateFTW=True, dataSize="env.dataSize"): self.dest = dest self.src1 = src1 self.src2 = "InstRegIndex(0)" @@ -201,6 +215,8 @@ let {{ self.className += "Flags" if spm: self.className += "Top" + if spm and UpdateFTW: + self.className += "Tag" def getAllocator(self, microFlags): return '''new %(class_name)s(machInst, macrocodeBlock, @@ -225,7 +241,7 @@ let {{ op_class = "FloatAddOp" def __init__(self, dest, src1, src2, spm=0, \ - SetStatus=False, dataSize="env.dataSize"): + SetStatus=False, UpdateFTW=True, dataSize="env.dataSize"): self.dest = dest self.src1 = src1 self.src2 = src2 @@ -235,6 +251,8 @@ let {{ self.className += "Flags" if spm: self.className += "Top" + if spm and UpdateFTW: + self.className += "Tag" def getAllocator(self, microFlags): return '''new %(class_name)s(machInst, macrocodeBlock, @@ -359,10 +377,10 @@ let {{ flag_code = 'FSW = new_fsw;' class Compfp(FpBinaryOp): - def __init__(self, src1, src2, spm=0, setStatus=False, \ + def __init__(self, src1, src2, spm=0, setStatus=False, updateFTW=True, \ dataSize="env.dataSize"): super(Compfp, self).__init__("InstRegIndex(FLOATREG_MICROFP0)", \ - src1, src2, spm, setStatus, dataSize) + src1, src2, spm, setStatus, updateFTW, dataSize) # This class sets the condition codes in rflags according to the # rules for comparing floating point. code = ''' -- cgit v1.2.3