summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-09-19 18:27:55 -0700
committerGabe Black <gblack@eecs.umich.edu>2007-09-19 18:27:55 -0700
commita75b6f51060ceaa52014aa4dd6aadc6ca83365f8 (patch)
treea8da313b6cf771f07ab0e1b795ea6be3137d4e29
parentf3f3747431e001dc6c80da5b6489516b610c22d6 (diff)
downloadgem5-a75b6f51060ceaa52014aa4dd6aadc6ca83365f8.tar.xz
X86: Move the fp microops to their own file with their own base classes in C++ and python.
--HG-- extra : convert_revision : 9cd223f2005adb36fea2bb56fa39793a58ec958c
-rw-r--r--src/arch/x86/SConscript2
-rw-r--r--src/arch/x86/insts/microfpop.cc85
-rw-r--r--src/arch/x86/insts/microfpop.hh104
-rw-r--r--src/arch/x86/insts/microop.cc139
-rw-r--r--src/arch/x86/insts/microop.hh43
-rw-r--r--src/arch/x86/insts/microregop.cc76
-rw-r--r--src/arch/x86/insts/microregop.hh42
-rw-r--r--src/arch/x86/isa/includes.isa1
-rw-r--r--src/arch/x86/isa/microops/base.isa8
-rw-r--r--src/arch/x86/isa/microops/fpop.isa341
-rw-r--r--src/arch/x86/isa/microops/microops.isa3
-rw-r--r--src/arch/x86/isa/microops/regop.isa65
-rw-r--r--src/arch/x86/isa/operands.isa3
13 files changed, 722 insertions, 190 deletions
diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript
index f4110024f..b3fd67f89 100644
--- a/src/arch/x86/SConscript
+++ b/src/arch/x86/SConscript
@@ -88,7 +88,9 @@ Import('*')
if env['TARGET_ISA'] == 'x86':
Source('emulenv.cc')
Source('floatregfile.cc')
+ Source('insts/microfpop.cc')
Source('insts/microldstop.cc')
+ Source('insts/microop.cc')
Source('insts/microregop.cc')
Source('insts/static_inst.cc')
Source('intregfile.cc')
diff --git a/src/arch/x86/insts/microfpop.cc b/src/arch/x86/insts/microfpop.cc
new file mode 100644
index 000000000..c25495da9
--- /dev/null
+++ b/src/arch/x86/insts/microfpop.cc
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "arch/x86/insts/microfpop.hh"
+#include "arch/x86/miscregs.hh"
+#include <string>
+
+namespace X86ISA
+{
+ /*
+ uint64_t FpOp::genFlags(uint64_t oldFlags, uint64_t flagMask,
+ uint64_t _dest, uint64_t _src1, uint64_t _src2,
+ bool subtract) const
+ {
+ }
+ */
+
+ std::string FpOp::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+ printDestReg(response, 0, dataSize);
+ response << ", ";
+ printSrcReg(response, 0, dataSize);
+ response << ", ";
+ printSrcReg(response, 1, dataSize);
+ return response.str();
+ }
+}
diff --git a/src/arch/x86/insts/microfpop.hh b/src/arch/x86/insts/microfpop.hh
new file mode 100644
index 000000000..2e01cadbc
--- /dev/null
+++ b/src/arch/x86/insts/microfpop.hh
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_X86_INSTS_MICROFPOP_HH__
+#define __ARCH_X86_INSTS_MICROFPOP_HH__
+
+#include "arch/x86/insts/microop.hh"
+
+namespace X86ISA
+{
+
+ /**
+ * Base classes for FpOps which provides a generateDisassembly method.
+ */
+ class FpOp : public X86MicroopBase
+ {
+ protected:
+ const RegIndex src1;
+ const RegIndex src2;
+ const RegIndex dest;
+ const uint8_t dataSize;
+ const int8_t spm;
+
+ // Constructor
+ FpOp(ExtMachInst _machInst,
+ const char *mnem, const char *_instMnem,
+ bool isMicro, bool isDelayed,
+ bool isFirst, bool isLast,
+ RegIndex _src1, RegIndex _src2, RegIndex _dest,
+ uint8_t _dataSize, int8_t _spm,
+ OpClass __opClass) :
+ X86MicroopBase(_machInst, mnem, _instMnem,
+ isMicro, isDelayed, isFirst, isLast,
+ __opClass),
+ src1(_src1), src2(_src2), dest(_dest),
+ dataSize(_dataSize), spm(_spm)
+ {}
+/*
+ //Figure out what the condition code flags should be.
+ uint64_t genFlags(uint64_t oldFlags, uint64_t flagMask,
+ uint64_t _dest, uint64_t _src1, uint64_t _src2,
+ bool subtract = false) const;
+ bool checkCondition(uint64_t flags) const;*/
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+ };
+}
+
+#endif //__ARCH_X86_INSTS_MICROFPOP_HH__
diff --git a/src/arch/x86/insts/microop.cc b/src/arch/x86/insts/microop.cc
new file mode 100644
index 000000000..6caa27f36
--- /dev/null
+++ b/src/arch/x86/insts/microop.cc
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2007 The Hewlett-Packard Development Company
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms,
+ * with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * The software must be used only for Non-Commercial Use which means any
+ * use which is NOT directed to receiving any direct monetary
+ * compensation for, or commercial advantage from such use. Illustrative
+ * examples of non-commercial use are academic research, personal study,
+ * teaching, education and corporate research & development.
+ * Illustrative examples of commercial use are distributing products for
+ * commercial advantage and providing services using the software for
+ * commercial advantage.
+ *
+ * If you wish to use this software or functionality therein that may be
+ * covered by patents for commercial use, please contact:
+ * Director of Intellectual Property Licensing
+ * Office of Strategy and Technology
+ * Hewlett-Packard Company
+ * 1501 Page Mill Road
+ * Palo Alto, California 94304
+ *
+ * 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission. No right of
+ * sublicense is granted herewith. Derivatives of the software and
+ * output created using the software may be prepared, but only for
+ * Non-Commercial Uses. Derivatives of the software may be shared with
+ * others provided: (i) the others agree to abide by the list of
+ * conditions herein which includes the Non-Commercial Use restrictions;
+ * and (ii) such Derivatives of the software include the above copyright
+ * notice to acknowledge the contribution from this software where
+ * applicable, this list of conditions and the disclaimer below.
+ *
+ * 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.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "arch/x86/insts/microop.hh"
+#include "arch/x86/miscregs.hh"
+
+namespace X86ISA
+{
+
+ bool X86MicroopBase::checkCondition(uint64_t flags, int condition) const
+ {
+ CCFlagBits ccflags = flags;
+ switch(condition)
+ {
+ case ConditionTests::True:
+ return true;
+ case ConditionTests::ECF:
+ return ccflags.ECF;
+ case ConditionTests::EZF:
+ return ccflags.EZF;
+ case ConditionTests::SZnZF:
+ return !(!ccflags.EZF & ccflags.ZF);
+ case ConditionTests::MSTRZ:
+ panic("This condition is not implemented!");
+ case ConditionTests::STRZ:
+ panic("This condition is not implemented!");
+ case ConditionTests::MSTRC:
+ panic("This condition is not implemented!");
+ case ConditionTests::STRZnEZF:
+ return !ccflags.EZF & ccflags.ZF;
+ //And no interrupts or debug traps are waiting
+ case ConditionTests::OF:
+ return ccflags.OF;
+ case ConditionTests::CF:
+ return ccflags.CF;
+ case ConditionTests::ZF:
+ return ccflags.ZF;
+ case ConditionTests::CvZF:
+ return ccflags.CF | ccflags.ZF;
+ case ConditionTests::SF:
+ return ccflags.SF;
+ case ConditionTests::PF:
+ return ccflags.PF;
+ case ConditionTests::SxOF:
+ return ccflags.SF ^ ccflags.OF;
+ case ConditionTests::SxOvZF:
+ return ccflags.SF ^ ccflags.OF | ccflags.ZF;
+ case ConditionTests::False:
+ return false;
+ case ConditionTests::NotECF:
+ return !ccflags.ECF;
+ case ConditionTests::NotEZF:
+ return !ccflags.EZF;
+ case ConditionTests::NotSZnZF:
+ return !ccflags.EZF & ccflags.ZF;
+ case ConditionTests::NotMSTRZ:
+ panic("This condition is not implemented!");
+ case ConditionTests::NotSTRZ:
+ panic("This condition is not implemented!");
+ case ConditionTests::NotMSTRC:
+ panic("This condition is not implemented!");
+ case ConditionTests::STRnZnEZF:
+ return !ccflags.EZF & !ccflags.ZF;
+ //And no interrupts or debug traps are waiting
+ case ConditionTests::NotOF:
+ return !ccflags.OF;
+ case ConditionTests::NotCF:
+ return !ccflags.CF;
+ case ConditionTests::NotZF:
+ return !ccflags.ZF;
+ case ConditionTests::NotCvZF:
+ return !(ccflags.CF | ccflags.ZF);
+ case ConditionTests::NotSF:
+ return !ccflags.SF;
+ case ConditionTests::NotPF:
+ return !ccflags.PF;
+ case ConditionTests::NotSxOF:
+ return !(ccflags.SF ^ ccflags.OF);
+ case ConditionTests::NotSxOvZF:
+ return !(ccflags.SF ^ ccflags.OF | ccflags.ZF);
+ }
+ panic("Unknown condition: %d\n", condition);
+ return true;
+ }
+}
diff --git a/src/arch/x86/insts/microop.hh b/src/arch/x86/insts/microop.hh
index 45e1cb5c8..535bcb817 100644
--- a/src/arch/x86/insts/microop.hh
+++ b/src/arch/x86/insts/microop.hh
@@ -62,6 +62,47 @@
namespace X86ISA
{
+ namespace ConditionTests
+ {
+ enum CondTest {
+ True,
+ NotFalse = True,
+ ECF,
+ EZF,
+ SZnZF,
+ MSTRZ,
+ STRZ,
+ MSTRC,
+ STRZnEZF,
+ OF,
+ CF,
+ ZF,
+ CvZF,
+ SF,
+ PF,
+ SxOF,
+ SxOvZF,
+
+ False,
+ NotTrue = False,
+ NotECF,
+ NotEZF,
+ NotSZnZF,
+ NotMSTRZ,
+ NotSTRZ,
+ NotMSTRC,
+ STRnZnEZF,
+ NotOF,
+ NotCF,
+ NotZF,
+ NotCvZF,
+ NotSF,
+ NotPF,
+ NotSxOF,
+ NotSxOvZF
+ };
+ }
+
//A class which is the base of all x86 micro ops. It provides a function to
//set necessary flags appropriately.
class X86MicroopBase : public X86StaticInst
@@ -94,6 +135,8 @@ namespace X86ISA
return ss.str();
}
+
+ bool checkCondition(uint64_t flags, int condition) const;
};
}
diff --git a/src/arch/x86/insts/microregop.cc b/src/arch/x86/insts/microregop.cc
index ad48a4bc1..60f32857d 100644
--- a/src/arch/x86/insts/microregop.cc
+++ b/src/arch/x86/insts/microregop.cc
@@ -93,82 +93,6 @@ namespace X86ISA
return flags;
}
- bool RegOpBase::checkCondition(uint64_t flags) const
- {
- CCFlagBits ccflags = flags;
- switch(ext)
- {
- case ConditionTests::True:
- return true;
- case ConditionTests::ECF:
- return ccflags.ECF;
- case ConditionTests::EZF:
- return ccflags.EZF;
- case ConditionTests::SZnZF:
- return !(!ccflags.EZF & ccflags.ZF);
- case ConditionTests::MSTRZ:
- panic("This condition is not implemented!");
- case ConditionTests::STRZ:
- panic("This condition is not implemented!");
- case ConditionTests::MSTRC:
- panic("This condition is not implemented!");
- case ConditionTests::STRZnEZF:
- return !ccflags.EZF & ccflags.ZF;
- //And no interrupts or debug traps are waiting
- case ConditionTests::OF:
- return ccflags.OF;
- case ConditionTests::CF:
- return ccflags.CF;
- case ConditionTests::ZF:
- return ccflags.ZF;
- case ConditionTests::CvZF:
- return ccflags.CF | ccflags.ZF;
- case ConditionTests::SF:
- return ccflags.SF;
- case ConditionTests::PF:
- return ccflags.PF;
- case ConditionTests::SxOF:
- return ccflags.SF ^ ccflags.OF;
- case ConditionTests::SxOvZF:
- return ccflags.SF ^ ccflags.OF | ccflags.ZF;
- case ConditionTests::False:
- return false;
- case ConditionTests::NotECF:
- return !ccflags.ECF;
- case ConditionTests::NotEZF:
- return !ccflags.EZF;
- case ConditionTests::NotSZnZF:
- return !ccflags.EZF & ccflags.ZF;
- case ConditionTests::NotMSTRZ:
- panic("This condition is not implemented!");
- case ConditionTests::NotSTRZ:
- panic("This condition is not implemented!");
- case ConditionTests::NotMSTRC:
- panic("This condition is not implemented!");
- case ConditionTests::STRnZnEZF:
- return !ccflags.EZF & !ccflags.ZF;
- //And no interrupts or debug traps are waiting
- case ConditionTests::NotOF:
- return !ccflags.OF;
- case ConditionTests::NotCF:
- return !ccflags.CF;
- case ConditionTests::NotZF:
- return !ccflags.ZF;
- case ConditionTests::NotCvZF:
- return !(ccflags.CF | ccflags.ZF);
- case ConditionTests::NotSF:
- return !ccflags.SF;
- case ConditionTests::NotPF:
- return !ccflags.PF;
- case ConditionTests::NotSxOF:
- return !(ccflags.SF ^ ccflags.OF);
- case ConditionTests::NotSxOvZF:
- return !(ccflags.SF ^ ccflags.OF | ccflags.ZF);
- }
- panic("Unknown condition: %d\n", ext);
- return true;
- }
-
std::string RegOp::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
diff --git a/src/arch/x86/insts/microregop.hh b/src/arch/x86/insts/microregop.hh
index f6bebb763..d805adb33 100644
--- a/src/arch/x86/insts/microregop.hh
+++ b/src/arch/x86/insts/microregop.hh
@@ -62,47 +62,6 @@
namespace X86ISA
{
- namespace ConditionTests
- {
- enum CondTest {
- True,
- NotFalse = True,
- ECF,
- EZF,
- SZnZF,
- MSTRZ,
- STRZ,
- MSTRC,
- STRZnEZF,
- OF,
- CF,
- ZF,
- CvZF,
- SF,
- PF,
- SxOF,
- SxOvZF,
-
- False,
- NotTrue = False,
- NotECF,
- NotEZF,
- NotSZnZF,
- NotMSTRZ,
- NotSTRZ,
- NotMSTRC,
- STRnZnEZF,
- NotOF,
- NotCF,
- NotZF,
- NotCvZF,
- NotSF,
- NotPF,
- NotSxOF,
- NotSxOvZF
- };
- }
-
/**
* Base classes for RegOps which provides a generateDisassembly method.
*/
@@ -136,7 +95,6 @@ namespace X86ISA
uint64_t genFlags(uint64_t oldFlags, uint64_t flagMask,
uint64_t _dest, uint64_t _src1, uint64_t _src2,
bool subtract = false) const;
- bool checkCondition(uint64_t flags) const;
};
class RegOp : public RegOpBase
diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa
index 9629a54e3..0679e972b 100644
--- a/src/arch/x86/isa/includes.isa
+++ b/src/arch/x86/isa/includes.isa
@@ -97,6 +97,7 @@ output header {{
#include <iostream>
#include "arch/x86/emulenv.hh"
+#include "arch/x86/insts/microfpop.hh"
#include "arch/x86/insts/microldstop.hh"
#include "arch/x86/insts/microregop.hh"
#include "arch/x86/insts/static_inst.hh"
diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa
index 9722f182e..75658a26c 100644
--- a/src/arch/x86/isa/microops/base.isa
+++ b/src/arch/x86/isa/microops/base.isa
@@ -92,11 +92,3 @@ let {{
return 'new %s(machInst, %s)' % \
(self.className, mnemonic, self.microFlagsText(microFlags))
}};
-
-//////////////////////////////////////////////////////////////////////////
-//
-// FpOp Microop templates
-//
-//////////////////////////////////////////////////////////////////////////
-
-//TODO Actually write an fp microop base class.
diff --git a/src/arch/x86/isa/microops/fpop.isa b/src/arch/x86/isa/microops/fpop.isa
new file mode 100644
index 000000000..e9a7cb84f
--- /dev/null
+++ b/src/arch/x86/isa/microops/fpop.isa
@@ -0,0 +1,341 @@
+// Copyright (c) 2007 The Hewlett-Packard Development Company
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the
+// following conditions are met:
+//
+// The software must be used only for Non-Commercial Use which means any
+// use which is NOT directed to receiving any direct monetary
+// compensation for, or commercial advantage from such use. Illustrative
+// examples of non-commercial use are academic research, personal study,
+// teaching, education and corporate research & development.
+// Illustrative examples of commercial use are distributing products for
+// commercial advantage and providing services using the software for
+// commercial advantage.
+//
+// If you wish to use this software or functionality therein that may be
+// covered by patents for commercial use, please contact:
+// Director of Intellectual Property Licensing
+// Office of Strategy and Technology
+// Hewlett-Packard Company
+// 1501 Page Mill Road
+// Palo Alto, California 94304
+//
+// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission. No right of
+// sublicense is granted herewith. Derivatives of the software and
+// output created using the software may be prepared, but only for
+// Non-Commercial Uses. Derivatives of the software may be shared with
+// others provided: (i) the others agree to abide by the list of
+// conditions herein which includes the Non-Commercial Use restrictions;
+// and (ii) such Derivatives of the software include the above copyright
+// notice to acknowledge the contribution from this software where
+// applicable, this list of conditions and the disclaimer below.
+//
+// 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.
+//
+// Authors: Gabe Black
+
+//////////////////////////////////////////////////////////////////////////
+//
+// FpOp Microop templates
+//
+//////////////////////////////////////////////////////////////////////////
+
+def template MicroFpOpExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ DPRINTF(X86, "The data size is %d\n", dataSize);
+ %(op_decl)s;
+ %(op_rd)s;
+
+ if(%(cond_check)s)
+ {
+ %(code)s;
+ %(flag_code)s;
+ %(top_code)s;
+ }
+ else
+ {
+ %(else_code)s;
+ }
+
+ //Write the resulting state to the execution context
+ if(fault == NoFault)
+ {
+ %(op_wb)s;
+ }
+ return fault;
+ }
+}};
+
+def template MicroFpOpDeclare {{
+ class %(class_name)s : public %(base_class)s
+ {
+ protected:
+ void buildMe();
+
+ public:
+ %(class_name)s(ExtMachInst _machInst,
+ const char * instMnem,
+ bool isMicro, bool isDelayed, bool isFirst, bool isLast,
+ RegIndex _src1, RegIndex _src2, RegIndex _dest,
+ uint8_t _dataSize, int8_t _spm);
+
+ %(class_name)s(ExtMachInst _machInst,
+ const char * instMnem,
+ RegIndex _src1, RegIndex _src2, RegIndex _dest,
+ uint8_t _dataSize, int8_t _spm);
+
+ %(BasicExecDeclare)s
+ };
+}};
+
+def template MicroFpOpConstructor {{
+
+ inline void %(class_name)s::buildMe()
+ {
+ %(constructor)s;
+ }
+
+ inline %(class_name)s::%(class_name)s(
+ ExtMachInst machInst, const char * instMnem,
+ RegIndex _src1, RegIndex _src2, RegIndex _dest,
+ uint8_t _dataSize, int8_t _spm) :
+ %(base_class)s(machInst, "%(mnemonic)s", instMnem,
+ false, false, false, false,
+ _src1, _src2, _dest, _dataSize, _spm,
+ %(op_class)s)
+ {
+ buildMe();
+ }
+
+ inline %(class_name)s::%(class_name)s(
+ ExtMachInst machInst, const char * instMnem,
+ bool isMicro, bool isDelayed, bool isFirst, bool isLast,
+ RegIndex _src1, RegIndex _src2, RegIndex _dest,
+ uint8_t _dataSize, int8_t _spm) :
+ %(base_class)s(machInst, "%(mnemonic)s", instMnem,
+ isMicro, isDelayed, isFirst, isLast,
+ _src1, _src2, _dest, _dataSize, _spm,
+ %(op_class)s)
+ {
+ buildMe();
+ }
+}};
+
+let {{
+ # Make these empty strings so that concatenating onto
+ # them will always work.
+ header_output = ""
+ decoder_output = ""
+ exec_output = ""
+
+ class FpOpMeta(type):
+ def buildCppClasses(self, name, Name, suffix, \
+ code, flag_code, cond_check, else_code):
+
+ # Globals to stick the output in
+ global header_output
+ global decoder_output
+ global exec_output
+
+ # Stick all the code together so it can be searched at once
+ allCode = "|".join((code, flag_code, cond_check, else_code))
+
+ # If there's something optional to do with flags, generate
+ # a version without it and fix up this version to use it.
+ if flag_code is not "" or cond_check is not "true":
+ self.buildCppClasses(name, Name, suffix,
+ code, "", "true", else_code)
+ suffix = "Flags" + suffix
+
+ base = "X86ISA::FpOp"
+
+ # Get everything ready for the substitution
+ iop_top = InstObjParams(name, Name + suffix + "Top", base,
+ {"code" : code,
+ "flag_code" : flag_code,
+ "cond_check" : cond_check,
+ "else_code" : else_code,
+ "top_code" : "TOP = (TOP + spm + 8) % 8;"})
+ iop = InstObjParams(name, Name + suffix, base,
+ {"code" : code,
+ "flag_code" : flag_code,
+ "cond_check" : cond_check,
+ "else_code" : else_code,
+ "top_code" : ";"})
+
+ # Generate the actual code (finally!)
+ header_output += MicroFpOpDeclare.subst(iop_top)
+ decoder_output += MicroFpOpConstructor.subst(iop_top)
+ exec_output += MicroFpOpExecute.subst(iop_top)
+ header_output += MicroFpOpDeclare.subst(iop)
+ decoder_output += MicroFpOpConstructor.subst(iop)
+ exec_output += MicroFpOpExecute.subst(iop)
+
+
+ def __new__(mcls, Name, bases, dict):
+ abstract = False
+ name = Name.lower()
+ if "abstract" in dict:
+ abstract = dict['abstract']
+ del dict['abstract']
+
+ cls = super(FpOpMeta, mcls).__new__(mcls, Name, bases, dict)
+ if not abstract:
+ cls.className = Name
+ cls.mnemonic = name
+ code = cls.code
+ flag_code = cls.flag_code
+ cond_check = cls.cond_check
+ else_code = cls.else_code
+
+ # Set up the C++ classes
+ mcls.buildCppClasses(cls, name, Name, "",
+ code, flag_code, cond_check, else_code)
+
+ # Hook into the microassembler dict
+ global microopClasses
+ microopClasses[name] = cls
+
+ return cls
+
+
+ class FpOp(X86Microop):
+ __metaclass__ = FpOpMeta
+ # This class itself doesn't act as a microop
+ abstract = True
+
+ # Default template parameter values
+ flag_code = ""
+ cond_check = "true"
+ else_code = ";"
+
+ def __init__(self, dest, src1, src2, spm=0, \
+ SetStatus=False, dataSize="env.dataSize"):
+ self.dest = dest
+ self.src1 = src1
+ self.src2 = src2
+ self.spm = spm
+ self.dataSize = dataSize
+ if SetStatus:
+ self.className += "Flags"
+ if spm:
+ self.className += "Top"
+
+ def getAllocator(self, *microFlags):
+ return '''new %(class_name)s(machInst, mnemonic
+ %(flags)s, %(src1)s, %(src2)s, %(dest)s,
+ %(dataSize)s, %(spm)d)''' % {
+ "class_name" : self.className,
+ "flags" : self.microFlagsText(microFlags),
+ "src1" : self.src1, "src2" : self.src2,
+ "dest" : self.dest,
+ "dataSize" : self.dataSize,
+ "spm" : self.spm}
+
+ class Movfp(FpOp):
+ def __init__(self, dest, src1, flags=0, spm=0, \
+ SetStatus=False, dataSize="env.dataSize"):
+ super(Movfp, self).__init__(dest, src1, flags, \
+ spm, SetStatus, dataSize)
+ code = 'FpDestReg.uqw = FpSrcReg2.uqw;'
+ else_code = 'FpDestReg.uqw = FpDestReg.uqw;'
+ cond_check = "checkCondition(ccFlagBits, src2)"
+
+ class Xorfp(FpOp):
+ code = 'FpDestReg.uqw = FpSrcReg1.uqw ^ FpSrcReg2.uqw;'
+
+ class Sqrtfp(FpOp):
+ code = 'FpDestReg = sqrt(FpSrcReg2);'
+
+ # Conversion microops
+ class ConvOp(FpOp):
+ abstract = True
+ def __init__(self, dest, src1):
+ super(ConvOp, self).__init__(dest, src1, "(int)FLOATREG_MICROFP0")
+
+ # These probably shouldn't look at the ExtMachInst directly to figure
+ # out what size to use and should instead delegate that to the macroop's
+ # constructor. That would be more efficient, and it would make the
+ # microops a little more modular.
+ class cvtf_i2d(ConvOp):
+ code = '''
+ X86IntReg intReg = SSrcReg1;
+ if (REX_W)
+ FpDestReg = intReg.SR;
+ else
+ FpDestReg = intReg.SE;
+ '''
+
+ class cvtf_i2d_hi(ConvOp):
+ code = 'FpDestReg = bits(SSrcReg1, 63, 32);'
+
+ class cvtf_d2i(ConvOp):
+ code = '''
+ int64_t intSrcReg1 = static_cast<int64_t>(FpSrcReg1);
+ if (REX_W)
+ SDestReg = intSrcReg1;
+ else
+ SDestReg = merge(SDestReg, intSrcReg1, 4);
+ '''
+
+ # These need to consider size at some point. They'll always use doubles
+ # for the moment.
+ class addfp(FpOp):
+ code = 'FpDestReg = FpSrcReg1 + FpSrcReg2;'
+
+ class mulfp(FpOp):
+ code = 'FpDestReg = FpSrcReg1 * FpSrcReg2;'
+
+ class divfp(FpOp):
+ code = 'FpDestReg = FpSrcReg1 / FpSrcReg2;'
+
+ class subfp(FpOp):
+ code = 'FpDestReg = FpSrcReg1 - FpSrcReg2;'
+
+ class Compfp(FpOp):
+ def __init__(self, src1, src2, spm=0, setStatus=False, \
+ dataSize="env.dataSize"):
+ super(Compfp, self).__init__("(int)FLOATREG_MICROFP0", \
+ src1, src2, spm, setStatus, dataSize)
+ # This class sets the condition codes in rflags according to the
+ # rules for comparing floating point.
+ code = '''
+ // ZF PF CF
+ // Unordered 1 1 1
+ // Greater than 0 0 0
+ // Less than 0 0 1
+ // Equal 1 0 0
+ // OF = SF = AF = 0
+ ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit |
+ ZFBit | PFBit | CFBit);
+ if (isnan(FpSrcReg1) || isnan(FpSrcReg2))
+ ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit);
+ else if(FpSrcReg1 < FpSrcReg2)
+ ccFlagBits = ccFlagBits | CFBit;
+ else if(FpSrcReg1 == FpSrcReg2)
+ ccFlagBits = ccFlagBits | ZFBit;
+ '''
+}};
diff --git a/src/arch/x86/isa/microops/microops.isa b/src/arch/x86/isa/microops/microops.isa
index 50c9ac498..53f34d3f2 100644
--- a/src/arch/x86/isa/microops/microops.isa
+++ b/src/arch/x86/isa/microops/microops.isa
@@ -56,6 +56,9 @@
//Common microop stuff
##include "base.isa"
+//Floating point definitions
+##include "fpop.isa"
+
//Register microop definitions
##include "regop.isa"
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index 98743e603..40a441b1e 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -458,7 +458,7 @@ let {{
class CondRegOp(RegOp):
abstract = True
- cond_check = "checkCondition(ccFlagBits)"
+ cond_check = "checkCondition(ccFlagBits, ext)"
class RdRegOp(RegOp):
abstract = True
@@ -873,67 +873,4 @@ let {{
class Zext(RegOp):
code = 'DestReg = bits(psrc1, imm8-1, 0);'
-
- class Compfp(WrRegOp):
- # This class sets the condition codes in rflags according to the
- # rules for comparing floating point.
- code = '''
- // ZF PF CF
- // Unordered 1 1 1
- // Greater than 0 0 0
- // Less than 0 0 1
- // Equal 1 0 0
- // OF = SF = AF = 0
- ccFlagBits = ccFlagBits & ~(OFBit | SFBit | AFBit |
- ZFBit | PFBit | CFBit);
- if (isnan(FpSrcReg1) || isnan(FpSrcReg2))
- ccFlagBits = ccFlagBits | (ZFBit | PFBit | CFBit);
- else if(FpSrcReg1 < FpSrcReg2)
- ccFlagBits = ccFlagBits | CFBit;
- else if(FpSrcReg1 == FpSrcReg2)
- ccFlagBits = ccFlagBits | ZFBit;
- '''
-
- class Xorfp(RegOp):
- code = 'FpDestReg.uqw = FpSrcReg1.uqw ^ FpSrcReg2.uqw;'
-
- class Sqrtfp(RegOp):
- code = 'FpDestReg = sqrt(FpSrcReg2);'
-
- class Movfp(CondRegOp):
- code = 'FpDestReg.uqw = FpSrcReg2.uqw;'
- else_code = 'FpDestReg.uqw = FpDestReg.uqw;'
-
- # Conversion microops
- class ConvOp(RegOp):
- abstract = True
- def __init__(self, dest, src1):
- super(ConvOp, self).__init__(dest, src1, "NUM_INTREGS")
-
- #FIXME This needs to always use 32 bits unless REX.W is present
- class cvtf_i2d(ConvOp):
- code = 'FpDestReg = spsrc1;'
-
- class cvtf_i2d_hi(ConvOp):
- code = 'FpDestReg = bits(SrcReg1, 63, 32);'
-
- class cvtf_d2i(ConvOp):
- code = '''
- int64_t intSrcReg1 = static_cast<int64_t>(FpSrcReg1);
- DestReg = merge(DestReg, intSrcReg1, dataSize);
- '''
-
- # These need to consider size at some point. They'll always use doubles
- # for the moment.
- class addfp(RegOp):
- code = 'FpDestReg = FpSrcReg1 + FpSrcReg2;'
-
- class mulfp(RegOp):
- code = 'FpDestReg = FpSrcReg1 * FpSrcReg2;'
-
- class divfp(RegOp):
- code = 'FpDestReg = FpSrcReg1 / FpSrcReg2;'
-
- class subfp(RegOp):
- code = 'FpDestReg = FpSrcReg1 - FpSrcReg2;'
}};
diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa
index 05a9f4418..8c0eacca2 100644
--- a/src/arch/x86/isa/operands.isa
+++ b/src/arch/x86/isa/operands.isa
@@ -96,10 +96,13 @@ def operand_types {{
def operands {{
'SrcReg1': ('IntReg', 'uqw', 'INTREG_FOLDED(src1, foldOBit)', 'IsInteger', 1),
+ 'SSrcReg1': ('IntReg', 'uqw', 'src1', 'IsInteger', 1),
'SrcReg2': ('IntReg', 'uqw', 'INTREG_FOLDED(src2, foldOBit)', 'IsInteger', 2),
+ 'SSrcReg2': ('IntReg', 'uqw', 'src2', 'IsInteger', 1),
'Index': ('IntReg', 'uqw', 'INTREG_FOLDED(index, foldABit)', 'IsInteger', 3),
'Base': ('IntReg', 'uqw', 'INTREG_FOLDED(base, foldABit)', 'IsInteger', 4),
'DestReg': ('IntReg', 'uqw', 'INTREG_FOLDED(dest, foldOBit)', 'IsInteger', 5),
+ 'SDestReg': ('IntReg', 'uqw', 'dest', 'IsInteger', 5),
'Data': ('IntReg', 'uqw', 'INTREG_FOLDED(data, foldOBit)', 'IsInteger', 6),
'ProdLow': ('IntReg', 'uqw', 'INTREG_IMPLICIT(0)', 'IsInteger', 7),
'ProdHi': ('IntReg', 'uqw', 'INTREG_IMPLICIT(1)', 'IsInteger', 8),