diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2007-09-19 18:27:55 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2007-09-19 18:27:55 -0700 |
commit | a75b6f51060ceaa52014aa4dd6aadc6ca83365f8 (patch) | |
tree | a8da313b6cf771f07ab0e1b795ea6be3137d4e29 /src/arch/x86 | |
parent | f3f3747431e001dc6c80da5b6489516b610c22d6 (diff) | |
download | gem5-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
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/SConscript | 2 | ||||
-rw-r--r-- | src/arch/x86/insts/microfpop.cc | 85 | ||||
-rw-r--r-- | src/arch/x86/insts/microfpop.hh | 104 | ||||
-rw-r--r-- | src/arch/x86/insts/microop.cc | 139 | ||||
-rw-r--r-- | src/arch/x86/insts/microop.hh | 43 | ||||
-rw-r--r-- | src/arch/x86/insts/microregop.cc | 76 | ||||
-rw-r--r-- | src/arch/x86/insts/microregop.hh | 42 | ||||
-rw-r--r-- | src/arch/x86/isa/includes.isa | 1 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/base.isa | 8 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/fpop.isa | 341 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/microops.isa | 3 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/regop.isa | 65 | ||||
-rw-r--r-- | src/arch/x86/isa/operands.isa | 3 |
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), |