From 4f7809d5e674384f58d3be6f4591afc0ceb2c37e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Jul 2007 17:14:19 -0700 Subject: Pull some hard coded base classes out of the isa description. --HG-- rename : src/arch/x86/isa/base.isa => src/arch/x86/isa/outputblock.isa extra : convert_revision : 7954e7d5eea3b5966c9e273a08bcd169a39f380c --- src/arch/x86/SConscript | 3 + src/arch/x86/insts/microldstop.cc | 79 +++++++++ src/arch/x86/insts/microldstop.hh | 102 ++++++++++++ src/arch/x86/insts/microop.hh | 100 ++++++++++++ src/arch/x86/insts/microregop.cc | 89 ++++++++++ src/arch/x86/insts/microregop.hh | 129 +++++++++++++++ src/arch/x86/insts/static_inst.cc | 192 ++++++++++++++++++++++ src/arch/x86/insts/static_inst.hh | 140 ++++++++++++++++ src/arch/x86/intregs.hh | 10 ++ src/arch/x86/isa/base.isa | 303 ----------------------------------- src/arch/x86/isa/formats/unimp.isa | 8 +- src/arch/x86/isa/includes.isa | 3 + src/arch/x86/isa/main.isa | 4 +- src/arch/x86/isa/microasm.isa | 6 +- src/arch/x86/isa/microops/base.isa | 36 ----- src/arch/x86/isa/microops/ldstop.isa | 63 +------- src/arch/x86/isa/microops/limmop.isa | 2 +- src/arch/x86/isa/microops/regop.isa | 109 ++----------- src/arch/x86/isa/microops/specop.isa | 2 +- src/arch/x86/isa/outputblock.isa | 91 +++++++++++ 20 files changed, 961 insertions(+), 510 deletions(-) create mode 100644 src/arch/x86/insts/microldstop.cc create mode 100644 src/arch/x86/insts/microldstop.hh create mode 100644 src/arch/x86/insts/microop.hh create mode 100644 src/arch/x86/insts/microregop.cc create mode 100644 src/arch/x86/insts/microregop.hh create mode 100644 src/arch/x86/insts/static_inst.cc create mode 100644 src/arch/x86/insts/static_inst.hh delete mode 100644 src/arch/x86/isa/base.isa create mode 100644 src/arch/x86/isa/outputblock.isa diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index 6de243c9c..e8f8059ce 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -87,6 +87,9 @@ Import('*') if env['TARGET_ISA'] == 'x86': Source('emulenv.cc') Source('floatregfile.cc') + Source('insts/microldstop.cc') + Source('insts/microregop.cc') + Source('insts/static_inst.cc') Source('intregfile.cc') Source('miscregfile.cc') Source('predecoder.cc') diff --git a/src/arch/x86/insts/microldstop.cc b/src/arch/x86/insts/microldstop.cc new file mode 100644 index 000000000..330a1b7bd --- /dev/null +++ b/src/arch/x86/insts/microldstop.cc @@ -0,0 +1,79 @@ +/* + * 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/microldstop.hh" +#include + +namespace X86ISA +{ + std::string LdStOp::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, instMnem, mnemonic); + printReg(response, data); + response << ", "; + printSegment(response, segment); + ccprintf(response, ":[%d*", scale); + printReg(response, index); + response << " + "; + printReg(response, base); + ccprintf(response, " + %#x]", disp); + return response.str(); + } +} diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh new file mode 100644 index 000000000..f90d6670e --- /dev/null +++ b/src/arch/x86/insts/microldstop.hh @@ -0,0 +1,102 @@ +/* + * 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_MICROLDSTOP_HH__ +#define __ARCH_X86_INSTS_MICROLDSTOP_HH__ + +#include "arch/x86/insts/microop.hh" + +namespace X86ISA +{ + /** + * Base class for load and store ops + */ + class LdStOp : public X86MicroopBase + { + protected: + const uint8_t scale; + const RegIndex index; + const RegIndex base; + const uint64_t disp; + const uint8_t segment; + const RegIndex data; + const uint8_t dataSize; + const uint8_t addressSize; + + //Constructor + LdStOp(ExtMachInst _machInst, + const char * mnem, const char * _instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + uint8_t _scale, RegIndex _index, RegIndex _base, + uint64_t _disp, uint8_t _segment, + RegIndex _data, + uint8_t _dataSize, uint8_t _addressSize, + OpClass __opClass) : + X86MicroopBase(machInst, mnem, _instMnem, + isMicro, isDelayed, isFirst, isLast, __opClass), + scale(_scale), index(_index), base(_base), + disp(_disp), segment(_segment), + data(_data), + dataSize(_dataSize), addressSize(_addressSize) + {} + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + }; +} + +#endif //__ARCH_X86_INSTS_MICROLDSTOP_HH__ diff --git a/src/arch/x86/insts/microop.hh b/src/arch/x86/insts/microop.hh new file mode 100644 index 000000000..45e1cb5c8 --- /dev/null +++ b/src/arch/x86/insts/microop.hh @@ -0,0 +1,100 @@ +/* + * 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_MICROOP_HH__ +#define __ARCH_X86_INSTS_MICROOP_HH__ + +#include "arch/x86/insts/static_inst.hh" + +namespace X86ISA +{ + //A class which is the base of all x86 micro ops. It provides a function to + //set necessary flags appropriately. + class X86MicroopBase : public X86StaticInst + { + protected: + const char * instMnem; + uint8_t opSize; + uint8_t addrSize; + + X86MicroopBase(ExtMachInst _machInst, + const char *mnem, const char *_instMnem, + bool isMicro, bool isDelayed, + bool isFirst, bool isLast, + OpClass __opClass) : + X86ISA::X86StaticInst(mnem, _machInst, __opClass), + instMnem(_instMnem) + { + flags[IsMicroop] = isMicro; + flags[IsDelayedCommit] = isDelayed; + flags[IsFirstMicroop] = isFirst; + flags[IsLastMicroop] = isLast; + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "\t%s.%s", instMnem, mnemonic); + + return ss.str(); + } + }; +} + +#endif //__ARCH_X86_INSTS_MICROOP_HH__ diff --git a/src/arch/x86/insts/microregop.cc b/src/arch/x86/insts/microregop.cc new file mode 100644 index 000000000..481d9f0ad --- /dev/null +++ b/src/arch/x86/insts/microregop.cc @@ -0,0 +1,89 @@ +/* + * 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/microregop.hh" +#include + +namespace X86ISA +{ + std::string RegOp::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, instMnem, mnemonic); + printReg(response, dest); + response << ", "; + printReg(response, src1); + response << ", "; + printReg(response, src2); + return response.str(); + } + + std::string RegOpImm::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, instMnem, mnemonic); + printReg(response, dest); + response << ", "; + printReg(response, src1); + ccprintf(response, ", %#x", imm8); + return response.str(); + } +} diff --git a/src/arch/x86/insts/microregop.hh b/src/arch/x86/insts/microregop.hh new file mode 100644 index 000000000..b20f13d55 --- /dev/null +++ b/src/arch/x86/insts/microregop.hh @@ -0,0 +1,129 @@ +/* + * 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_MICROREGOP_HH__ +#define __ARCH_X86_INSTS_MICROREGOP_HH__ + +#include "arch/x86/insts/microop.hh" + +namespace X86ISA +{ + /** + * Base classes for RegOps which provides a generateDisassembly method. + */ + class RegOp : public X86MicroopBase + { + protected: + const RegIndex src1; + const RegIndex src2; + const RegIndex dest; + const bool setStatus; + const uint8_t dataSize; + const uint8_t ext; + + // Constructor + RegOp(ExtMachInst _machInst, + const char *mnem, const char *_instMnem, + bool isMicro, bool isDelayed, + bool isFirst, bool isLast, + RegIndex _src1, RegIndex _src2, RegIndex _dest, + bool _setStatus, uint8_t _dataSize, uint8_t _ext, + OpClass __opClass) : + X86MicroopBase(_machInst, mnem, _instMnem, + isMicro, isDelayed, isFirst, isLast, + __opClass), + src1(_src1), src2(_src2), dest(_dest), + setStatus(_setStatus), dataSize(_dataSize), ext(_ext) + { + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + }; + + class RegOpImm : public X86MicroopBase + { + protected: + const RegIndex src1; + const uint8_t imm8; + const RegIndex dest; + const bool setStatus; + const uint8_t dataSize; + const uint8_t ext; + + // Constructor + RegOpImm(ExtMachInst _machInst, + const char * mnem, const char *_instMnem, + bool isMicro, bool isDelayed, + bool isFirst, bool isLast, + RegIndex _src1, uint8_t _imm8, RegIndex _dest, + bool _setStatus, uint8_t _dataSize, uint8_t _ext, + OpClass __opClass) : + X86MicroopBase(_machInst, mnem, _instMnem, + isMicro, isDelayed, isFirst, isLast, + __opClass), + src1(_src1), imm8(_imm8), dest(_dest), + setStatus(_setStatus), dataSize(_dataSize), ext(_ext) + { + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + }; +} + +#endif //__ARCH_X86_INSTS_MICROREGOP_HH__ diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc new file mode 100644 index 000000000..bf84c6e2b --- /dev/null +++ b/src/arch/x86/insts/static_inst.cc @@ -0,0 +1,192 @@ +/* + * 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/static_inst.hh" + +namespace X86ISA +{ + void X86StaticInst::printMnemonic(std::ostream &os, + const char * mnemonic) const + { + ccprintf(os, "\t%s ", mnemonic); + } + + void X86StaticInst::printMnemonic(std::ostream &os, + const char * instMnemonic, const char * mnemonic) const + { + ccprintf(os, "\t%s : %s ", instMnemonic, mnemonic); + } + + void X86StaticInst::printSegment(std::ostream &os, int segment) const + { + switch (segment) + { + case 0: + ccprintf(os, "ES"); + break; + case 1: + ccprintf(os, "CS"); + break; + case 2: + ccprintf(os, "SS"); + break; + case 3: + ccprintf(os, "DS"); + break; + case 4: + ccprintf(os, "FS"); + break; + case 5: + ccprintf(os, "GS"); + break; + default: + panic("Unrecognized segment %d\n", segment); + } + } + + void + X86StaticInst::printSrcReg(std::ostream &os, int reg) const + { + if(_numSrcRegs > reg) + printReg(os, _srcRegIdx[reg]); + } + + void + X86StaticInst::printDestReg(std::ostream &os, int reg) const + { + if(_numDestRegs > reg) + printReg(os, _destRegIdx[reg]); + } + + void + X86StaticInst::printReg(std::ostream &os, int reg) const + { + if (reg < FP_Base_DepTag) { + //FIXME These should print differently depending on the + //mode etc, but for now this will get the point across + switch (reg) { + case INTREG_RAX: + ccprintf(os, "rax"); + break; + case INTREG_RBX: + ccprintf(os, "rbx"); + break; + case INTREG_RCX: + ccprintf(os, "rcx"); + break; + case INTREG_RDX: + ccprintf(os, "rdx"); + break; + case INTREG_RSP: + ccprintf(os, "rsp"); + break; + case INTREG_RBP: + ccprintf(os, "rbp"); + break; + case INTREG_RSI: + ccprintf(os, "rsi"); + break; + case INTREG_RDI: + ccprintf(os, "rdi"); + break; + case INTREG_R8W: + ccprintf(os, "r8"); + break; + case INTREG_R9W: + ccprintf(os, "r9"); + break; + case INTREG_R10W: + ccprintf(os, "r10"); + break; + case INTREG_R11W: + ccprintf(os, "r11"); + break; + case INTREG_R12W: + ccprintf(os, "r12"); + break; + case INTREG_R13W: + ccprintf(os, "r13"); + break; + case INTREG_R14W: + ccprintf(os, "r14"); + break; + case INTREG_R15W: + ccprintf(os, "r15"); + break; + default: + ccprintf(os, "t%d", reg - NUM_INTREGS); + } + } else if (reg < Ctrl_Base_DepTag) { + ccprintf(os, "%%f%d", reg - FP_Base_DepTag); + } else { + switch (reg - Ctrl_Base_DepTag) { + default: + ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag); + } + } + } + + std::string X86StaticInst::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream ss; + + printMnemonic(ss, mnemonic); + + return ss.str(); + } +} diff --git a/src/arch/x86/insts/static_inst.hh b/src/arch/x86/insts/static_inst.hh new file mode 100644 index 000000000..3e9dbf26e --- /dev/null +++ b/src/arch/x86/insts/static_inst.hh @@ -0,0 +1,140 @@ +/* + * 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_STATICINST_HH__ +#define __ARCH_X86_INSTS_STATICINST_HH__ + +#include "cpu/static_inst.hh" + +namespace X86ISA +{ + /** + * Base class for all X86 static instructions. + */ + + class X86StaticInst : public StaticInst + { + protected: + // Constructor. + X86StaticInst(const char *mnem, + ExtMachInst _machInst, OpClass __opClass) + : StaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + + void printMnemonic(std::ostream &os, const char * mnemonic) const; + void printMnemonic(std::ostream &os, const char * instMnemonic, + const char * mnemonic) const; + + void printSegment(std::ostream &os, int segment) const; + + void printReg(std::ostream &os, int reg) const; + void printSrcReg(std::ostream &os, int reg) const; + void printDestReg(std::ostream &os, int reg) const; + + inline uint64_t merge(uint64_t into, uint64_t val, int size) const + { + X86IntReg reg; + reg = into; + //FIXME This needs to be handle high bytes as well + switch(size) + { + case 1: + reg.L = val; + break; + case 2: + reg.X = val; + break; + case 4: + //XXX Check if this should be zeroed or sign extended + reg = 0; + reg.E = val; + break; + case 8: + reg.R = val; + break; + default: + panic("Tried to merge with unrecognized size %d.\n", size); + } + return val; + } + + inline uint64_t pick(uint64_t from, int size) + { + X86IntReg reg; + reg = from; + switch(size) + { + case 1: + return reg.L; + case 2: + return reg.E; + case 4: + return reg.X; + case 8: + return reg.R; + default: + panic("Tried to pick with unrecognized size %d.\n", size); + } + } + }; +} + +#endif //__ARCH_X86_INSTS_STATICINST_HH__ diff --git a/src/arch/x86/intregs.hh b/src/arch/x86/intregs.hh index 1b5777f01..c3beb27c3 100644 --- a/src/arch/x86/intregs.hh +++ b/src/arch/x86/intregs.hh @@ -58,8 +58,18 @@ #ifndef __ARCH_X86_INTREGS_HH__ #define __ARCH_X86_INTREGS_HH__ +#include "base/bitfield.hh" + namespace X86ISA { + BitUnion64(X86IntReg) + Bitfield<63,0> R; + Bitfield<31,0> E; + Bitfield<15,0> X; + Bitfield<15,8> H; + Bitfield<7, 0> L; + EndBitUnion(X86IntReg) + enum IntRegIndex { INTREG_RAX, diff --git a/src/arch/x86/isa/base.isa b/src/arch/x86/isa/base.isa deleted file mode 100644 index eed969b47..000000000 --- a/src/arch/x86/isa/base.isa +++ /dev/null @@ -1,303 +0,0 @@ -// 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 - -//////////////////////////////////////////////////////////////////// -// -// Base class for sparc instructions, and some support functions -// - -let {{ - # This class will help make dealing with output a little less verbose - class OutputBlocks(object): - def __init__(self, header_output="", - decoder_output="", - decode_block="", - exec_output=""): - self.header_output = header_output - self.decoder_output = decoder_output - self.decode_block = decode_block - self.exec_output = exec_output - - def append(self, blocks): - if isinstance(blocks, list) or isinstance(blocks, tuple): - assert(len(blocks) == 4) - self.header_output += blocks[0] - self.decoder_output += blocks[1] - self.decode_block += blocks[2] - self.exec_output += blocks[3] - else: - self.header_output += blocks.header_output - self.decoder_output += blocks.decoder_output - self.decode_block += blocks.decode_block - self.exec_output += blocks.exec_output - - def makeList(self): - return (self.header_output, - self.decoder_output, - self.decode_block, - self.exec_output) -}}; - -output header {{ - - /** - * Base class for all X86 static instructions. - */ - BitUnion64(X86IntReg) - Bitfield<63,0> R; - Bitfield<31,0> E; - Bitfield<15,0> X; - Bitfield<15,8> H; - Bitfield<7, 0> L; - EndBitUnion(X86IntReg) - - class X86StaticInst : public StaticInst - { - protected: - // Constructor. - X86StaticInst(const char *mnem, - ExtMachInst _machInst, OpClass __opClass) - : StaticInst(mnem, _machInst, __opClass) - { - } - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - - void printReg(std::ostream &os, int reg) const; - void printSrcReg(std::ostream &os, int reg) const; - void printDestReg(std::ostream &os, int reg) const; - - inline uint64_t merge(uint64_t into, uint64_t val, int size) const - { - X86IntReg reg; - reg = into; - //FIXME This needs to be handle high bytes as well - switch(size) - { - case 1: - reg.L = val; - break; - case 2: - reg.X = val; - break; - case 4: - //XXX Check if this should be zeroed or sign extended - reg = 0; - reg.E = val; - break; - case 8: - reg.R = val; - break; - default: - panic("Tried to merge with unrecognized size %d.\n", size); - } - return val; - } - - inline uint64_t pick(uint64_t from, int size) - { - X86IntReg reg; - reg = from; - switch(size) - { - case 1: - return reg.L; - case 2: - return reg.E; - case 4: - return reg.X; - case 8: - return reg.R; - default: - panic("Tried to pick with unrecognized size %d.\n", size); - } - } - - }; -}}; - -output decoder {{ - - inline void printMnemonic(std::ostream &os, const char * mnemonic) - { - ccprintf(os, "\t%s ", mnemonic); - } - - inline void printMnemonic(std::ostream &os, - const char * instMnemonic, const char * mnemonic) - { - ccprintf(os, "\t%s : %s ", instMnemonic, mnemonic); - } - - void printSegment(std::ostream &os, int segment) - { - switch (segment) - { - case 0: - ccprintf(os, "ES"); - break; - case 1: - ccprintf(os, "CS"); - break; - case 2: - ccprintf(os, "SS"); - break; - case 3: - ccprintf(os, "DS"); - break; - case 4: - ccprintf(os, "FS"); - break; - case 5: - ccprintf(os, "GS"); - break; - default: - panic("Unrecognized segment %d\n", segment); - } - } - - void - X86StaticInst::printSrcReg(std::ostream &os, int reg) const - { - if(_numSrcRegs > reg) - printReg(os, _srcRegIdx[reg]); - } - - void - X86StaticInst::printDestReg(std::ostream &os, int reg) const - { - if(_numDestRegs > reg) - printReg(os, _destRegIdx[reg]); - } - - void - X86StaticInst::printReg(std::ostream &os, int reg) const - { - if (reg < FP_Base_DepTag) { - //FIXME These should print differently depending on the - //mode etc, but for now this will get the point across - switch (reg) { - case INTREG_RAX: - ccprintf(os, "rax"); - break; - case INTREG_RBX: - ccprintf(os, "rbx"); - break; - case INTREG_RCX: - ccprintf(os, "rcx"); - break; - case INTREG_RDX: - ccprintf(os, "rdx"); - break; - case INTREG_RSP: - ccprintf(os, "rsp"); - break; - case INTREG_RBP: - ccprintf(os, "rbp"); - break; - case INTREG_RSI: - ccprintf(os, "rsi"); - break; - case INTREG_RDI: - ccprintf(os, "rdi"); - break; - case INTREG_R8W: - ccprintf(os, "r8"); - break; - case INTREG_R9W: - ccprintf(os, "r9"); - break; - case INTREG_R10W: - ccprintf(os, "r10"); - break; - case INTREG_R11W: - ccprintf(os, "r11"); - break; - case INTREG_R12W: - ccprintf(os, "r12"); - break; - case INTREG_R13W: - ccprintf(os, "r13"); - break; - case INTREG_R14W: - ccprintf(os, "r14"); - break; - case INTREG_R15W: - ccprintf(os, "r15"); - break; - default: - ccprintf(os, "t%d", reg - NUM_INTREGS); - } - } else if (reg < Ctrl_Base_DepTag) { - ccprintf(os, "%%f%d", reg - FP_Base_DepTag); - } else { - switch (reg - Ctrl_Base_DepTag) { - default: - ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag); - } - } - } - - std::string X86StaticInst::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - std::stringstream ss; - - printMnemonic(ss, mnemonic); - - return ss.str(); - } -}}; diff --git a/src/arch/x86/isa/formats/unimp.isa b/src/arch/x86/isa/formats/unimp.isa index 12fa8387b..183beb3b8 100644 --- a/src/arch/x86/isa/formats/unimp.isa +++ b/src/arch/x86/isa/formats/unimp.isa @@ -68,12 +68,12 @@ output header {{ * 'Unknown' class is used for unrecognized/illegal instructions. * This is a leaf class. */ - class FailUnimplemented : public X86StaticInst + class FailUnimplemented : public X86ISA::X86StaticInst { public: /// Constructor FailUnimplemented(const char *_mnemonic, ExtMachInst _machInst) - : X86StaticInst(_mnemonic, _machInst, No_OpClass) + : X86ISA::X86StaticInst(_mnemonic, _machInst, No_OpClass) { // don't call execute() (which panics) if we're on a // speculative path @@ -95,7 +95,7 @@ output header {{ * probably make the 'warned' flag a static member of the derived * class. */ - class WarnUnimplemented : public X86StaticInst + class WarnUnimplemented : public X86ISA::X86StaticInst { private: /// Have we warned on this instruction yet? @@ -104,7 +104,7 @@ output header {{ public: /// Constructor WarnUnimplemented(const char *_mnemonic, ExtMachInst _machInst) - : X86StaticInst(_mnemonic, _machInst, No_OpClass), warned(false) + : X86ISA::X86StaticInst(_mnemonic, _machInst, No_OpClass), warned(false) { // don't call execute() (which panics) if we're on a // speculative path diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index 4f27c72f5..d1c76c252 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -97,6 +97,9 @@ output header {{ #include #include "arch/x86/emulenv.hh" +#include "arch/x86/insts/microldstop.hh" +#include "arch/x86/insts/microregop.hh" +#include "arch/x86/insts/static_inst.hh" #include "arch/x86/isa_traits.hh" #include "arch/x86/regfile.hh" #include "arch/x86/types.hh" diff --git a/src/arch/x86/isa/main.isa b/src/arch/x86/isa/main.isa index fed8903c0..73cebc12b 100644 --- a/src/arch/x86/isa/main.isa +++ b/src/arch/x86/isa/main.isa @@ -79,8 +79,8 @@ namespace X86ISA; //Include the bitfield definitions ##include "bitfields.isa" -//Include the base class for x86 instructions, and some support code. -##include "base.isa" +//Include the OutputBlocks class which is used to bundle output. +##include "outputblock.isa" //Include the definitions for the instruction formats ##include "formats/formats.isa" diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index ee2b92f53..afe8ae64c 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -56,9 +56,9 @@ // Authors: Gabe Black //Include the definitions of the micro ops. -//These are StaticInst classes which stand on their own and make up an -//internal instruction set, and also python representations which are passed -//into the microcode assembler. +//These are python representations of static insts which stand on their own +//and make up an internal instruction set. They are used by the micro +//assembler. ##include "microops/microops.isa" //Include code to build macroops in both C++ and python. diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa index 79ac4493a..71fc3b3a5 100644 --- a/src/arch/x86/isa/microops/base.isa +++ b/src/arch/x86/isa/microops/base.isa @@ -61,42 +61,6 @@ let {{ microopClasses = {} }}; -//A class which is the base of all x86 micro ops. It provides a function to -//set necessary flags appropriately. -output header {{ - class X86MicroopBase : public X86StaticInst - { - protected: - const char * instMnem; - uint8_t opSize; - uint8_t addrSize; - - X86MicroopBase(ExtMachInst _machInst, - const char *mnem, const char *_instMnem, - bool isMicro, bool isDelayed, - bool isFirst, bool isLast, - OpClass __opClass) : - X86StaticInst(mnem, _machInst, __opClass), - instMnem(_instMnem) - { - flags[IsMicroop] = isMicro; - flags[IsDelayedCommit] = isDelayed; - flags[IsFirstMicroop] = isFirst; - flags[IsLastMicroop] = isLast; - } - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "\t%s.%s", instMnem, mnemonic); - - return ss.str(); - } - }; -}}; - ////////////////////////////////////////////////////////////////////////// // // Base class for the python representation of x86 microops diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index fbff899a0..2e98a42bf 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -59,63 +59,6 @@ // ////////////////////////////////////////////////////////////////////////// -output header {{ - /** - * Base class for load and store ops - */ - class LdStOp : public X86MicroopBase - { - protected: - const uint8_t scale; - const RegIndex index; - const RegIndex base; - const uint64_t disp; - const uint8_t segment; - const RegIndex data; - const uint8_t dataSize; - const uint8_t addressSize; - - //Constructor - LdStOp(ExtMachInst _machInst, - const char * mnem, const char * _instMnem, - bool isMicro, bool isDelayed, bool isFirst, bool isLast, - uint8_t _scale, RegIndex _index, RegIndex _base, - uint64_t _disp, uint8_t _segment, - RegIndex _data, - uint8_t _dataSize, uint8_t _addressSize, - OpClass __opClass) : - X86MicroopBase(machInst, mnem, _instMnem, - isMicro, isDelayed, isFirst, isLast, __opClass), - scale(_scale), index(_index), base(_base), - disp(_disp), segment(_segment), - data(_data), - dataSize(_dataSize), addressSize(_addressSize) - {} - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - std::string LdStOp::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - std::stringstream response; - - printMnemonic(response, instMnem, mnemonic); - printReg(response, data); - response << ", "; - printSegment(response, segment); - ccprintf(response, ":[%d*", scale); - printReg(response, index); - response << " + "; - printReg(response, base); - ccprintf(response, " + %#x]", disp); - return response.str(); - } -}}; - // LEA template def template MicroLeaExecute {{ @@ -424,7 +367,7 @@ let {{ name = mnemonic.lower() # Build up the all register version of this micro op - iop = InstObjParams(name, Name, 'LdStOp', + iop = InstObjParams(name, Name, 'X86ISA::LdStOp', {"code": code, "ea_code": calculateEA}) header_output += MicroLdStOpDeclare.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop) @@ -451,7 +394,7 @@ let {{ name = mnemonic.lower() # Build up the all register version of this micro op - iop = InstObjParams(name, Name, 'LdStOp', + iop = InstObjParams(name, Name, 'X86ISA::LdStOp', {"code": code, "ea_code": calculateEA}) header_output += MicroLdStOpDeclare.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop) @@ -469,7 +412,7 @@ let {{ defineMicroLoadOp('St', 'Mem = Data;') - iop = InstObjParams("lea", "Lea", 'LdStOp', + iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', {"code": "Data = merge(Data, EA, dataSize);", "ea_code": calculateEA}) header_output += MicroLeaDeclare.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop) diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa index 141d7523f..177a914ae 100644 --- a/src/arch/x86/isa/microops/limmop.isa +++ b/src/arch/x86/isa/microops/limmop.isa @@ -72,7 +72,7 @@ def template MicroLimmOpExecute {{ }}; def template MicroLimmOpDeclare {{ - class %(class_name)s : public X86MicroopBase + class %(class_name)s : public X86ISA::X86MicroopBase { protected: const RegIndex dest; diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 65b75fab8..542b517fb 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -59,100 +59,6 @@ // ////////////////////////////////////////////////////////////////////////// -output header {{ - /** - * Base classes for RegOps which provides a generateDisassembly method. - */ - class RegOp : public X86MicroopBase - { - protected: - const RegIndex src1; - const RegIndex src2; - const RegIndex dest; - const bool setStatus; - const uint8_t dataSize; - const uint8_t ext; - - // Constructor - RegOp(ExtMachInst _machInst, - const char *mnem, const char *_instMnem, - bool isMicro, bool isDelayed, - bool isFirst, bool isLast, - RegIndex _src1, RegIndex _src2, RegIndex _dest, - bool _setStatus, uint8_t _dataSize, uint8_t _ext, - OpClass __opClass) : - X86MicroopBase(_machInst, mnem, _instMnem, - isMicro, isDelayed, isFirst, isLast, - __opClass), - src1(_src1), src2(_src2), dest(_dest), - setStatus(_setStatus), dataSize(_dataSize), ext(_ext) - { - } - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - }; - - class RegOpImm : public X86MicroopBase - { - protected: - const RegIndex src1; - const uint8_t imm8; - const RegIndex dest; - const bool setStatus; - const uint8_t dataSize; - const uint8_t ext; - - // Constructor - RegOpImm(ExtMachInst _machInst, - const char * mnem, const char *_instMnem, - bool isMicro, bool isDelayed, - bool isFirst, bool isLast, - RegIndex _src1, uint8_t _imm8, RegIndex _dest, - bool _setStatus, uint8_t _dataSize, uint8_t _ext, - OpClass __opClass) : - X86MicroopBase(_machInst, mnem, _instMnem, - isMicro, isDelayed, isFirst, isLast, - __opClass), - src1(_src1), imm8(_imm8), dest(_dest), - setStatus(_setStatus), dataSize(_dataSize), ext(_ext) - { - } - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - std::string RegOp::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - std::stringstream response; - - printMnemonic(response, instMnem, mnemonic); - printReg(response, dest); - response << ", "; - printReg(response, src1); - response << ", "; - printReg(response, src2); - return response.str(); - } - - std::string RegOpImm::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - std::stringstream response; - - printMnemonic(response, instMnem, mnemonic); - printReg(response, dest); - response << ", "; - printReg(response, src1); - ccprintf(response, ", %#x", imm8); - return response.str(); - } -}}; - def template MicroRegOpExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const @@ -391,7 +297,8 @@ let {{ self.className = Name self.mnemonic = name - setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild, flagCode); + setUpMicroRegOp(name, Name, "X86ISA::RegOp", \ + regCode, RegOpChild, flagCode); # Build the immediate version of this micro op class RegOpChildImm(RegOpImm): @@ -400,7 +307,8 @@ let {{ self.className = Name + "Imm" self.mnemonic = name + "i" - setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, flagCode); + setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", \ + immCode, RegOpChildImm, flagCode); defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to set OF,CF,SF defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)', "") @@ -431,7 +339,7 @@ let {{ self.className = Name self.mnemonic = name - setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild, ""); + setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, RegOpChild, ""); # Build the immediate version of this micro op class RegOpChildImm(RegOpImm): @@ -440,7 +348,8 @@ let {{ self.className = Name + "Imm" self.mnemonic = name + "i" - setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm, ""); + setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", \ + immCode, RegOpChildImm, ""); defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2') @@ -455,7 +364,7 @@ let {{ self.className = Name self.mnemonic = name - setUpMicroRegOp(name, Name, "RegOp", code, RegOpChild, ""); + setUpMicroRegOp(name, Name, "X86ISA::RegOp", code, RegOpChild, ""); defineMicroRegOpRd('Rdip', 'DestReg = RIP') @@ -469,7 +378,7 @@ let {{ self.className = Name self.mnemonic = name - setUpMicroRegOp(name, Name, "RegOpImm", code, RegOpChild, ""); + setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, RegOpChild, ""); defineMicroRegOpImm('Sext', ''' IntReg val = SrcReg1; diff --git a/src/arch/x86/isa/microops/specop.isa b/src/arch/x86/isa/microops/specop.isa index b56223390..4d9957587 100644 --- a/src/arch/x86/isa/microops/specop.isa +++ b/src/arch/x86/isa/microops/specop.isa @@ -60,7 +60,7 @@ ////////////////////////////////////////////////////////////////////////// output header {{ - class MicroFault : public X86MicroopBase + class MicroFault : public X86ISA::X86MicroopBase { protected: Fault fault; diff --git a/src/arch/x86/isa/outputblock.isa b/src/arch/x86/isa/outputblock.isa new file mode 100644 index 000000000..342d6ac4b --- /dev/null +++ b/src/arch/x86/isa/outputblock.isa @@ -0,0 +1,91 @@ +// 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 + +//////////////////////////////////////////////////////////////////// +// +// Output blocks which group together code generated by the parser. +// + +let {{ + # This class will help make dealing with output a little less verbose + class OutputBlocks(object): + def __init__(self, header_output="", + decoder_output="", + decode_block="", + exec_output=""): + self.header_output = header_output + self.decoder_output = decoder_output + self.decode_block = decode_block + self.exec_output = exec_output + + def append(self, blocks): + if isinstance(blocks, list) or isinstance(blocks, tuple): + assert(len(blocks) == 4) + self.header_output += blocks[0] + self.decoder_output += blocks[1] + self.decode_block += blocks[2] + self.exec_output += blocks[3] + else: + self.header_output += blocks.header_output + self.decoder_output += blocks.decoder_output + self.decode_block += blocks.decode_block + self.exec_output += blocks.exec_output + + def makeList(self): + return (self.header_output, + self.decoder_output, + self.decode_block, + self.exec_output) +}}; -- cgit v1.2.3 From 873b762d4b7ced232782c937e6927d1f007e82eb Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Jul 2007 17:28:26 -0700 Subject: Move bitunion code into it's own file. --HG-- extra : convert_revision : 8d55ca9645ee4e357b7f4595435542eb72490331 --- src/arch/x86/intregs.hh | 2 +- src/arch/x86/types.hh | 2 +- src/base/bitfield.hh | 269 ------------------------------------------ src/base/bitunion.hh | 306 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 308 insertions(+), 271 deletions(-) create mode 100644 src/base/bitunion.hh diff --git a/src/arch/x86/intregs.hh b/src/arch/x86/intregs.hh index c3beb27c3..bfec7d041 100644 --- a/src/arch/x86/intregs.hh +++ b/src/arch/x86/intregs.hh @@ -58,7 +58,7 @@ #ifndef __ARCH_X86_INTREGS_HH__ #define __ARCH_X86_INTREGS_HH__ -#include "base/bitfield.hh" +#include "base/bitunion.hh" namespace X86ISA { diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh index 61ab2bac9..ef4d2e5c4 100644 --- a/src/arch/x86/types.hh +++ b/src/arch/x86/types.hh @@ -61,7 +61,7 @@ #include #include -#include "base/bitfield.hh" +#include "base/bitunion.hh" #include "base/cprintf.hh" namespace X86ISA diff --git a/src/base/bitfield.hh b/src/base/bitfield.hh index 70a46386e..664093fa2 100644 --- a/src/base/bitfield.hh +++ b/src/base/bitfield.hh @@ -161,273 +161,4 @@ findMsbSet(uint64_t val) { return msb; } -// The following implements the BitUnion system of defining bitfields -//on top of an underlying class. This is done through the pervasive use of -//both named and unnamed unions which all contain the same actual storage. -//Since they're unioned with each other, all of these storage locations -//overlap. This allows all of the bitfields to manipulate the same data -//without having to have access to each other. More details are provided with the -//individual components. - -//This namespace is for classes which implement the backend of the BitUnion -//stuff. Don't use any of these directly, except for the Bitfield classes in -//the *BitfieldTypes class(es). -namespace BitfieldBackend -{ - //A base class for all bitfields. It instantiates the actual storage, - //and provides getBits and setBits functions for manipulating it. The - //Data template parameter is type of the underlying storage. - template - class BitfieldBase - { - protected: - Data __data; - - //This function returns a range of bits from the underlying storage. - //It relies on the "bits" function above. It's the user's - //responsibility to make sure that there is a properly overloaded - //version of this function for whatever type they want to overlay. - inline uint64_t - getBits(int first, int last) const - { - return bits(__data, first, last); - } - - //Similar to the above, but for settings bits with replaceBits. - inline void - setBits(int first, int last, uint64_t val) - { - replaceBits(__data, first, last, val); - } - }; - - //This class contains all the "regular" bitfield classes. It is inherited - //by all BitUnions which give them access to those types. - template - class RegularBitfieldTypes - { - protected: - //This class implements ordinary bitfields, that is a span of bits - //who's msb is "first", and who's lsb is "last". - template - class Bitfield : public BitfieldBase - { - public: - operator uint64_t () const - { - return this->getBits(first, last); - } - - uint64_t - operator=(const uint64_t _data) - { - this->setBits(first, last, _data); - return _data; - } - }; - - //A class which specializes the above so that it can only be read - //from. This is accomplished explicitly making sure the assignment - //operator is blocked. The conversion operator is carried through - //inheritance. This will unfortunately need to be copied into each - //bitfield type due to limitations with how templates work - template - class BitfieldRO : public Bitfield - { - private: - uint64_t - operator=(const uint64_t _data); - }; - - //Similar to the above, but only allows writing. - template - class BitfieldWO : public Bitfield - { - private: - operator uint64_t () const; - - public: - using Bitfield::operator=; - }; - }; - - //This class contains all the "regular" bitfield classes. It is inherited - //by all BitUnions which give them access to those types. - template - class SignedBitfieldTypes - { - protected: - //This class implements ordinary bitfields, that is a span of bits - //who's msb is "first", and who's lsb is "last". - template - class SignedBitfield : public BitfieldBase - { - public: - operator int64_t () const - { - return sext(this->getBits(first, last)); - } - - int64_t - operator=(const int64_t _data) - { - this->setBits(first, last, _data); - return _data; - } - }; - - //A class which specializes the above so that it can only be read - //from. This is accomplished explicitly making sure the assignment - //operator is blocked. The conversion operator is carried through - //inheritance. This will unfortunately need to be copied into each - //bitfield type due to limitations with how templates work - template - class SignedBitfieldRO : public SignedBitfield - { - private: - int64_t - operator=(const int64_t _data); - }; - - //Similar to the above, but only allows writing. - template - class SignedBitfieldWO : public SignedBitfield - { - private: - operator int64_t () const; - - public: - int64_t operator=(const int64_t _data) - { - *((SignedBitfield *)this) = _data; - return _data; - } - }; - }; - - template - class BitfieldTypes : public RegularBitfieldTypes, - public SignedBitfieldTypes - {}; - - //When a BitUnion is set up, an underlying class is created which holds - //the actual union. This class then inherits from it, and provids the - //implementations for various operators. Setting things up this way - //prevents having to redefine these functions in every different BitUnion - //type. More operators could be implemented in the future, as the need - //arises. - template - class BitUnionOperators : public Base - { - public: - operator Type () const - { - return Base::__data; - } - - Type - operator=(const Type & _data) - { - Base::__data = _data; - return _data; - } - - bool - operator<(const Base & base) const - { - return Base::__data < base.__data; - } - - bool - operator==(const Base & base) const - { - return Base::__data == base.__data; - } - }; -} - -//This macro is a backend for other macros that specialize it slightly. -//First, it creates/extends a namespace "BitfieldUnderlyingClasses" and -//sticks the class which has the actual union in it, which -//BitfieldOperators above inherits from. Putting these classes in a special -//namespace ensures that there will be no collisions with other names as long -//as the BitUnion names themselves are all distinct and nothing else uses -//the BitfieldUnderlyingClasses namespace, which is unlikely. The class itself -//creates a typedef of the "type" parameter called __DataType. This allows -//the type to propagate outside of the macro itself in a controlled way. -//Finally, the base storage is defined which BitfieldOperators will refer to -//in the operators it defines. This macro is intended to be followed by -//bitfield definitions which will end up inside it's union. As explained -//above, these is overlayed the __data member in its entirety by each of the -//bitfields which are defined in the union, creating shared storage with no -//overhead. -#define __BitUnion(type, name) \ - namespace BitfieldUnderlyingClasses \ - { \ - class name; \ - } \ - class BitfieldUnderlyingClasses::name : \ - public BitfieldBackend::BitfieldTypes \ - { \ - public: \ - typedef type __DataType; \ - union { \ - type __data;\ - -//This closes off the class and union started by the above macro. It is -//followed by a typedef which makes "name" refer to a BitfieldOperator -//class inheriting from the class and union just defined, which completes -//building up the type for the user. -#define EndBitUnion(name) \ - }; \ - }; \ - typedef BitfieldBackend::BitUnionOperators< \ - BitfieldUnderlyingClasses::name::__DataType, \ - BitfieldUnderlyingClasses::name> name; - -//This sets up a bitfield which has other bitfields nested inside of it. The -//__data member functions like the "underlying storage" of the top level -//BitUnion. Like everything else, it overlays with the top level storage, so -//making it a regular bitfield type makes the entire thing function as a -//regular bitfield when referred to by itself. -#define __SubBitUnion(fieldType, first, last, name) \ - class : public BitfieldBackend::BitfieldTypes<__DataType> \ - { \ - public: \ - union { \ - fieldType __data; - -//This closes off the union created above and gives it a name. Unlike the top -//level BitUnion, we're interested in creating an object instead of a type. -//The operators are defined in the macro itself instead of a class for -//technical reasons. If someone determines a way to move them to one, please -//do so. -#define EndSubBitUnion(name) \ - }; \ - inline operator const __DataType () \ - { return __data; } \ - \ - inline const __DataType operator = (const __DataType & _data) \ - { __data = _data; } \ - } name; - -//Regular bitfields -//These define macros for read/write regular bitfield based subbitfields. -#define SubBitUnion(name, first, last) \ - __SubBitUnion(Bitfield, first, last, name) - -//Regular bitfields -//These define macros for read/write regular bitfield based subbitfields. -#define SignedSubBitUnion(name, first, last) \ - __SubBitUnion(SignedBitfield, first, last, name) - -//Use this to define an arbitrary type overlayed with bitfields. -#define BitUnion(type, name) __BitUnion(type, name) - -//Use this to define conveniently sized values overlayed with bitfields. -#define BitUnion64(name) __BitUnion(uint64_t, name) -#define BitUnion32(name) __BitUnion(uint32_t, name) -#define BitUnion16(name) __BitUnion(uint16_t, name) -#define BitUnion8(name) __BitUnion(uint8_t, name) - #endif // __BASE_BITFIELD_HH__ diff --git a/src/base/bitunion.hh b/src/base/bitunion.hh new file mode 100644 index 000000000..55553fd9c --- /dev/null +++ b/src/base/bitunion.hh @@ -0,0 +1,306 @@ +/* + * 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. + * + * Authors: Gabe Black + */ + +#ifndef __BASE_BITUNION_HH__ +#define __BASE_BITUNION_HH__ + +#include +#include "base/bitfield.hh" + +// The following implements the BitUnion system of defining bitfields +//on top of an underlying class. This is done through the pervasive use of +//both named and unnamed unions which all contain the same actual storage. +//Since they're unioned with each other, all of these storage locations +//overlap. This allows all of the bitfields to manipulate the same data +//without having to have access to each other. More details are provided with +//the individual components. + +//This namespace is for classes which implement the backend of the BitUnion +//stuff. Don't use any of these directly, except for the Bitfield classes in +//the *BitfieldTypes class(es). +namespace BitfieldBackend +{ + //A base class for all bitfields. It instantiates the actual storage, + //and provides getBits and setBits functions for manipulating it. The + //Data template parameter is type of the underlying storage. + template + class BitfieldBase + { + protected: + Data __data; + + //This function returns a range of bits from the underlying storage. + //It relies on the "bits" function above. It's the user's + //responsibility to make sure that there is a properly overloaded + //version of this function for whatever type they want to overlay. + inline uint64_t + getBits(int first, int last) const + { + return bits(__data, first, last); + } + + //Similar to the above, but for settings bits with replaceBits. + inline void + setBits(int first, int last, uint64_t val) + { + replaceBits(__data, first, last, val); + } + }; + + //This class contains all the "regular" bitfield classes. It is inherited + //by all BitUnions which give them access to those types. + template + class RegularBitfieldTypes + { + protected: + //This class implements ordinary bitfields, that is a span of bits + //who's msb is "first", and who's lsb is "last". + template + class Bitfield : public BitfieldBase + { + public: + operator uint64_t () const + { + return this->getBits(first, last); + } + + uint64_t + operator=(const uint64_t _data) + { + this->setBits(first, last, _data); + return _data; + } + }; + + //A class which specializes the above so that it can only be read + //from. This is accomplished explicitly making sure the assignment + //operator is blocked. The conversion operator is carried through + //inheritance. This will unfortunately need to be copied into each + //bitfield type due to limitations with how templates work + template + class BitfieldRO : public Bitfield + { + private: + uint64_t + operator=(const uint64_t _data); + }; + + //Similar to the above, but only allows writing. + template + class BitfieldWO : public Bitfield + { + private: + operator uint64_t () const; + + public: + using Bitfield::operator=; + }; + }; + + //This class contains all the "regular" bitfield classes. It is inherited + //by all BitUnions which give them access to those types. + template + class SignedBitfieldTypes + { + protected: + //This class implements ordinary bitfields, that is a span of bits + //who's msb is "first", and who's lsb is "last". + template + class SignedBitfield : public BitfieldBase + { + public: + operator int64_t () const + { + return sext(this->getBits(first, last)); + } + + int64_t + operator=(const int64_t _data) + { + this->setBits(first, last, _data); + return _data; + } + }; + + //A class which specializes the above so that it can only be read + //from. This is accomplished explicitly making sure the assignment + //operator is blocked. The conversion operator is carried through + //inheritance. This will unfortunately need to be copied into each + //bitfield type due to limitations with how templates work + template + class SignedBitfieldRO : public SignedBitfield + { + private: + int64_t + operator=(const int64_t _data); + }; + + //Similar to the above, but only allows writing. + template + class SignedBitfieldWO : public SignedBitfield + { + private: + operator int64_t () const; + + public: + int64_t operator=(const int64_t _data) + { + *((SignedBitfield *)this) = _data; + return _data; + } + }; + }; + + template + class BitfieldTypes : public RegularBitfieldTypes, + public SignedBitfieldTypes + {}; + + //When a BitUnion is set up, an underlying class is created which holds + //the actual union. This class then inherits from it, and provids the + //implementations for various operators. Setting things up this way + //prevents having to redefine these functions in every different BitUnion + //type. More operators could be implemented in the future, as the need + //arises. + template + class BitUnionOperators : public Base + { + public: + operator Type () const + { + return Base::__data; + } + + Type + operator=(const Type & _data) + { + Base::__data = _data; + return _data; + } + + bool + operator<(const Base & base) const + { + return Base::__data < base.__data; + } + + bool + operator==(const Base & base) const + { + return Base::__data == base.__data; + } + }; +} + +//This macro is a backend for other macros that specialize it slightly. +//First, it creates/extends a namespace "BitfieldUnderlyingClasses" and +//sticks the class which has the actual union in it, which +//BitfieldOperators above inherits from. Putting these classes in a special +//namespace ensures that there will be no collisions with other names as long +//as the BitUnion names themselves are all distinct and nothing else uses +//the BitfieldUnderlyingClasses namespace, which is unlikely. The class itself +//creates a typedef of the "type" parameter called __DataType. This allows +//the type to propagate outside of the macro itself in a controlled way. +//Finally, the base storage is defined which BitfieldOperators will refer to +//in the operators it defines. This macro is intended to be followed by +//bitfield definitions which will end up inside it's union. As explained +//above, these is overlayed the __data member in its entirety by each of the +//bitfields which are defined in the union, creating shared storage with no +//overhead. +#define __BitUnion(type, name) \ + namespace BitfieldUnderlyingClasses \ + { \ + class name; \ + } \ + class BitfieldUnderlyingClasses::name : \ + public BitfieldBackend::BitfieldTypes \ + { \ + public: \ + typedef type __DataType; \ + union { \ + type __data;\ + +//This closes off the class and union started by the above macro. It is +//followed by a typedef which makes "name" refer to a BitfieldOperator +//class inheriting from the class and union just defined, which completes +//building up the type for the user. +#define EndBitUnion(name) \ + }; \ + }; \ + typedef BitfieldBackend::BitUnionOperators< \ + BitfieldUnderlyingClasses::name::__DataType, \ + BitfieldUnderlyingClasses::name> name; + +//This sets up a bitfield which has other bitfields nested inside of it. The +//__data member functions like the "underlying storage" of the top level +//BitUnion. Like everything else, it overlays with the top level storage, so +//making it a regular bitfield type makes the entire thing function as a +//regular bitfield when referred to by itself. +#define __SubBitUnion(fieldType, first, last, name) \ + class : public BitfieldBackend::BitfieldTypes<__DataType> \ + { \ + public: \ + union { \ + fieldType __data; + +//This closes off the union created above and gives it a name. Unlike the top +//level BitUnion, we're interested in creating an object instead of a type. +//The operators are defined in the macro itself instead of a class for +//technical reasons. If someone determines a way to move them to one, please +//do so. +#define EndSubBitUnion(name) \ + }; \ + inline operator const __DataType () \ + { return __data; } \ + \ + inline const __DataType operator = (const __DataType & _data) \ + { __data = _data; } \ + } name; + +//Regular bitfields +//These define macros for read/write regular bitfield based subbitfields. +#define SubBitUnion(name, first, last) \ + __SubBitUnion(Bitfield, first, last, name) + +//Regular bitfields +//These define macros for read/write regular bitfield based subbitfields. +#define SignedSubBitUnion(name, first, last) \ + __SubBitUnion(SignedBitfield, first, last, name) + +//Use this to define an arbitrary type overlayed with bitfields. +#define BitUnion(type, name) __BitUnion(type, name) + +//Use this to define conveniently sized values overlayed with bitfields. +#define BitUnion64(name) __BitUnion(uint64_t, name) +#define BitUnion32(name) __BitUnion(uint32_t, name) +#define BitUnion16(name) __BitUnion(uint16_t, name) +#define BitUnion8(name) __BitUnion(uint8_t, name) + +#endif // __BASE_BITUNION_HH__ -- cgit v1.2.3 From 13ccac1a3cb7bb33b7a6d2c65f875d1a40a6e352 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 17 Jul 2007 13:23:42 -0700 Subject: Add a conversion constructor so a bitunion can be initialized to a value. Previously, the bitunion would need to be declared and then assigned to separately. --HG-- extra : convert_revision : d229bd83bc7baeca2259d4e7b080f359915015f3 --- src/base/bitunion.hh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/base/bitunion.hh b/src/base/bitunion.hh index 55553fd9c..98861e779 100644 --- a/src/base/bitunion.hh +++ b/src/base/bitunion.hh @@ -193,6 +193,13 @@ namespace BitfieldBackend class BitUnionOperators : public Base { public: + BitUnionOperators(Type & _data) + { + Base::__data = _data; + } + + BitUnionOperators() {} + operator Type () const { return Base::__data; -- cgit v1.2.3 From aad11bf879913131670dc5afc1d98de5b6f381a3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 17 Jul 2007 13:26:06 -0700 Subject: Add a spot for the condition code portion of the flag register. This is stored in the integer register file so that it can be renamed, but it should be a misc reg. --HG-- extra : convert_revision : eee48f24dd80b145f14427482047c4d8af2521ab --- src/arch/x86/intregfile.hh | 3 ++- src/arch/x86/x86_traits.hh | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/arch/x86/intregfile.hh b/src/arch/x86/intregfile.hh index f7b03f0f0..be6242a41 100644 --- a/src/arch/x86/intregfile.hh +++ b/src/arch/x86/intregfile.hh @@ -104,7 +104,8 @@ namespace X86ISA std::string getIntRegName(RegIndex); const int NumIntArchRegs = NUM_INTREGS; - const int NumIntRegs = NumIntArchRegs + NumMicroIntRegs; + const int NumIntRegs = + NumIntArchRegs + NumMicroIntRegs + NumPseudoIntRegs; class IntRegFile { diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh index e45d62f8f..5794e7079 100644 --- a/src/arch/x86/x86_traits.hh +++ b/src/arch/x86/x86_traits.hh @@ -61,6 +61,7 @@ namespace X86ISA { const int NumMicroIntRegs = 16; + const int NumPseudoIntRegs = 1; const int NumMMXRegs = 8; const int NumXMMRegs = 16; -- cgit v1.2.3 From 8f3153ffb3ee5f838fc3aef7ac3b481792487b4f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 17 Jul 2007 13:28:03 -0700 Subject: Create a file of functions for computing condition codes. These haven't been very thuroughly tested, so use at your own risk. --HG-- extra : convert_revision : 938885d36fea4a99f8228cdf195a0e0a38dd9031 --- src/base/condcodes.hh | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/base/condcodes.hh diff --git a/src/base/condcodes.hh b/src/base/condcodes.hh new file mode 100644 index 000000000..10109e4ad --- /dev/null +++ b/src/base/condcodes.hh @@ -0,0 +1,91 @@ +/* + * 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. + * + * Authors: Gabe Black + */ + +#ifndef __BASE_CONDCODE_HH__ +#define __BASE_CONDCODE_HH__ + +#include "base/bitfield.hh" + +/** + * Calculate the carry flag from an addition. This should work even when + * a carry value is also added in. + */ +inline +bool +findCarry(int width, uint64_t dest, uint64_t src1, uint64_t src2) { + int shift = width - 1; + return (~(dest >> shift) + (src1 >> shift) + (src2 >> shift)) & 0x2; +} + +/** + * Calculate the overflow flag from an addition. + */ +inline +bool +findOverflow(int width, uint64_t dest, uint64_t src1, uint64_t src2) { + int shift = width - 1; + return ((src1 ^ ~src2) & (src1 ^ dest)) & (1 << shift); +} + +/** + * Calculate the parity of a value. 1 is for odd parity and 0 is for even. + */ +inline +bool +findParity(int width, uint64_t dest) { + dest &= width; + dest ^= (dest >> 32); + dest ^= (dest >> 16); + dest ^= (dest >> 8); + dest ^= (dest >> 4); + dest ^= (dest >> 2); + dest ^= (dest >> 1); + return dest & 1; +} + +/** + * Calculate the negative flag. + */ +inline +bool +findNegative(int width, uint64_t dest) { + return bits(dest, width - 1, width - 1); +} + +/** + * Calculate the zero flag. + */ +inline +bool +findZero(int width, uint64_t dest) { + return !(dest & mask(width)); +} + +#endif // __BASE_CONDCODE_HH__ -- cgit v1.2.3 From b0643a08a32d14b57e774d9587c7ecba833b1ef7 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 17 Jul 2007 13:29:40 -0700 Subject: Create a file to describe misc registers. Define bitfields, indices, etc. --HG-- extra : convert_revision : 8fffdc4cf796d304b12b317d8bddf5685bd50cf4 --- src/arch/x86/miscregs.hh | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/arch/x86/miscregs.hh diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh new file mode 100644 index 000000000..57653cd8a --- /dev/null +++ b/src/arch/x86/miscregs.hh @@ -0,0 +1,88 @@ +/* + * 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_MISCREGS_HH__ +#define __ARCH_X86_MISCREGS_HH__ + +#include "base/bitunion.hh" + +namespace X86ISA +{ + enum CondFlagBit { + CFBit = 1 << 0, + PFBit = 1 << 2, + ECFBit = 1 << 3, + AFBit = 1 << 4, + EZFBit = 1 << 5, + ZFBit = 1 << 6, + SFBit = 1 << 7, + OFBit = 1 << 11 + }; + + BitUnion64(CCFlagBits) + Bitfield<11> OF; + Bitfield<7> SF; + Bitfield<6> ZF; + Bitfield<5> EZF; + Bitfield<4> AF; + Bitfield<3> ECF; + Bitfield<2> PF; + Bitfield<0> CF; + EndBitUnion(CCFlagBits) +}; + +#endif // __ARCH_X86_INTREGS_HH__ -- cgit v1.2.3 From cbc24d66001dbe3ec85f82073048d62141af2fd4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 17 Jul 2007 13:30:23 -0700 Subject: Actually include miscregs.hh --HG-- extra : convert_revision : 6ebf906d2211b94f28c173f0d2da91bd446fcb2c --- src/arch/x86/isa/includes.isa | 1 + 1 file changed, 1 insertion(+) diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index d1c76c252..58aef7b1d 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -111,6 +111,7 @@ output header {{ output decoder {{ #include "arch/x86/faults.hh" +#include "arch/x86/miscregs.hh" #include "arch/x86/segmentregs.hh" #include "base/cprintf.hh" #include "base/loader/symtab.hh" -- cgit v1.2.3 From bbf7163dd9a9c2a17cb8873f7620f2b17841ac26 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 17 Jul 2007 15:27:28 -0700 Subject: Add symbols for each of the flags a microop could set and each condition it could check. --HG-- extra : convert_revision : 1f542b8aadfd5146539cadef631b49d77f578472 --- src/arch/x86/isa/microasm.isa | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index afe8ae64c..213468b0b 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -96,6 +96,19 @@ let {{ assembler.symbols["r%s" % reg] = "INTREG_R%s" % reg.upper() assembler.symbols.update(symbols) + for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF'): + assembler.symbols[flag] = flag + "Bit" + + for cond in ('True', 'False', 'ECF', 'EZF', 'SZnZF', + 'MSTRZ', 'STRZ', 'MSTRC', 'STRZnZF', + 'OF', 'CF', 'ZF', 'CvZF', + 'SF', 'PF', 'SxOF', 'SxOvZF'): + assembler.symbols["C%s" % cond] = "ConditionTests::%s" % cond + assembler.symbols["nC%s" % cond] = "ConditionTests::Not%s" % cond + + assembler.symbols["CTrue"] = "ConditionTests::True" + assembler.symbols["CFalse"] = "ConditionTests::False" + # Code literal which forces a default 64 bit operand size in 64 bit mode. assembler.symbols["oszIn64Override"] = ''' if (machInst.mode.submode == SixtyFourBitMode && -- cgit v1.2.3 From cf846d5205c021a04ab1a8e830d9cb86be0bda6e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 17 Jul 2007 15:28:48 -0700 Subject: Add in operand which holds the condition code bits of the flag register. --HG-- extra : convert_revision : 416052f41fccc8286b3bdbe8d559512a761224f2 --- src/arch/x86/isa/operands.isa | 1 + 1 file changed, 1 insertion(+) diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index b2ac17d66..83df583ea 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -103,5 +103,6 @@ def operands {{ 'Index': ('IntReg', 'uqw', 'index', 'IsInteger', 5), 'Data': ('IntReg', 'uqw', 'data', 'IsInteger', 6), 'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 10), + 'ccFlagBits': ('IntReg', 'uqw', 'NUM_INTREGS + NumMicroIntRegs', None, 20), 'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100) }}; -- cgit v1.2.3 From a6757095c35cfdc491396cd97a32c19aacaffe2e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 17 Jul 2007 15:33:18 -0700 Subject: Add in support for condition code flags. Some microops can set the condition codes, and some of them can be predicated on them. Some of the codes aren't implemented because it was unclear from the AMD patent what they actually did. They are used with string instructions, but they use variables IP, DTF, and SSTF which don't appear to be documented. --HG-- extra : convert_revision : 2236cccd07d0091762b50148975f301bb1d2da3f --- src/arch/x86/insts/microregop.cc | 99 +++++++++++++++++ src/arch/x86/insts/microregop.hh | 97 +++++++++++++---- src/arch/x86/isa/microops/regop.isa | 204 +++++++++++++++++++++++------------- 3 files changed, 311 insertions(+), 89 deletions(-) diff --git a/src/arch/x86/insts/microregop.cc b/src/arch/x86/insts/microregop.cc index 481d9f0ad..3c60d7212 100644 --- a/src/arch/x86/insts/microregop.cc +++ b/src/arch/x86/insts/microregop.cc @@ -56,10 +56,109 @@ */ #include "arch/x86/insts/microregop.hh" +#include "arch/x86/miscregs.hh" +#include "base/condcodes.hh" #include namespace X86ISA { + uint64_t RegOpBase::genFlags(uint64_t oldFlags, uint64_t flagMask, + uint64_t _dest, uint64_t _src1, uint64_t _src2) const + { + uint64_t flags = oldFlags & ~flagMask; + if(flagMask & CFBit && findCarry(dataSize, _dest, _src1, _src2)) + flags |= CFBit; + if(flagMask & PFBit && findParity(dataSize, _dest)) + flags |= PFBit; + if(flagMask & ECFBit && findCarry(dataSize, _dest, _src1, _src2)) + flags |= ECFBit; + if(flagMask & AFBit && findCarry(4, _dest, _src1, _src2)) + flags |= AFBit; + if(flagMask & EZFBit && findZero(dataSize, _dest)) + flags |= EZFBit; + if(flagMask & ZFBit && findZero(dataSize, _dest)) + flags |= ZFBit; + if(flagMask & SFBit && findNegative(dataSize, _dest)) + flags |= SFBit; + if(flagMask & OFBit && findOverflow(dataSize, _dest, _src1, _src2)) + flags |= OFBit; + 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::STRZnZF: + panic("This condition is not implemented!"); + 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::NotSTRZnZF: + panic("This condition is not implemented!"); + 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 b20f13d55..a8049ba19 100644 --- a/src/arch/x86/insts/microregop.hh +++ b/src/arch/x86/insts/microregop.hh @@ -62,18 +62,84 @@ namespace X86ISA { + namespace ConditionTests + { + enum CondTest { + True, + NotFalse = True, + ECF, + EZF, + SZnZF, + MSTRZ, + STRZ, + MSTRC, + STRZnZF, + OF, + CF, + ZF, + CvZF, + SF, + PF, + SxOF, + SxOvZF, + + False, + NotTrue = False, + NotECF, + NotEZF, + NotSZnZF, + NotMSTRZ, + NotSTRZ, + NotMSTRC, + NotSTRZnZF, + NotOF, + NotCF, + NotZF, + NotCvZF, + NotSF, + NotPF, + NotSxOF, + NotSxOvZF + }; + } + /** * Base classes for RegOps which provides a generateDisassembly method. */ - class RegOp : public X86MicroopBase + class RegOpBase : public X86MicroopBase { protected: const RegIndex src1; - const RegIndex src2; const RegIndex dest; - const bool setStatus; const uint8_t dataSize; - const uint8_t ext; + const uint16_t ext; + + // Constructor + RegOpBase(ExtMachInst _machInst, + const char *mnem, const char *_instMnem, + bool isMicro, bool isDelayed, + bool isFirst, bool isLast, + RegIndex _src1, RegIndex _dest, + uint8_t _dataSize, uint16_t _ext, + OpClass __opClass) : + X86MicroopBase(_machInst, mnem, _instMnem, + isMicro, isDelayed, isFirst, isLast, + __opClass), + src1(_src1), dest(_dest), + dataSize(_dataSize), ext(_ext) + { + } + + //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) const; + bool checkCondition(uint64_t flags) const; + }; + + class RegOp : public RegOpBase + { + protected: + const RegIndex src2; // Constructor RegOp(ExtMachInst _machInst, @@ -81,13 +147,13 @@ namespace X86ISA bool isMicro, bool isDelayed, bool isFirst, bool isLast, RegIndex _src1, RegIndex _src2, RegIndex _dest, - bool _setStatus, uint8_t _dataSize, uint8_t _ext, + uint8_t _dataSize, uint16_t _ext, OpClass __opClass) : - X86MicroopBase(_machInst, mnem, _instMnem, + RegOpBase(_machInst, mnem, _instMnem, isMicro, isDelayed, isFirst, isLast, + _src1, _dest, _dataSize, _ext, __opClass), - src1(_src1), src2(_src2), dest(_dest), - setStatus(_setStatus), dataSize(_dataSize), ext(_ext) + src2(_src2) { } @@ -95,15 +161,10 @@ namespace X86ISA const SymbolTable *symtab) const; }; - class RegOpImm : public X86MicroopBase + class RegOpImm : public RegOpBase { protected: - const RegIndex src1; const uint8_t imm8; - const RegIndex dest; - const bool setStatus; - const uint8_t dataSize; - const uint8_t ext; // Constructor RegOpImm(ExtMachInst _machInst, @@ -111,13 +172,13 @@ namespace X86ISA bool isMicro, bool isDelayed, bool isFirst, bool isLast, RegIndex _src1, uint8_t _imm8, RegIndex _dest, - bool _setStatus, uint8_t _dataSize, uint8_t _ext, + uint8_t _dataSize, uint16_t _ext, OpClass __opClass) : - X86MicroopBase(_machInst, mnem, _instMnem, + RegOpBase(_machInst, mnem, _instMnem, isMicro, isDelayed, isFirst, isLast, + _src1, _dest, _dataSize, _ext, __opClass), - src1(_src1), imm8(_imm8), dest(_dest), - setStatus(_setStatus), dataSize(_dataSize), ext(_ext) + imm8(_imm8) { } diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 542b517fb..dd196a50d 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -67,8 +67,12 @@ def template MicroRegOpExecute {{ %(op_decl)s; %(op_rd)s; - %(code)s; - %(flag_code)s; + + if(%(cond_check)s) + { + %(code)s; + %(flag_code)s; + } //Write the resulting state to the execution context if(fault == NoFault) @@ -87,8 +91,12 @@ def template MicroRegOpImmExecute {{ %(op_decl)s; %(op_rd)s; - %(code)s; - %(flag_code)s; + + if(%(cond_check)s) + { + %(code)s; + %(flag_code)s; + } //Write the resulting state to the execution context if(fault == NoFault) @@ -110,12 +118,12 @@ def template MicroRegOpDeclare {{ const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, RegIndex _src1, RegIndex _src2, RegIndex _dest, - bool _setStatus, uint8_t _dataSize, uint8_t _ext); + uint8_t _dataSize, uint8_t _ext); %(class_name)s(ExtMachInst _machInst, const char * instMnem, RegIndex _src1, RegIndex _src2, RegIndex _dest, - bool _setStatus, uint8_t _dataSize, uint8_t _ext); + uint8_t _dataSize, uint8_t _ext); %(BasicExecDeclare)s }; @@ -133,12 +141,12 @@ def template MicroRegOpImmDeclare {{ const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, RegIndex _src1, uint8_t _imm8, RegIndex _dest, - bool _setStatus, uint8_t _dataSize, uint8_t _ext); + uint8_t _dataSize, uint8_t _ext); %(class_name)sImm(ExtMachInst _machInst, const char * instMnem, RegIndex _src1, uint8_t _imm8, RegIndex _dest, - bool _setStatus, uint8_t _dataSize, uint8_t _ext); + uint8_t _dataSize, uint8_t _ext); %(BasicExecDeclare)s }; @@ -154,10 +162,10 @@ def template MicroRegOpConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, RegIndex _src1, RegIndex _src2, RegIndex _dest, - bool _setStatus, uint8_t _dataSize, uint8_t _ext) : + uint8_t _dataSize, uint8_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, false, false, false, false, - _src1, _src2, _dest, _setStatus, _dataSize, _ext, + _src1, _src2, _dest, _dataSize, _ext, %(op_class)s) { buildMe(); @@ -167,10 +175,10 @@ def template MicroRegOpConstructor {{ ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, RegIndex _src1, RegIndex _src2, RegIndex _dest, - bool _setStatus, uint8_t _dataSize, uint8_t _ext) : + uint8_t _dataSize, uint8_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, isMicro, isDelayed, isFirst, isLast, - _src1, _src2, _dest, _setStatus, _dataSize, _ext, + _src1, _src2, _dest, _dataSize, _ext, %(op_class)s) { buildMe(); @@ -187,10 +195,10 @@ def template MicroRegOpImmConstructor {{ inline %(class_name)sImm::%(class_name)sImm( ExtMachInst machInst, const char * instMnem, RegIndex _src1, uint8_t _imm8, RegIndex _dest, - bool _setStatus, uint8_t _dataSize, uint8_t _ext) : + uint8_t _dataSize, uint8_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, false, false, false, false, - _src1, _imm8, _dest, _setStatus, _dataSize, _ext, + _src1, _imm8, _dest, _dataSize, _ext, %(op_class)s) { buildMe(); @@ -200,10 +208,10 @@ def template MicroRegOpImmConstructor {{ ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, RegIndex _src1, uint8_t _imm8, RegIndex _dest, - bool _setStatus, uint8_t _dataSize, uint8_t _ext) : + uint8_t _dataSize, uint8_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, isMicro, isDelayed, isFirst, isLast, - _src1, _imm8, _dest, _setStatus, _dataSize, _ext, + _src1, _imm8, _dest, _dataSize, _ext, %(op_class)s) { buildMe(); @@ -211,46 +219,74 @@ def template MicroRegOpImmConstructor {{ }}; let {{ + class X86MicroMeta(type): + def __new__(mcls, name, bases, dict): + abstract = False + if "abstract" in dict: + abstract = dict['abstract'] + del dict['abstract'] + + cls = type.__new__(mcls, name, bases, dict) + if not abstract: + allClasses[name] = cls + return cls + + class XXX86Microop(object): + __metaclass__ = X86MicroMeta + abstract = True + class RegOp(X86Microop): - def __init__(self, dest, src1, src2, setStatus): + abstract = True + def __init__(self, dest, src1, src2, flags): self.dest = dest self.src1 = src1 self.src2 = src2 - self.setStatus = setStatus + self.flags = flags self.dataSize = "env.dataSize" - self.ext = 0 + if flags is None: + self.ext = 0 + else: + if not isinstance(flags, (list, tuple)): + raise Exception, "flags must be a list or tuple of flags" + self.ext = " | ".join(flags) + self.className += "Flags" def getAllocator(self, *microFlags): allocator = '''new %(class_name)s(machInst, mnemonic %(flags)s, %(src1)s, %(src2)s, %(dest)s, - %(setStatus)s, %(dataSize)s, %(ext)s)''' % { + %(dataSize)s, %(ext)s)''' % { "class_name" : self.className, "flags" : self.microFlagsText(microFlags), "src1" : self.src1, "src2" : self.src2, "dest" : self.dest, - "setStatus" : self.cppBool(self.setStatus), "dataSize" : self.dataSize, "ext" : self.ext} return allocator class RegOpImm(X86Microop): - def __init__(self, dest, src1, imm8, setStatus): + abstract = True + def __init__(self, dest, src1, imm8, flags): self.dest = dest self.src1 = src1 self.imm8 = imm8 - self.setStatus = setStatus + self.flags = flags self.dataSize = "env.dataSize" - self.ext = 0 + if flags is None: + self.ext = 0 + else: + if not isinstance(flags, (list, tuple)): + raise Exception, "flags must be a list or tuple of flags" + self.ext = " | ".join(flags) + self.className += "Flags" def getAllocator(self, *microFlags): allocator = '''new %(class_name)s(machInst, mnemonic %(flags)s, %(src1)s, %(imm8)s, %(dest)s, - %(setStatus)s, %(dataSize)s, %(ext)s)''' % { + %(dataSize)s, %(ext)s)''' % { "class_name" : self.className, "flags" : self.microFlagsText(microFlags), "src1" : self.src1, "imm8" : self.imm8, "dest" : self.dest, - "setStatus" : self.cppBool(self.setStatus), "dataSize" : self.dataSize, "ext" : self.ext} return allocator @@ -264,7 +300,8 @@ let {{ decoder_output = "" exec_output = "" - def setUpMicroRegOp(name, Name, base, code, child, flagCode): + # A function which builds the C++ classes that implement the microops + def setUpMicroRegOp(name, Name, base, code, flagCode, condCheck): global header_output global decoder_output global exec_output @@ -272,14 +309,20 @@ let {{ iop = InstObjParams(name, Name, base, {"code" : code, - "flag_code" : flagCode}) + "flag_code" : flagCode, + "cond_check" : condCheck}) header_output += MicroRegOpDeclare.subst(iop) decoder_output += MicroRegOpConstructor.subst(iop) exec_output += MicroRegOpExecute.subst(iop) - microopClasses[name] = child - def defineMicroRegOp(mnemonic, code, flagCode): + checkCCFlagBits = "checkCondition(ccFlagBits)" + genCCFlagBits = "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, %s);" + + + # This creates a python representations of a microop which are a cross + # product of reg/immediate and flag/no flag versions. + def defineMicroRegOp(mnemonic, code, secondSrc = "op2", cc=False): Name = mnemonic name = mnemonic.lower() @@ -290,35 +333,47 @@ let {{ regCode = matcher.sub("SrcReg2", code) immCode = matcher.sub("imm8", code) - # Build the all register version of this micro op + if not cc: + flagCode = genCCFlagBits % secondSrc + condCode = "true" + else: + flagCode = "" + condCode = checkCCFlagBits + + regFlagCode = matcher.sub("SrcReg2", flagCode) + immFlagCode = matcher.sub("imm8", flagCode) + class RegOpChild(RegOp): - def __init__(self, dest, src1, src2, setStatus=False): - super(RegOpChild, self).__init__(dest, src1, src2, setStatus) - self.className = Name - self.mnemonic = name + mnemonic = name + className = Name + def __init__(self, dest, src1, src2, flags=None): + super(RegOpChild, self).__init__(dest, src1, src2, flags) + + microopClasses[name] = RegOpChild - setUpMicroRegOp(name, Name, "X86ISA::RegOp", \ - regCode, RegOpChild, flagCode); + setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, "", "true"); + setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, regFlagCode, condCode); - # Build the immediate version of this micro op class RegOpChildImm(RegOpImm): - def __init__(self, dest, src1, src2, setStatus=False): - super(RegOpChildImm, self).__init__(dest, src1, src2, setStatus) - self.className = Name + "Imm" - self.mnemonic = name + "i" - - setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", \ - immCode, RegOpChildImm, flagCode); - - defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to set OF,CF,SF - defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)', "") - defineMicroRegOp('Adc', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)', "") #Needs to add in CF, set OF,CF,SF - defineMicroRegOp('Sbb', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', "") #Needs to subtract CF, set OF,CF,SF - defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)', "") - defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', "") #Needs to set OF,CF,SF - defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)', "") - defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', "") #Needs to set OF,CF,SF and not DestReg - defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', "") + mnemonic = name + 'i' + className = Name + 'Imm' + def __init__(self, dest, src1, src2, flags=None): + super(RegOpChildImm, self).__init__(dest, src1, src2, flags) + + microopClasses[name + 'i'] = RegOpChildImm + + setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode, "", "true"); + setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode, immFlagCode, condCode); + + defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') + defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)') + defineMicroRegOp('Adc', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') + defineMicroRegOp('Sbb', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', '-op2') + defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)') + defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', '-op2') + defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)') + defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', '-op2') + defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', cc=True) # This has it's own function because Wr ops have implicit destinations def defineMicroRegOpWr(mnemonic, code): @@ -332,24 +387,27 @@ let {{ regCode = matcher.sub("SrcReg2", code) immCode = matcher.sub("imm8", code) - # Build the all register version of this micro op class RegOpChild(RegOp): - def __init__(self, src1, src2): - super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, False) - self.className = Name - self.mnemonic = name + mnemonic = name + className = Name + def __init__(self, src1, src2, flags=None): + super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, flags) + + microopClasses[name] = RegOpChild - setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, RegOpChild, ""); + setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, "", "true"); + setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, "", checkCCFlagBits); - # Build the immediate version of this micro op class RegOpChildImm(RegOpImm): + mnemonic = name + className = Name def __init__(self, src1, src2): - super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, False) - self.className = Name + "Imm" - self.mnemonic = name + "i" + super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, None) + + microopClasses[name + 'i'] = RegOpChildImm - setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", \ - immCode, RegOpChildImm, ""); + setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", immCode, "", "true"); + setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode, "", checkCCFlagBits); defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2') @@ -360,11 +418,13 @@ let {{ class RegOpChild(RegOp): def __init__(self, dest, src1 = "NUM_INTREGS"): - super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", False) + super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", None) self.className = Name self.mnemonic = name - setUpMicroRegOp(name, Name, "X86ISA::RegOp", code, RegOpChild, ""); + microopClasses[name] = RegOpChild + + setUpMicroRegOp(name, Name, "X86ISA::RegOp", code, "", "true"); defineMicroRegOpRd('Rdip', 'DestReg = RIP') @@ -374,11 +434,13 @@ let {{ class RegOpChild(RegOpImm): def __init__(self, dest, src1, src2): - super(RegOpChild, self).__init__(dest, src1, src2, False) + super(RegOpChild, self).__init__(dest, src1, src2, None) self.className = Name self.mnemonic = name - setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, RegOpChild, ""); + microopClasses[name] = RegOpChild + + setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, "", "true"); defineMicroRegOpImm('Sext', ''' IntReg val = SrcReg1; -- cgit v1.2.3 From c4004482a536f412f5aa8416aa6ca39d8075a89c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 17 Jul 2007 15:35:34 -0700 Subject: Make "test" set some condition codes. It still needs to zero the overflow and carry flags to be correct. --HG-- extra : convert_revision : 73cb3a55f7b4234389d9355f5ad45da6aaaa6c60 --- src/arch/x86/isa/insts/compare_and_test/test.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/arch/x86/isa/insts/compare_and_test/test.py b/src/arch/x86/isa/insts/compare_and_test/test.py index 89d406912..1d2364f0f 100644 --- a/src/arch/x86/isa/insts/compare_and_test/test.py +++ b/src/arch/x86/isa/insts/compare_and_test/test.py @@ -57,26 +57,26 @@ microcode = ''' def macroop TEST_M_R { ld t1, ds, [scale, index, base], disp - and t0, t1, reg + and t0, t1, reg, flags=(SF, ZF, PF) }; def macroop TEST_P_R { rdip t7 ld t1, ds, [scale, index, base], disp - and t0, t1, reg + and t0, t1, reg, flags=(SF, ZF, PF) }; def macroop TEST_R_R { - and t0, reg, regm + and t0, reg, regm, flags=(SF, ZF, PF) }; def macroop TEST_M_I { ld t1, ds, [scale, index, base], disp limm t2, imm - and t0, t1, t2 + and t0, t1, t2, flags=(SF, ZF, PF) }; def macroop TEST_P_I @@ -84,12 +84,12 @@ def macroop TEST_P_I rdip t7 ld t1, ds, [scale, index, base], disp limm t2, imm - and t0, t1, t2 + and t0, t1, t2, flags=(SF, ZF, PF) }; def macroop TEST_R_I { limm t1, imm - and t0, reg, t1 + and t0, reg, t1, flags=(SF, ZF, PF) }; ''' -- cgit v1.2.3 From d77d4c04b702fd8af1d268893bd71e7245f9c542 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 17 Jul 2007 15:36:45 -0700 Subject: Implement the jz instruction. --HG-- extra : convert_revision : 7c0bd7ce244f724ac03bbb5fdf770c7a3eba78b4 --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 2 +- src/arch/x86/isa/insts/control_transfer/jump.py | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 484f8160d..4be83bf54 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -263,7 +263,7 @@ 0x1: jno_Jb(); 0x2: jb_Jb(); 0x3: jnb_Jb(); - 0x4: jz_Jb(); + 0x4: Inst::JZ(Jb); 0x5: jnz_Jb(); 0x6: jbe_Jb(); 0x7: jnbe_Jb(); diff --git a/src/arch/x86/isa/insts/control_transfer/jump.py b/src/arch/x86/isa/insts/control_transfer/jump.py index e90e5b12b..9a013a823 100644 --- a/src/arch/x86/isa/insts/control_transfer/jump.py +++ b/src/arch/x86/isa/insts/control_transfer/jump.py @@ -53,8 +53,11 @@ # # Authors: Gabe Black -microcode = "" -#let {{ -# class JMP(Inst): -# "GenFault ${new UnimpInstFault}" -#}}; +microcode = ''' +def macroop JZ_I +{ + rdip t1 + limm t2, imm + wrip t1, t2, flags=(CZF,) +}; +''' -- cgit v1.2.3 From 62ffc71faba7f2cf05ab7e3fc0624a2c12bf6486 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 17 Jul 2007 16:50:13 -0700 Subject: Use limm to set up immediate value for subtract instruction. --HG-- extra : convert_revision : f94e391e36a47c2f5222f30d7e28f48f7875db58 --- src/arch/x86/isa/insts/arithmetic/add_and_subtract.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py index 809b9ac7c..fbfe4be7e 100644 --- a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py +++ b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py @@ -56,21 +56,24 @@ microcode = ''' def macroop SUB_R_I { - subi reg, reg, imm + limm t1, imm + sub reg, reg, t1 }; def macroop SUB_M_I { + limm t2, imm ld t1, ds, [scale, index, base], disp - subi t1, t1, imm + sub t1, t1, t2 st t1, ds, [scale, index, base], disp }; def macroop SUB_P_I { rdip t7 + limm t2, imm ld t1, ds, [scale, index, base], disp - subi t1, t1, imm + sub t1, t1, t2 st t1, ds, [scale, index, base], disp }; ''' -- cgit v1.2.3 From 2e80f71dcd2367ceae00df88405deee66a68b9ca Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 17 Jul 2007 16:55:33 -0700 Subject: Implemented jnz. --HG-- extra : convert_revision : ea169ad68acbb3383443586b783b831b3a9eecf9 --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 2 +- src/arch/x86/isa/insts/control_transfer/jump.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 4be83bf54..546577662 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -264,7 +264,7 @@ 0x2: jb_Jb(); 0x3: jnb_Jb(); 0x4: Inst::JZ(Jb); - 0x5: jnz_Jb(); + 0x5: Inst::JNZ(Jb); 0x6: jbe_Jb(); 0x7: jnbe_Jb(); } diff --git a/src/arch/x86/isa/insts/control_transfer/jump.py b/src/arch/x86/isa/insts/control_transfer/jump.py index 9a013a823..15f00e083 100644 --- a/src/arch/x86/isa/insts/control_transfer/jump.py +++ b/src/arch/x86/isa/insts/control_transfer/jump.py @@ -60,4 +60,11 @@ def macroop JZ_I limm t2, imm wrip t1, t2, flags=(CZF,) }; + +def macroop JNZ_I +{ + rdip t1 + limm t2, imm + wrip t1, t2, flags=(nCZF,) +}; ''' -- cgit v1.2.3 From e524240d689a6341a53865e0911ad04d440c6683 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 17 Jul 2007 18:12:33 -0700 Subject: Make disassembled x86 register indices reflect their size. This doesn't handle high byte register accesses. It also highlights the fact that address size isn't actually being calculated, and that the size a microop uses needs to be overridable from the microassembly. --HG-- extra : convert_revision : d495ac4f5756dc55a5f71953ff6963b3c030e6cb --- src/arch/x86/insts/microldstop.cc | 6 ++-- src/arch/x86/insts/microregop.cc | 10 +++---- src/arch/x86/insts/static_inst.cc | 56 ++++++++++++++++++++---------------- src/arch/x86/insts/static_inst.hh | 6 ++-- src/arch/x86/isa/microops/limmop.isa | 21 ++++++++------ 5 files changed, 55 insertions(+), 44 deletions(-) diff --git a/src/arch/x86/insts/microldstop.cc b/src/arch/x86/insts/microldstop.cc index 330a1b7bd..8a52ad932 100644 --- a/src/arch/x86/insts/microldstop.cc +++ b/src/arch/x86/insts/microldstop.cc @@ -66,13 +66,13 @@ namespace X86ISA std::stringstream response; printMnemonic(response, instMnem, mnemonic); - printReg(response, data); + printReg(response, data, dataSize); response << ", "; printSegment(response, segment); ccprintf(response, ":[%d*", scale); - printReg(response, index); + printReg(response, index, addressSize); response << " + "; - printReg(response, base); + printReg(response, base, addressSize); ccprintf(response, " + %#x]", disp); return response.str(); } diff --git a/src/arch/x86/insts/microregop.cc b/src/arch/x86/insts/microregop.cc index 3c60d7212..f4559d95f 100644 --- a/src/arch/x86/insts/microregop.cc +++ b/src/arch/x86/insts/microregop.cc @@ -165,11 +165,11 @@ namespace X86ISA std::stringstream response; printMnemonic(response, instMnem, mnemonic); - printReg(response, dest); + printReg(response, dest, dataSize); response << ", "; - printReg(response, src1); + printReg(response, src1, dataSize); response << ", "; - printReg(response, src2); + printReg(response, src2, dataSize); return response.str(); } @@ -179,9 +179,9 @@ namespace X86ISA std::stringstream response; printMnemonic(response, instMnem, mnemonic); - printReg(response, dest); + printReg(response, dest, dataSize); response << ", "; - printReg(response, src1); + printReg(response, src1, dataSize); ccprintf(response, ", %#x", imm8); return response.str(); } diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc index bf84c6e2b..9b2f81e49 100644 --- a/src/arch/x86/insts/static_inst.cc +++ b/src/arch/x86/insts/static_inst.cc @@ -99,76 +99,84 @@ namespace X86ISA } void - X86StaticInst::printSrcReg(std::ostream &os, int reg) const + X86StaticInst::printSrcReg(std::ostream &os, int reg, int size) const { if(_numSrcRegs > reg) - printReg(os, _srcRegIdx[reg]); + printReg(os, _srcRegIdx[reg], size); } void - X86StaticInst::printDestReg(std::ostream &os, int reg) const + X86StaticInst::printDestReg(std::ostream &os, int reg, int size) const { if(_numDestRegs > reg) - printReg(os, _destRegIdx[reg]); + printReg(os, _destRegIdx[reg], size); } void - X86StaticInst::printReg(std::ostream &os, int reg) const + X86StaticInst::printReg(std::ostream &os, int reg, int size) const { + assert(size == 1 || size == 2 || size == 4 || size == 8); + static const char * abcdFormats[9] = + {"", "%sl", "%sx", "", "e%sx", "", "", "", "r%sx"}; + static const char * piFormats[9] = + {"", "%sl", "%s", "", "e%s", "", "", "", "r%s"}; + static const char * longFormats[9] = + {"", "r%sb", "r%sw", "", "r%sd", "", "", "", "r%s"}; + static const char * microFormats[9] = + {"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"}; + if (reg < FP_Base_DepTag) { - //FIXME These should print differently depending on the - //mode etc, but for now this will get the point across switch (reg) { case INTREG_RAX: - ccprintf(os, "rax"); + ccprintf(os, abcdFormats[size], "a"); break; case INTREG_RBX: - ccprintf(os, "rbx"); + ccprintf(os, abcdFormats[size], "b"); break; case INTREG_RCX: - ccprintf(os, "rcx"); + ccprintf(os, abcdFormats[size], "c"); break; case INTREG_RDX: - ccprintf(os, "rdx"); + ccprintf(os, abcdFormats[size], "d"); break; case INTREG_RSP: - ccprintf(os, "rsp"); + ccprintf(os, piFormats[size], "sp"); break; case INTREG_RBP: - ccprintf(os, "rbp"); + ccprintf(os, piFormats[size], "bp"); break; case INTREG_RSI: - ccprintf(os, "rsi"); + ccprintf(os, piFormats[size], "si"); break; case INTREG_RDI: - ccprintf(os, "rdi"); + ccprintf(os, piFormats[size], "di"); break; case INTREG_R8W: - ccprintf(os, "r8"); + ccprintf(os, longFormats[size], "8"); break; case INTREG_R9W: - ccprintf(os, "r9"); + ccprintf(os, longFormats[size], "9"); break; case INTREG_R10W: - ccprintf(os, "r10"); + ccprintf(os, longFormats[size], "10"); break; case INTREG_R11W: - ccprintf(os, "r11"); + ccprintf(os, longFormats[size], "11"); break; case INTREG_R12W: - ccprintf(os, "r12"); + ccprintf(os, longFormats[size], "12"); break; case INTREG_R13W: - ccprintf(os, "r13"); + ccprintf(os, longFormats[size], "13"); break; case INTREG_R14W: - ccprintf(os, "r14"); + ccprintf(os, longFormats[size], "14"); break; case INTREG_R15W: - ccprintf(os, "r15"); + ccprintf(os, longFormats[size], "15"); break; default: - ccprintf(os, "t%d", reg - NUM_INTREGS); + ccprintf(os, microFormats[size], reg - NUM_INTREGS); } } else if (reg < Ctrl_Base_DepTag) { ccprintf(os, "%%f%d", reg - FP_Base_DepTag); diff --git a/src/arch/x86/insts/static_inst.hh b/src/arch/x86/insts/static_inst.hh index 3e9dbf26e..c39c2956e 100644 --- a/src/arch/x86/insts/static_inst.hh +++ b/src/arch/x86/insts/static_inst.hh @@ -85,9 +85,9 @@ namespace X86ISA void printSegment(std::ostream &os, int segment) const; - void printReg(std::ostream &os, int reg) const; - void printSrcReg(std::ostream &os, int reg) const; - void printDestReg(std::ostream &os, int reg) const; + void printReg(std::ostream &os, int reg, int size) const; + void printSrcReg(std::ostream &os, int reg, int size) const; + void printDestReg(std::ostream &os, int reg, int size) const; inline uint64_t merge(uint64_t into, uint64_t val, int size) const { diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa index 177a914ae..37180d7fa 100644 --- a/src/arch/x86/isa/microops/limmop.isa +++ b/src/arch/x86/isa/microops/limmop.isa @@ -77,6 +77,7 @@ def template MicroLimmOpDeclare {{ protected: const RegIndex dest; const uint64_t imm; + const uint8_t dataSize; void buildMe(); std::string generateDisassembly(Addr pc, @@ -86,11 +87,11 @@ def template MicroLimmOpDeclare {{ %(class_name)s(ExtMachInst _machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - RegIndex _dest, uint64_t _imm); + RegIndex _dest, uint64_t _imm, uint8_t _dataSize); %(class_name)s(ExtMachInst _machInst, const char * instMnem, - RegIndex _dest, uint64_t _imm); + RegIndex _dest, uint64_t _imm, uint8_t _dataSize); %(BasicExecDeclare)s }; @@ -103,7 +104,7 @@ def template MicroLimmOpDisassembly {{ std::stringstream response; printMnemonic(response, instMnem, mnemonic); - printReg(response, dest); + printReg(response, dest, dataSize); response << ", "; ccprintf(response, "%#x", imm); return response.str(); @@ -119,10 +120,10 @@ def template MicroLimmOpConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, - RegIndex _dest, uint64_t _imm) : + RegIndex _dest, uint64_t _imm, uint8_t _dataSize) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, false, false, false, false, %(op_class)s), - dest(_dest), imm(_imm) + dest(_dest), imm(_imm), dataSize(_dataSize) { buildMe(); } @@ -130,10 +131,10 @@ def template MicroLimmOpConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - RegIndex _dest, uint64_t _imm) : + RegIndex _dest, uint64_t _imm, uint8_t _dataSize) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, isMicro, isDelayed, isFirst, isLast, %(op_class)s), - dest(_dest), imm(_imm) + dest(_dest), imm(_imm), dataSize(_dataSize) { buildMe(); } @@ -146,14 +147,16 @@ let {{ self.mnemonic = "limm" self.dest = dest self.imm = imm + self.dataSize = "env.dataSize" def getAllocator(self, *microFlags): allocator = '''new %(class_name)s(machInst, mnemonic - %(flags)s, %(dest)s, %(imm)s)''' % { + %(flags)s, %(dest)s, %(imm)s, %(dataSize)s)''' % { "class_name" : self.className, "mnemonic" : self.mnemonic, "flags" : self.microFlagsText(microFlags), - "dest" : self.dest, "imm" : self.imm } + "dest" : self.dest, "imm" : self.imm, + "dataSize" : self.dataSize} return allocator microopClasses["limm"] = LimmOp -- cgit v1.2.3 From 85f32920fb2e4b4938cefcfc275c09abef20cf11 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 17 Jul 2007 20:54:55 -0700 Subject: Calculate the correct address size. --HG-- extra : convert_revision : 6bd9d5a01ba6600781e3678e0403dca524fb2cba --- src/arch/x86/predecoder.cc | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc index 49f76699b..6052d8392 100644 --- a/src/arch/x86/predecoder.cc +++ b/src/arch/x86/predecoder.cc @@ -235,14 +235,42 @@ namespace X86ISA logOpSize = 1; // 16 bit operand size } + //Set the actual op size + emi.opSize = 1 << logOpSize; + + //Figure out the effective address size. This can be overriden to + //a fixed value at the decoder level. + int logAddrSize; + if(/*FIXME 64-bit mode*/1) + { + if(emi.legacy.addr) + logAddrSize = 2; // 32 bit address size + else + logAddrSize = 3; // 64 bit address size + } + else if(/*FIXME default 32*/1) + { + if(emi.legacy.addr) + logAddrSize = 1; // 16 bit address size + else + logAddrSize = 2; // 32 bit address size + } + else // 16 bit default operand size + { + if(emi.legacy.addr) + logAddrSize = 2; // 32 bit address size + else + logAddrSize = 1; // 16 bit address size + } + + //Set the actual address size + emi.addrSize = 1 << logAddrSize; + //Figure out how big of an immediate we'll retreive based //on the opcode. int immType = ImmediateType[emi.opcode.num - 1][nextByte]; immediateSize = SizeTypeToSize[logOpSize - 1][immType]; - //Set the actual op size - emi.opSize = 1 << logOpSize; - //Determine what to expect next if (UsesModRM[emi.opcode.num - 1][nextByte]) { nextState = ModRMState; -- cgit v1.2.3 From 6fbcb225af4b17c9c9695c6a1d9ee2254ceae1af Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 16:09:00 -0700 Subject: Make name, isMachineCheckFault, and isAlignmentFault const. --HG-- extra : convert_revision : a27e0cbdfcb2a5fdc5979686f887cec7d106542b --- src/arch/alpha/faults.hh | 42 +++++++++++++++++++++--------------------- src/arch/mips/faults.hh | 42 +++++++++++++++++++++--------------------- src/arch/sparc/faults.hh | 7 +++---- src/sim/faults.hh | 10 +++++----- 4 files changed, 50 insertions(+), 51 deletions(-) diff --git a/src/arch/alpha/faults.hh b/src/arch/alpha/faults.hh index 6342122c2..ed0c3a6b1 100644 --- a/src/arch/alpha/faults.hh +++ b/src/arch/alpha/faults.hh @@ -66,10 +66,10 @@ class MachineCheckFault : public AlphaFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} - bool isMachineCheckFault() {return true;} + bool isMachineCheckFault() const {return true;} }; class AlignmentFault : public AlphaFault @@ -79,10 +79,10 @@ class AlignmentFault : public AlphaFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} - bool isAlignmentFault() {return true;} + bool isAlignmentFault() const {return true;} }; static inline Fault genMachineCheckFault() @@ -102,7 +102,7 @@ class ResetFault : public AlphaFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -116,7 +116,7 @@ class ArithmeticFault : public AlphaFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} #if FULL_SYSTEM @@ -133,7 +133,7 @@ class InterruptFault : public AlphaFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -150,7 +150,7 @@ class DtbFault : public AlphaFault : vaddr(_vaddr), reqFlags(_reqFlags), flags(_flags) { } #endif - FaultName name() = 0; + FaultName name() const = 0; FaultVect vect() = 0; FaultStat & countStat() = 0; #if FULL_SYSTEM @@ -170,7 +170,7 @@ class NDtbMissFault : public DtbFault : DtbFault(vaddr, reqFlags, flags) { } #endif - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -187,7 +187,7 @@ class PDtbMissFault : public DtbFault : DtbFault(vaddr, reqFlags, flags) { } #endif - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -204,7 +204,7 @@ class DtbPageFault : public DtbFault : DtbFault(vaddr, reqFlags, flags) { } #endif - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -221,7 +221,7 @@ class DtbAcvFault : public DtbFault : DtbFault(vaddr, reqFlags, flags) { } #endif - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -238,7 +238,7 @@ class DtbAlignmentFault : public DtbFault : DtbFault(vaddr, reqFlags, flags) { } #endif - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -251,7 +251,7 @@ class ItbFault : public AlphaFault ItbFault(Addr _pc) : pc(_pc) { } - FaultName name() = 0; + FaultName name() const = 0; FaultVect vect() = 0; FaultStat & countStat() = 0; #if FULL_SYSTEM @@ -269,7 +269,7 @@ class ItbMissFault : public ItbFault ItbMissFault(Addr pc) : ItbFault(pc) { } - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -284,7 +284,7 @@ class ItbPageFault : public ItbFault ItbPageFault(Addr pc) : ItbFault(pc) { } - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -299,7 +299,7 @@ class ItbAcvFault : public ItbFault ItbAcvFault(Addr pc) : ItbFault(pc) { } - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -311,7 +311,7 @@ class UnimplementedOpcodeFault : public AlphaFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -323,7 +323,7 @@ class FloatEnableFault : public AlphaFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -337,7 +337,7 @@ class PalFault : public AlphaFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -349,7 +349,7 @@ class IntegerOverflowFault : public AlphaFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; diff --git a/src/arch/mips/faults.hh b/src/arch/mips/faults.hh index 05a86acd7..2e5aa81d6 100644 --- a/src/arch/mips/faults.hh +++ b/src/arch/mips/faults.hh @@ -61,10 +61,10 @@ class MachineCheckFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} - bool isMachineCheckFault() {return true;} + bool isMachineCheckFault() const {return true;} }; class AlignmentFault : public MipsFault @@ -74,10 +74,10 @@ class AlignmentFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} - bool isAlignmentFault() {return true;} + bool isAlignmentFault() const {return true;} }; class UnimplementedOpcodeFault : public MipsFault @@ -87,7 +87,7 @@ class UnimplementedOpcodeFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -133,7 +133,7 @@ class ResetFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} void invoke(ThreadContext * tc); @@ -146,7 +146,7 @@ class CoprocessorUnusableFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} void invoke(ThreadContext * tc); @@ -159,7 +159,7 @@ class ReservedInstructionFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} void invoke(ThreadContext * tc); @@ -172,7 +172,7 @@ class ThreadFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} void invoke(ThreadContext * tc); @@ -188,7 +188,7 @@ class ArithmeticFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} #if FULL_SYSTEM @@ -205,7 +205,7 @@ class InterruptFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -217,7 +217,7 @@ class NDtbMissFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -229,7 +229,7 @@ class PDtbMissFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -241,7 +241,7 @@ class DtbPageFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -253,7 +253,7 @@ class DtbAcvFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -265,7 +265,7 @@ class ItbMissFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -277,7 +277,7 @@ class ItbPageFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -289,7 +289,7 @@ class ItbAcvFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -301,7 +301,7 @@ class FloatEnableFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -313,7 +313,7 @@ class IntegerOverflowFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; @@ -325,7 +325,7 @@ class DspStateDisabledFault : public MipsFault static FaultVect _vect; static FaultStat _count; public: - FaultName name() {return _name;} + FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} void invoke(ThreadContext * tc); diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index 10ef89279..2456ad28a 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -65,7 +65,6 @@ class SparcFaultBase : public FaultBase #if FULL_SYSTEM void invoke(ThreadContext * tc); #endif - virtual FaultName name() = 0; virtual TrapType trapType() = 0; virtual FaultPriority priority() = 0; virtual FaultStat & countStat() = 0; @@ -78,7 +77,7 @@ class SparcFault : public SparcFaultBase protected: static FaultVals vals; public: - FaultName name() {return vals.name;} + FaultName name() const {return vals.name;} TrapType trapType() {return vals.trapType;} FaultPriority priority() {return vals.priority;} FaultStat & countStat() {return vals.count;} @@ -133,7 +132,7 @@ class InternalProcessorError : public SparcFault { public: - bool isMachineCheckFault() {return true;} + bool isMachineCheckFault() const {return true;} }; class InstructionInvalidTSBEntry : public SparcFault {}; @@ -152,7 +151,7 @@ class MemAddressNotAligned : public SparcFault { public: - bool isAlignmentFault() {return true;} + bool isAlignmentFault() const {return true;} }; class LDDFMemAddressNotAligned : public SparcFault {}; diff --git a/src/sim/faults.hh b/src/sim/faults.hh index 2f0b5af62..f2e638945 100644 --- a/src/sim/faults.hh +++ b/src/sim/faults.hh @@ -53,12 +53,12 @@ typedef Stats::Scalar<> FaultStat; class FaultBase : public RefCounted { public: - virtual FaultName name() = 0; + virtual FaultName name() const = 0; virtual void invoke(ThreadContext * tc); // template // bool isA() {return dynamic_cast(this);} - virtual bool isMachineCheckFault() {return false;} - virtual bool isAlignmentFault() {return false;} + virtual bool isMachineCheckFault() const {return false;} + virtual bool isAlignmentFault() const {return false;} }; FaultBase * const NoFault = 0; @@ -72,7 +72,7 @@ class UnimpFault : public FaultBase : panicStr(_str) { } - FaultName name() {return "Unimplemented simulator feature";} + FaultName name() const {return "Unimplemented simulator feature";} void invoke(ThreadContext * tc); }; @@ -82,7 +82,7 @@ class PageTableFault : public FaultBase private: Addr vaddr; public: - FaultName name() {return "M5 page table fault";} + FaultName name() const {return "M5 page table fault";} PageTableFault(Addr va) : vaddr(va) {} void invoke(ThreadContext * tc); }; -- cgit v1.2.3 From dffc40ff62e6901084efdef6806343ddb8404208 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 16:09:35 -0700 Subject: Add a generateDisassembly function to the MicroFault StaticInst. --HG-- extra : convert_revision : 73811bf99b26fad413c9b84a54f44e3763ff1835 --- src/arch/x86/isa/microops/specop.isa | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/arch/x86/isa/microops/specop.isa b/src/arch/x86/isa/microops/specop.isa index 4d9957587..5c9e8dda9 100644 --- a/src/arch/x86/isa/microops/specop.isa +++ b/src/arch/x86/isa/microops/specop.isa @@ -75,6 +75,9 @@ output header {{ Fault _fault); %(BasicExecDeclare)s + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; }}; @@ -106,6 +109,22 @@ output decoder {{ } }}; +output decoder {{ + std::string MicroFault::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, instMnem, mnemonic); + if(fault) + response << fault->name(); + else + response << "No Fault"; + + return response.str(); + } +}}; + let {{ class Fault(X86Microop): def __init__(self, fault): -- cgit v1.2.3 From 3bd42af99e99f526349dda8e392009c782bd7a01 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 16:10:44 -0700 Subject: Implement the x86 nop to be a "fault" microop which returns "NoFault". --HG-- extra : convert_revision : 1b446def756f1d0f80631db944d1cc41be95efbd --- src/arch/x86/isa/insts/no_operation.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/arch/x86/isa/insts/no_operation.py b/src/arch/x86/isa/insts/no_operation.py index 1a287aea7..306ee2797 100644 --- a/src/arch/x86/isa/insts/no_operation.py +++ b/src/arch/x86/isa/insts/no_operation.py @@ -53,8 +53,9 @@ # # Authors: Gabe Black -microcode = "" -#let {{ -# class NOP(Inst): -# "GenFault ${new UnimpInstFault}" -#}}; +microcode = ''' +def macroop NOP +{ + fault "NoFault" +}; +''' -- cgit v1.2.3 From d21c16fd3753084f3c995fd6174c053d78529d34 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 16:11:16 -0700 Subject: Fix a compilation error for SubBitUnions, --HG-- extra : convert_revision : aad9388afe81ba6541d0b18fa9777e6ffcfd871c --- src/base/bitunion.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/bitunion.hh b/src/base/bitunion.hh index 98861e779..c02ca6155 100644 --- a/src/base/bitunion.hh +++ b/src/base/bitunion.hh @@ -288,7 +288,7 @@ namespace BitfieldBackend { return __data; } \ \ inline const __DataType operator = (const __DataType & _data) \ - { __data = _data; } \ + { return __data = _data;} \ } name; //Regular bitfields -- cgit v1.2.3 From 5cca5ca3d9e5fffb284d5ffd3fc21de147f2f1d3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 16:11:52 -0700 Subject: Hook x86 nop into the decoder. --HG-- extra : convert_revision : 26f765ecf74a0bb6a1ec89816f1d630a1a8e4553 --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 546577662..55fb3087d 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -322,7 +322,7 @@ 0x7: group10_Ev(); //Make sure this is Ev } 0x12: decode OPCODE_OP_BOTTOM3 { - default: nop_or_pause(); //Check for repe prefix + default: Inst::NOP(); //XXX repe makes this a "pause" 0x1: xchg_rCX_rAX(); 0x2: xchg_rDX_rAX(); 0x3: xchg_rVX_rAX(); -- cgit v1.2.3 From 387f00e3ddf43f57fbca50657b698322421bf678 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 16:12:39 -0700 Subject: Fill out the miscreg file and add types to miscregs.hh --HG-- extra : convert_revision : 865432256518c4340d9f319bdd9b7d160dc656a0 --- src/arch/x86/miscregfile.cc | 47 +++++++-- src/arch/x86/miscregfile.hh | 8 +- src/arch/x86/miscregs.hh | 241 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 288 insertions(+), 8 deletions(-) diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index 14ba3c7cc..9d8e94061 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -86,6 +86,7 @@ */ #include "arch/x86/miscregfile.hh" +#include "sim/serialize.hh" using namespace X86ISA; using namespace std; @@ -105,31 +106,65 @@ void MiscRegFile::clear() MiscReg MiscRegFile::readRegNoEffect(int miscReg) { - panic("No misc registers in x86 yet!\n"); + switch(miscReg) + { + case MISCREG_CR1: + case MISCREG_CR5: + case MISCREG_CR6: + case MISCREG_CR7: + case MISCREG_CR9: + case MISCREG_CR10: + case MISCREG_CR11: + case MISCREG_CR12: + case MISCREG_CR13: + case MISCREG_CR14: + case MISCREG_CR15: + panic("Tried to read invalid control register %d\n", miscReg); + break; + } + return regVal[miscReg]; } MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc) { - panic("No misc registers in x86 yet!\n"); + warn("No miscreg effects implemented yet!\n"); + return readRegNoEffect(miscReg); } void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val) { - panic("No misc registers in x86 yet!\n"); + switch(miscReg) + { + case MISCREG_CR1: + case MISCREG_CR5: + case MISCREG_CR6: + case MISCREG_CR7: + case MISCREG_CR9: + case MISCREG_CR10: + case MISCREG_CR11: + case MISCREG_CR12: + case MISCREG_CR13: + case MISCREG_CR14: + case MISCREG_CR15: + panic("Tried to write invalid control register %d\n", miscReg); + break; + } + regVal[miscReg] = val; } void MiscRegFile::setReg(int miscReg, const MiscReg &val, ThreadContext * tc) { - panic("No misc registers in x86 yet!\n"); + warn("No miscreg effects implemented yet!\n"); + setRegNoEffect(miscReg, val); } void MiscRegFile::serialize(std::ostream & os) { - panic("No misc registers in x86 yet!\n"); + SERIALIZE_ARRAY(regVal, NumMiscRegs); } void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) { - panic("No misc registers in x86 yet!\n"); + UNSERIALIZE_ARRAY(regVal, NumMiscRegs); } diff --git a/src/arch/x86/miscregfile.hh b/src/arch/x86/miscregfile.hh index 10acb97a4..e095e06e9 100644 --- a/src/arch/x86/miscregfile.hh +++ b/src/arch/x86/miscregfile.hh @@ -89,6 +89,7 @@ #define __ARCH_X86_MISCREGFILE_HH__ #include "arch/x86/faults.hh" +#include "arch/x86/miscregs.hh" #include "arch/x86/types.hh" #include @@ -100,11 +101,14 @@ namespace X86ISA std::string getMiscRegName(RegIndex); //These will have to be updated in the future. - const int NumMiscArchRegs = 0; - const int NumMiscRegs = 0; + const int NumMiscArchRegs = NUM_MISCREGS; + const int NumMiscRegs = NUM_MISCREGS; class MiscRegFile { + protected: + MiscReg regVal[NumMiscRegs]; + public: void clear(); diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index 57653cd8a..39425fc9d 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -73,6 +73,101 @@ namespace X86ISA OFBit = 1 << 11 }; + enum MiscRegIndex + { + // Control registers + // Most of these are invalid. + MISCREG_CR0, + MISCREG_CR1, + MISCREG_CR2, + MISCREG_CR3, + MISCREG_CR4, + MISCREG_CR5, + MISCREG_CR6, + MISCREG_CR7, + MISCREG_CR8, + MISCREG_CR9, + MISCREG_CR10, + MISCREG_CR11, + MISCREG_CR12, + MISCREG_CR13, + MISCREG_CR14, + MISCREG_CR15, + + // Debug registers + MISCREG_DR0, + MISCREG_DR1, + MISCREG_DR2, + MISCREG_DR3, + MISCREG_DR4, + MISCREG_DR5, + MISCREG_DR6, + MISCREG_DR7, + + // Flags register + MISCREG_RFLAGS, + + // Segment selectors + MISCREG_ES, + MISCREG_CS, + MISCREG_SS, + MISCREG_DS, + MISCREG_FS, + MISCREG_GS, + + // Hidden segment base field + MISCREG_ES_BASE, + MISCREG_CS_BASE, + MISCREG_SS_BASE, + MISCREG_DS_BASE, + MISCREG_FS_BASE, + MISCREG_GS_BASE, + + // Hidden segment limit field + MISCREG_ES_LIMIT, + MISCREG_CS_LIMIT, + MISCREG_SS_LIMIT, + MISCREG_DS_LIMIT, + MISCREG_FS_LIMIT, + MISCREG_GS_LIMIT, + + // Hidden segment limit attributes + MISCREG_ES_ATTR, + MISCREG_CS_ATTR, + MISCREG_SS_ATTR, + MISCREG_DS_ATTR, + MISCREG_FS_ATTR, + MISCREG_GS_ATTR, + + // System segment selectors + MISCREG_LDTR, + MISCREG_TR, + + // Hidden system segment base field + MISCREG_LDTR_BASE, + MISCREG_TR_BASE, + MISCREG_GDTR_BASE, + MISCREG_IDTR_BASE, + + // Hidden system segment limit field + MISCREG_LDTR_LIMIT, + MISCREG_TR_LIMIT, + MISCREG_GDTR_LIMIT, + MISCREG_IDTR_LIMIT, + + // Hidden system segment attribute field + MISCREG_LDTR_ATTR, + MISCREG_TR_ATTR, + + //XXX Add "Model-Specific Registers" + + NUM_MISCREGS + }; + + /** + * A type to describe the condition code bits of the RFLAGS register, + * plus two flags, EZF and ECF, which are only visible to microcode. + */ BitUnion64(CCFlagBits) Bitfield<11> OF; Bitfield<7> SF; @@ -83,6 +178,152 @@ namespace X86ISA Bitfield<2> PF; Bitfield<0> CF; EndBitUnion(CCFlagBits) + + /** + * RFLAGS + */ + BitUnion64(RFLAGS) + Bitfield<21> ID; // ID Flag + Bitfield<20> VIP; // Virtual Interrupt Pending + Bitfield<19> VIF; // Virtual Interrupt Flag + Bitfield<18> AC; // Alignment Check + Bitfield<17> VM; // Virtual-8086 Mode + Bitfield<16> RF; // Resume Flag + Bitfield<14> NT; // Nested Task + Bitfield<13, 12> IOPL; // I/O Privilege Level + Bitfield<11> OF; // Overflow Flag + Bitfield<10> DF; // Direction Flag + Bitfield<9> IF; // Interrupt Flag + Bitfield<8> TF; // Trap Flag + Bitfield<7> SF; // Sign Flag + Bitfield<6> ZF; // Zero Flag + Bitfield<4> AF; // Auxiliary Flag + Bitfield<2> PF; // Parity Flag + Bitfield<0> CF; // Carry Flag + EndBitUnion(RFLAGS) + + /** + * Control registers + */ + BitUnion64(CR0) + Bitfield<31> PG; // Paging + Bitfield<30> CD; // Cache Disable + Bitfield<29> NW; // Not Writethrough + Bitfield<18> AM; // Alignment Mask + Bitfield<16> WP; // Write Protect + Bitfield<5> NE; // Numeric Error + Bitfield<4> ET; // Extension Type + Bitfield<3> TS; // Task Switched + Bitfield<2> EM; // Emulation + Bitfield<1> MP; // Monitor Coprocessor + Bitfield<0> PE; // Protection Enabled + EndBitUnion(CR0) + + // Page Fault Virtual Address + BitUnion64(CR2) + Bitfield<31, 0> legacy; + EndBitUnion(CR2) + + BitUnion64(CR3) + Bitfield<51, 12> longPDTB; // Long Mode Page-Directory-Table + // Base Address + Bitfield<31, 12> PDTB; // Non-PAE Addressing Page-Directory-Table + // Base Address + Bitfield<31, 5> PAEPDTB; // PAE Addressing Page-Directory-Table + // Base Address + Bitfield<4> PCD; // Page-Level Cache Disable + Bitfield<3> PWT; // Page-Level Writethrough + EndBitUnion(CR3) + + BitUnion64(CR4) + Bitfield<10> OSXMMEXCPT; // Operating System Unmasked + // Exception Support + Bitfield<9> OSFXSR; // Operating System FXSave/FSRSTOR Support + Bitfield<8> PCE; // Performance-Monitoring Counter Enable + Bitfield<7> PGE; // Page-Global Enable + Bitfield<6> MCE; // Machine Check Enable + Bitfield<5> PAE; // Physical-Address Extension + Bitfield<4> PSE; // Page Size Extensions + Bitfield<3> DE; // Debugging Extensions + Bitfield<2> TSD; // Time Stamp Disable + Bitfield<1> PVI; // Protected-Mode Virtual Interrupts + Bitfield<0> VME; // Virtual-8086 Mode Extensions + EndBitUnion(CR4) + + BitUnion64(CR8) + Bitfield<3, 0> TPR; // Task Priority Register + EndBitUnion(CR4) + + /** + * Segment Selector + */ + BitUnion64(SegSelector) + Bitfield<15, 3> SI; // Selector Index + Bitfield<2> TI; // Table Indicator + Bitfield<1, 0> RPL; // Requestor Privilege Level + EndBitUnion(SegSelector) + + /** + * Segment Descriptors + */ + + BitUnion64(SegDescriptor) + Bitfield<63, 56> baseHigh; + Bitfield<39, 16> baseLow; + Bitfield<55> G; // Granularity + Bitfield<54> D; // Default Operand Size + Bitfield<54> B; // Default Operand Size + Bitfield<53> L; // Long Attribute Bit + Bitfield<52> AVL; // Available To Software + Bitfield<51, 48> limitHigh; + Bitfield<15, 0> limitLow; + Bitfield<47> P; // Present + Bitfield<46, 45> DPL; // Descriptor Privilege-Level + Bitfield<44> S; // System + SubBitUnion(type, 43, 40) + // Specifies whether this descriptor is for code or data. + Bitfield<43> codeOrData; + + // These bit fields are for code segments + Bitfield<42> C; // Conforming + Bitfield<41> R; // Readable + + // These bit fields are for data segments + Bitfield<42> E; // Expand-Down + Bitfield<41> W; // Writable + + // This is used for both code and data segments. + Bitfield<40> A; // Accessed + EndSubBitUnion(type) + EndBitUnion(SegDescriptor) + + BitUnion64(GateDescriptor) + Bitfield<63, 48> offsetHigh; // Target Code-Segment Offset + Bitfield<15, 0> offsetLow; // Target Code-Segment Offset + Bitfield<31, 16> selector; // Target Code-Segment Selector + Bitfield<47> P; // Present + Bitfield<46, 45> DPL; // Descriptor Privilege-Level + Bitfield<43, 40> type; + Bitfield<36, 32> count; // Parameter Count + EndBitUnion(GateDescriptor) + + /** + * Descriptor-Table Registers + */ + BitUnion64(GDTR) + EndBitUnion(GDTR) + + BitUnion64(IDTR) + EndBitUnion(IDTR) + + BitUnion64(LDTR) + EndBitUnion(LDTR) + + /** + * Task Register + */ + BitUnion64(TR) + EndBitUnion(TR) }; #endif // __ARCH_X86_INTREGS_HH__ -- cgit v1.2.3 From b949458d4c99ae03698c463fb293b1a245eb1e9f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 16:26:17 -0700 Subject: Make the data size used by regops overridable in the microassembly. --HG-- extra : convert_revision : 84d850aa5340c9d02d03502704b063215f6e2140 --- src/arch/x86/isa/microops/regop.isa | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index dd196a50d..d36fcb773 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -237,12 +237,12 @@ let {{ class RegOp(X86Microop): abstract = True - def __init__(self, dest, src1, src2, flags): + def __init__(self, dest, src1, src2, flags, dataSize): self.dest = dest self.src1 = src1 self.src2 = src2 self.flags = flags - self.dataSize = "env.dataSize" + self.dataSize = dataSize if flags is None: self.ext = 0 else: @@ -265,12 +265,12 @@ let {{ class RegOpImm(X86Microop): abstract = True - def __init__(self, dest, src1, imm8, flags): + def __init__(self, dest, src1, imm8, flags, dataSize): self.dest = dest self.src1 = src1 self.imm8 = imm8 self.flags = flags - self.dataSize = "env.dataSize" + self.dataSize = dataSize if flags is None: self.ext = 0 else: @@ -346,8 +346,8 @@ let {{ class RegOpChild(RegOp): mnemonic = name className = Name - def __init__(self, dest, src1, src2, flags=None): - super(RegOpChild, self).__init__(dest, src1, src2, flags) + def __init__(self, dest, src1, src2, flags=None, dataSize="env.dataSize"): + super(RegOpChild, self).__init__(dest, src1, src2, flags, dataSize) microopClasses[name] = RegOpChild @@ -357,8 +357,8 @@ let {{ class RegOpChildImm(RegOpImm): mnemonic = name + 'i' className = Name + 'Imm' - def __init__(self, dest, src1, src2, flags=None): - super(RegOpChildImm, self).__init__(dest, src1, src2, flags) + def __init__(self, dest, src1, src2, flags=None, dataSize="env.dataSize"): + super(RegOpChildImm, self).__init__(dest, src1, src2, flags, dataSize) microopClasses[name + 'i'] = RegOpChildImm @@ -390,8 +390,8 @@ let {{ class RegOpChild(RegOp): mnemonic = name className = Name - def __init__(self, src1, src2, flags=None): - super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, flags) + def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"): + super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize) microopClasses[name] = RegOpChild @@ -401,8 +401,8 @@ let {{ class RegOpChildImm(RegOpImm): mnemonic = name className = Name - def __init__(self, src1, src2): - super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, None) + def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"): + super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize) microopClasses[name + 'i'] = RegOpChildImm @@ -417,8 +417,8 @@ let {{ name = mnemonic.lower() class RegOpChild(RegOp): - def __init__(self, dest, src1 = "NUM_INTREGS"): - super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", None) + def __init__(self, dest, src1 = "NUM_INTREGS", dataSize="env.dataSize"): + super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", None, dataSize) self.className = Name self.mnemonic = name @@ -433,8 +433,8 @@ let {{ name = mnemonic.lower() class RegOpChild(RegOpImm): - def __init__(self, dest, src1, src2): - super(RegOpChild, self).__init__(dest, src1, src2, None) + def __init__(self, dest, src1, src2, dataSize="env.dataSize"): + super(RegOpChild, self).__init__(dest, src1, src2, None, dataSize) self.className = Name self.mnemonic = name -- cgit v1.2.3 From bafb7ee5c1ba31c9a52de835a24d9df65b818ab6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 16:26:52 -0700 Subject: Fix the operand types in a section of the decoder. --HG-- extra : convert_revision : c37600fd65b44817eed2ba653f9d4f08a9869874 --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 55fb3087d..6c54f77bc 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -297,14 +297,14 @@ } //0x3: group1_Ev_Ib(); 0x3: decode MODRM_REG { - 0x0: add_Eb_Ib(); - 0x1: or_Eb_Ib(); - 0x2: adc_Eb_Ib(); - 0x3: sbb_Eb_Ib(); - 0x4: Inst::AND(Eb,Ib); - 0x5: sub_Eb_Ib(); - 0x6: xor_Eb_Ib(); - 0x7: cmp_Eb_Ib(); + 0x0: add_Ev_Ib(); + 0x1: or_Ev_Ib(); + 0x2: adc_Ev_Ib(); + 0x3: sbb_Ev_Ib(); + 0x4: Inst::AND(Ev,Ib); + 0x5: sub_Ev_Ib(); + 0x6: xor_Ev_Ib(); + 0x7: cmp_Ev_Ib(); } 0x4: Inst::TEST(Eb,Gb); 0x5: Inst::TEST(Ev,Gv); -- cgit v1.2.3 From 6c54b654a880ffa83a16a043d90612bd49815de6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 16:33:56 -0700 Subject: Implement some forms of add. --HG-- extra : convert_revision : adbff2e9b9952ec09853cc43d40243e7262410a7 --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 2 +- .../x86/isa/insts/arithmetic/add_and_subtract.py | 23 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 6c54f77bc..82e50e745 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -297,7 +297,7 @@ } //0x3: group1_Ev_Ib(); 0x3: decode MODRM_REG { - 0x0: add_Ev_Ib(); + 0x0: Inst::ADD(Ev,Ib); 0x1: or_Ev_Ib(); 0x2: adc_Ev_Ib(); 0x3: sbb_Ev_Ib(); diff --git a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py index fbfe4be7e..4d6e40c74 100644 --- a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py +++ b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py @@ -54,6 +54,29 @@ # Authors: Gabe Black microcode = ''' +def macroop ADD_R_I +{ + limm t1, imm + add reg, reg, t1 +}; + +def macroop ADD_M_I +{ + limm t2, imm + ld t1, ds, [scale, index, base], disp + add t1, t1, t2 + st t1, ds, [scale, index, base], disp +}; + +def macroop ADD_P_I +{ + rdip t7 + limm t2, imm + ld t1, ds, [scale, index, base], disp + add t1, t1, t2 + st t1, ds, [scale, index, base], disp +}; + def macroop SUB_R_I { limm t1, imm -- cgit v1.2.3 From 17f3da6c29f5bd2ef8ca1f2a522c3710f7d98746 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 17:43:30 -0700 Subject: Fix the panic in the "error" format for x86, --HG-- extra : convert_revision : bd0715b5b63665f9160082d67c5b5d90d2405c5c --- src/arch/x86/isa/formats/error.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/x86/isa/formats/error.isa b/src/arch/x86/isa/formats/error.isa index 8ac2ea44d..e85eff762 100644 --- a/src/arch/x86/isa/formats/error.isa +++ b/src/arch/x86/isa/formats/error.isa @@ -64,7 +64,7 @@ def template ErrorDecode {{ { - panic("X86 decoder internal error: '%%s' %%s", + panic("X86 decoder internal error: '%s' %s", %(message)s, machInst); } }}; -- cgit v1.2.3 From e209fce9dec5445bc559f52a472c39adf52ee49a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 17:44:12 -0700 Subject: Fix a comment to refer to the right type of instruction. --HG-- extra : convert_revision : dd441d8fbaed1ed8b2b66e3ad0275009bd4dcef4 --- src/arch/x86/isa/insts/control_transfer/call.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/x86/isa/insts/control_transfer/call.py b/src/arch/x86/isa/insts/control_transfer/call.py index 530162bfd..b9ba621e5 100644 --- a/src/arch/x86/isa/insts/control_transfer/call.py +++ b/src/arch/x86/isa/insts/control_transfer/call.py @@ -56,7 +56,7 @@ microcode = ''' def macroop CALL_I { - # Make the default data size of pops 64 bits in 64 bit mode + # Make the default data size of calls 64 bits in 64 bit mode .adjust_env oszIn64Override limm t2, imm -- cgit v1.2.3 From 05a33a443ff00c7a7b668128b6a53bd65e0305cd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 17:45:06 -0700 Subject: Make store microops actually store instead of load. --HG-- extra : convert_revision : fe90f8adc96dd0e680cfa45e4c510a906046ae3d --- src/arch/x86/isa/microops/ldstop.isa | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 2e98a42bf..9ceaaac19 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -404,13 +404,13 @@ let {{ class StoreOp(LdStOp): def __init__(self, data, segment, addr, disp = 0): - super(LoadOp, self).__init__(data, segment, addr, disp) + super(StoreOp, self).__init__(data, segment, addr, disp) self.className = Name self.mnemonic = name microopClasses[name] = StoreOp - defineMicroLoadOp('St', 'Mem = Data;') + defineMicroStoreOp('St', 'Mem = Data;') iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', {"code": "Data = merge(Data, EA, dataSize);", "ea_code": calculateEA}) -- cgit v1.2.3 From 776283cff8bcb01a308dbe216b515f809e053b55 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 17:45:43 -0700 Subject: Fix the overload which prints ExtMachInst in X86. --HG-- extra : convert_revision : 2ef8ee71999f36b09270ba9526c2846beda65051 --- src/arch/x86/types.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh index ef4d2e5c4..9d927679d 100644 --- a/src/arch/x86/types.hh +++ b/src/arch/x86/types.hh @@ -184,8 +184,8 @@ namespace X86ISA "prefixA = %#x,\n\t\tprefixB = %#x\n\t},\n\t" "modRM = %#x,\n\tsib = %#x,\n\t" "immediate = %#x,\n\tdisplacement = %#x\n}\n", - emi.legacy, (uint8_t)emi.rex, - emi.opcode.num, emi.opcode.op, + (uint8_t)emi.legacy, (uint8_t)emi.rex, + emi.opcode.num, (uint8_t)emi.opcode.op, emi.opcode.prefixA, emi.opcode.prefixB, (uint8_t)emi.modRM, (uint8_t)emi.sib, emi.immediate, emi.displacement); -- cgit v1.2.3 From 99310a1d939e052ab1ecc949e1b2d7974daddd60 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 17:46:38 -0700 Subject: Make instructions that conditionally set registers set them to their old value if they don't actually execute. --HG-- extra : convert_revision : 36e63dd0c6ac1a3e1133c7985cf5507b83e9ee45 --- src/arch/x86/isa/microops/regop.isa | 46 ++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index d36fcb773..37cbaa8c6 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -73,6 +73,10 @@ def template MicroRegOpExecute {{ %(code)s; %(flag_code)s; } + else + { + %(else_code)s; + } //Write the resulting state to the execution context if(fault == NoFault) @@ -97,6 +101,10 @@ def template MicroRegOpImmExecute {{ %(code)s; %(flag_code)s; } + else + { + %(else_code)s; + } //Write the resulting state to the execution context if(fault == NoFault) @@ -301,7 +309,7 @@ let {{ exec_output = "" # A function which builds the C++ classes that implement the microops - def setUpMicroRegOp(name, Name, base, code, flagCode, condCheck): + def setUpMicroRegOp(name, Name, base, code, flagCode, condCheck, elseCode): global header_output global decoder_output global exec_output @@ -310,7 +318,8 @@ let {{ iop = InstObjParams(name, Name, base, {"code" : code, "flag_code" : flagCode, - "cond_check" : condCheck}) + "cond_check" : condCheck, + "else_code" : elseCode}) header_output += MicroRegOpDeclare.subst(iop) decoder_output += MicroRegOpConstructor.subst(iop) exec_output += MicroRegOpExecute.subst(iop) @@ -322,7 +331,7 @@ let {{ # This creates a python representations of a microop which are a cross # product of reg/immediate and flag/no flag versions. - def defineMicroRegOp(mnemonic, code, secondSrc = "op2", cc=False): + def defineMicroRegOp(mnemonic, code, secondSrc = "op2", cc=False, elseCode=";"): Name = mnemonic name = mnemonic.lower() @@ -351,8 +360,8 @@ let {{ microopClasses[name] = RegOpChild - setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, "", "true"); - setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, regFlagCode, condCode); + setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, "", "true", elseCode); + setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, regFlagCode, condCode, elseCode); class RegOpChildImm(RegOpImm): mnemonic = name + 'i' @@ -362,8 +371,8 @@ let {{ microopClasses[name + 'i'] = RegOpChildImm - setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode, "", "true"); - setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode, immFlagCode, condCode); + setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode, "", "true", elseCode); + setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode, immFlagCode, condCode, elseCode); defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)') @@ -373,10 +382,11 @@ let {{ defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', '-op2') defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)') defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', '-op2') - defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', cc=True) + defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', + elseCode='DestReg=DestReg;', cc=True) # This has it's own function because Wr ops have implicit destinations - def defineMicroRegOpWr(mnemonic, code): + def defineMicroRegOpWr(mnemonic, code, elseCode=";"): Name = mnemonic name = mnemonic.lower() @@ -395,21 +405,21 @@ let {{ microopClasses[name] = RegOpChild - setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, "", "true"); - setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, "", checkCCFlagBits); + setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, "", "true", elseCode); + setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, "", checkCCFlagBits, elseCode); class RegOpChildImm(RegOpImm): - mnemonic = name - className = Name + mnemonic = name + 'i' + className = Name + 'Imm' def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"): super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize) microopClasses[name + 'i'] = RegOpChildImm - setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", immCode, "", "true"); - setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode, "", checkCCFlagBits); + setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", immCode, "", "true", elseCode); + setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode, "", checkCCFlagBits, elseCode); - defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2') + defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;") # This has it's own function because Rd ops don't always have two parameters def defineMicroRegOpRd(mnemonic, code): @@ -424,7 +434,7 @@ let {{ microopClasses[name] = RegOpChild - setUpMicroRegOp(name, Name, "X86ISA::RegOp", code, "", "true"); + setUpMicroRegOp(name, Name, "X86ISA::RegOp", code, "", "true", ";"); defineMicroRegOpRd('Rdip', 'DestReg = RIP') @@ -440,7 +450,7 @@ let {{ microopClasses[name] = RegOpChild - setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, "", "true"); + setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, "", "true", ";"); defineMicroRegOpImm('Sext', ''' IntReg val = SrcReg1; -- cgit v1.2.3 From dbf361128a1e9940ada0af32d9d0d728d08b8943 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 17:47:40 -0700 Subject: Implement near returns. --HG-- extra : convert_revision : 3d6e8a976d31cb016a4b78200716b0ece155137a --- src/arch/x86/isa/insts/control_transfer/xreturn.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/arch/x86/isa/insts/control_transfer/xreturn.py b/src/arch/x86/isa/insts/control_transfer/xreturn.py index aaffa2b92..1e8e0ba55 100644 --- a/src/arch/x86/isa/insts/control_transfer/xreturn.py +++ b/src/arch/x86/isa/insts/control_transfer/xreturn.py @@ -53,8 +53,14 @@ # # Authors: Gabe Black -microcode = "" -#let {{ -# class RET(Inst): -# "GenFault ${new UnimpInstFault}" -#}}; +microcode = ''' +def macroop RET +{ + # Make the default data size of rets 64 bits in 64 bit mode + .adjust_env oszIn64Override + + ld t1, ss, [0, t0, rsp] + addi rsp, rsp, dsz + wripi t1, 0 +}; +''' -- cgit v1.2.3 From f6d326d6fcd505068ffff4014b19d4fa27f2e5be Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 17:48:16 -0700 Subject: Hook near returns into the decoder. --HG-- extra : convert_revision : b38d4417552991e44f5d1de1f35d5d1ad8f32340 --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 82e50e745..12bebd47b 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -398,7 +398,7 @@ 0x0: group2_Eb_Ib(); 0x1: group2_Ev_Ib(); 0x2: ret_near_Iw(); - 0x3: ret_near(); + 0x3: Inst::RET(); 0x4: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); default: les_Gz_Mp(); -- cgit v1.2.3 From 09f056a1ef324b540818f1d85377fb09af44a0f1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 18 Jul 2007 17:51:05 -0700 Subject: Check for the two opcode prefix correctly and add in some instructions. --HG-- extra : convert_revision : 751e54843f5c81b81529050a1ae9d46d07c36e97 --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index f05c33bdb..7fc571205 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -58,7 +58,7 @@ // Decode the two byte opcodes // 0x2: decode OPCODE_PREFIXA { - 0xF0: decode OPCODE_OP_TOP5 { + 0x0F: decode OPCODE_OP_TOP5 { format WarnUnimpl { 0x00: decode OPCODE_OP_BOTTOM3 { 0x00: group6(); @@ -67,9 +67,7 @@ 0x03: lsl_Gv_Ew(); //sandpile.org doesn't seem to know what this is... ? 0x04: loadall_or_reset_or_hang(); - //sandpile.org says (AMD) after syscall, so I might want to check - //if that means amd64 or AMD machines - 0x05: loadall_or_syscall(); + 0x05: syscall(); 0x06: clts(); //sandpile.org says (AMD) after sysret, so I might want to check //if that means amd64 or AMD machines @@ -226,14 +224,14 @@ 0x7: holder(); } 0x10: decode OPCODE_OP_BOTTOM3 { - 0x0: holder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: jo_Jz(); + 0x1: jno_Jz(); + 0x2: jb_Jz(); + 0x3: jnb_Jz(); + 0x4: jz_Jz(); + 0x5: Inst::JNZ(Jz); + 0x6: jbe_Jz(); + 0x7: jnbe_Jz(); } 0x11: decode OPCODE_OP_BOTTOM3 { 0x0: holder(); -- cgit v1.2.3 From cfadef74d1d7ce47d0bd30a14a509a15a354849a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 19 Jul 2007 15:15:47 -0700 Subject: x86 fixes Make the emulation environment consider the rex prefix. Implement and hook in forms of j, jmp, cmp, syscall, movzx Added a format for an instruction to carry a call to the SE mode syscalls system Made memory instructions which refer to the rip do so directly Made the operand size overridable in the microassembly Made the "ext" field of register operations 16 bits to hold a sparse encoding of flags to set or conditions to predicate on Added an explicit "rax" operand for the syscall format Implemented syscall returns. --HG-- extra : convert_revision : ae84bd8c6a1d400906e17e8b8c4185f2ebd4c5f2 --- src/arch/x86/emulenv.cc | 12 +- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 10 +- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 234 +++++++++++---------- src/arch/x86/isa/formats/formats.isa | 4 + src/arch/x86/isa/formats/syscall.isa | 112 ++++++++++ src/arch/x86/isa/insts/compare_and_test/compare.py | 12 +- src/arch/x86/isa/insts/compare_and_test/test.py | 4 +- src/arch/x86/isa/insts/control_transfer/jump.py | 48 +++++ src/arch/x86/isa/insts/data_transfer/move.py | 66 +++++- src/arch/x86/isa/microops/ldstop.isa | 22 +- src/arch/x86/isa/microops/regop.isa | 16 +- src/arch/x86/isa/operands.isa | 1 + src/arch/x86/syscallreturn.hh | 5 +- 13 files changed, 391 insertions(+), 155 deletions(-) create mode 100644 src/arch/x86/isa/formats/syscall.isa diff --git a/src/arch/x86/emulenv.cc b/src/arch/x86/emulenv.cc index e3f703cff..3a54d7365 100644 --- a/src/arch/x86/emulenv.cc +++ b/src/arch/x86/emulenv.cc @@ -66,8 +66,8 @@ void EmulEnv::doModRM(const ExtMachInst & machInst) //Use the SIB byte for addressing if the modrm byte calls for it. if (machInst.modRM.rm == 4 && machInst.addrSize != 2) { scale = 1 << machInst.sib.scale; - index = machInst.sib.index; - base = machInst.sib.base; + index = machInst.sib.index | (machInst.rex.x << 3); + base = machInst.sib.base | (machInst.rex.b << 3); //In this special case, we don't use a base. The displacement also //changes, but that's managed by the predecoder. if (machInst.sib.base == INTREG_RBP && machInst.modRM.mod == 0) @@ -80,11 +80,13 @@ void EmulEnv::doModRM(const ExtMachInst & machInst) warn("I'm not really using 16 bit MODRM like I'm supposed to!\n"); } else { scale = 0; - base = machInst.modRM.rm; + base = machInst.modRM.rm | (machInst.rex.b << 3); if (machInst.modRM.mod == 0 && machInst.modRM.rm == 5) { base = NUM_INTREGS; - if (machInst.mode.submode == SixtyFourBitMode) - base = NUM_INTREGS+7; + //Since we need to use a different encoding of this + //instruction anyway, just ignore the base in those cases +// if (machInst.mode.submode == SixtyFourBitMode) +// base = NUM_INTREGS+7; } } } diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 12bebd47b..ee6072454 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -163,8 +163,8 @@ 0x1: cmp_Ev_Gv(); 0x2: cmp_Gb_Eb(); 0x3: cmp_Gv_Ev(); - 0x4: cmp_Al_Ib(); - 0x5: cmp_rAX_Iz(); + 0x4: Inst::CMP(rAl,Ib); + 0x5: Inst::CMP(rAX,Iz); 0x6: M5InternalError::error( {{"Tried to execute the DS segment override prefix!"}}); 0x7: decode MODE_SUBMODE { @@ -262,10 +262,10 @@ 0x0: jo_Jb(); 0x1: jno_Jb(); 0x2: jb_Jb(); - 0x3: jnb_Jb(); + 0x3: Inst::JNB(Jb); 0x4: Inst::JZ(Jb); 0x5: Inst::JNZ(Jb); - 0x6: jbe_Jb(); + 0x6: Inst::JBE(Jb); 0x7: jnbe_Jb(); } 0x0F: decode OPCODE_OP_BOTTOM3 { @@ -475,7 +475,7 @@ 0x0: This_should_be_an_illegal_instruction(); default: jmp_Ap(); } - 0x3: jmp_Jb(); + 0x3: Inst::JMP(Jb); 0x4: in_Al_Dx(); 0x5: in_eAX_Dx(); 0x6: out_Dx_Al(); diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 7fc571205..e042893bb 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -67,21 +67,25 @@ 0x03: lsl_Gv_Ew(); //sandpile.org doesn't seem to know what this is... ? 0x04: loadall_or_reset_or_hang(); +#if FULL_SYSTEM 0x05: syscall(); +#else + 0x05: SyscallInst::syscall('xc->syscall(rax)'); +#endif 0x06: clts(); //sandpile.org says (AMD) after sysret, so I might want to check //if that means amd64 or AMD machines 0x07: loadall_or_sysret(); } 0x01: decode OPCODE_OP_BOTTOM3 { - 0x0: holderholder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: invd(); + 0x1: wbinvd(); + 0x2: This_should_be_an_illegal_instruction(); + 0x3: UD1(); + 0x4: This_should_be_an_illegal_instruction(); + 0x5: threednow(); + 0x6: threednow(); + 0x7: threednow(); } 0x02: decode OPCODE_OP_BOTTOM3 { 0x0: holder(); @@ -94,14 +98,14 @@ 0x7: holder(); } 0x03: decode OPCODE_OP_BOTTOM3 { - 0x0: holder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: group17(); + 0x1: group17(); + 0x2: group17(); + 0x3: group17(); + 0x4: group17(); + 0x5: group17(); + 0x6: group17(); + 0x7: group17(); } 0x04: decode OPCODE_OP_BOTTOM3 { 0x0: holder(); @@ -124,44 +128,44 @@ 0x7: holder(); } 0x06: decode OPCODE_OP_BOTTOM3 { - 0x0: holder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: wrmsr(); + 0x1: rdtsc(); + 0x2: rdmsr(); + 0x3: rdpmc(); + 0x4: sysenter(); + 0x5: sysexit(); + 0x6: This_should_be_an_illegal_instruction(); + 0x7: getsec(); } 0x07: decode OPCODE_OP_BOTTOM3 { - 0x0: holder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: three_byte_opcode(); + 0x1: three_byte_opcode(); + 0x2: three_byte_opcode(); + 0x3: three_byte_opcode(); + 0x4: three_byte_opcode(); + 0x5: three_byte_opcode(); + 0x6: three_byte_opcode(); + 0x7: three_byte_opcode(); } 0x08: decode OPCODE_OP_BOTTOM3 { - 0x0: holder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: cmovo_Gv_Ev(); + 0x1: cmovno_Gv_Ev(); + 0x2: cmovb_Gv_Ev(); + 0x3: cmovnb_Gv_Ev(); + 0x4: cmovz_Gv_Ev(); + 0x5: cmovnz_Gv_Ev(); + 0x6: cmovbe_Gv_Ev(); + 0x7: cmovnbe_Gv_Ev(); } 0x09: decode OPCODE_OP_BOTTOM3 { - 0x0: holder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: cmovs_Gv_Ev(); + 0x1: cmovns_Gv_Ev(); + 0x2: cmovp_Gv_Ev(); + 0x3: cmovnp_Gv_Ev(); + 0x4: cmovl_Gv_Ev(); + 0x5: cmovnl_Gv_Ev(); + 0x6: cmovle_Gv_Ev(); + 0x7: cmovnle_Gv_Ev(); } 0x0A: decode OPCODE_OP_BOTTOM3 { 0x0: holder(); @@ -227,81 +231,81 @@ 0x0: jo_Jz(); 0x1: jno_Jz(); 0x2: jb_Jz(); - 0x3: jnb_Jz(); - 0x4: jz_Jz(); + 0x3: Inst::JNB(Jz); + 0x4: Inst::JZ(Jz); 0x5: Inst::JNZ(Jz); - 0x6: jbe_Jz(); + 0x6: Inst::JBE(Jz); 0x7: jnbe_Jz(); } 0x11: decode OPCODE_OP_BOTTOM3 { - 0x0: holder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: js_Jz(); + 0x1: jns_Jz(); + 0x2: jp_Jz(); + 0x3: jnp_Jz(); + 0x4: jl_Jz(); + 0x5: jnl_Jz(); + 0x6: jle_Jz(); + 0x7: jnle_Jz(); } 0x12: decode OPCODE_OP_BOTTOM3 { - 0x0: holder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: seto_Eb(); + 0x1: setno_Eb(); + 0x2: setb_Eb(); + 0x3: setnb_Eb(); + 0x4: setz_Eb(); + 0x5: setnz_Eb(); + 0x6: setbe_Eb(); + 0x7: setnbe_Eb(); } 0x13: decode OPCODE_OP_BOTTOM3 { - 0x0: holder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: sets_Eb(); + 0x1: setns_Eb(); + 0x2: setp_Eb(); + 0x3: setnp_Eb(); + 0x4: setl_Eb(); + 0x5: setnl_Eb(); + 0x6: setle_Eb(); + 0x7: setnle_Eb(); } 0x14: decode OPCODE_OP_BOTTOM3 { - 0x0: holder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: push_fs(); + 0x1: pop_fs(); + 0x2: cpuid(); + 0x3: bt_Ev_Gv(); + 0x4: shld_Ev_Gv_Ib(); + 0x5: shld_Ev_Gv_rCl(); + 0x6: xbts_and_cmpxchg(); + 0x7: ibts_and_cmpxchg(); } 0x15: decode OPCODE_OP_BOTTOM3 { - 0x0: holder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: push_gs(); + 0x1: pop_gs(); + 0x2: rsm_smm(); + 0x3: bts_Ev_Gv(); + 0x4: shrd_Ev_Gv_Ib(); + 0x5: shrd_Ev_Gv_rCl(); + 0x6: group16(); + 0x7: imul_Gv_Ev(); } 0x16: decode OPCODE_OP_BOTTOM3 { - 0x0: holder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: cmpxchg_Eb_Gb(); + 0x1: cmpxchg_Ev_Gv(); + 0x2: lss_Gz_Mp(); + 0x3: btr_Ev_Gv(); + 0x4: lfs_Gz_Mp(); + 0x5: lgs_Gz_Mp(); + 0x6: Inst::MOVZX_B(Gv,Eb); + 0x7: Inst::MOVZX_W(Gv,Ew); } 0x17: decode OPCODE_OP_BOTTOM3 { - 0x0: holder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: jmpe_Jz(); // IA-64? + 0x1: group11_UD2(); + 0x2: group8_Ev_Ib(); + 0x3: btc_Ev_Gv(); + 0x4: bsf_Gv_Ev(); + 0x5: bsr_Gv_Ev(); + 0x6: movsx_Gv_Eb(); + 0x7: movsx_Gv_Ew(); } 0x18: decode OPCODE_OP_BOTTOM3 { 0x0: holder(); @@ -314,14 +318,14 @@ 0x7: holder(); } 0x19: decode OPCODE_OP_BOTTOM3 { - 0x0: holder(); - 0x1: holder(); - 0x2: holder(); - 0x3: holder(); - 0x4: holder(); - 0x5: holder(); - 0x6: holder(); - 0x7: holder(); + 0x0: bswap_rAx(); + 0x1: bswap_rCx(); + 0x2: bswap_rDx(); + 0x3: bswap_rBx(); + 0x4: bswap_rSP(); + 0x5: bswap_rBP(); + 0x6: bswap_rSI(); + 0x7: bswap_rDI(); } 0x1A: decode OPCODE_OP_BOTTOM3 { 0x0: holder(); diff --git a/src/arch/x86/isa/formats/formats.isa b/src/arch/x86/isa/formats/formats.isa index d763c05bc..1e7bb4a74 100644 --- a/src/arch/x86/isa/formats/formats.isa +++ b/src/arch/x86/isa/formats/formats.isa @@ -98,3 +98,7 @@ //Include a format which implements a batch of instructions which do the same //thing on a variety of inputs ##include "multi.isa" + +//Include a format which makes instructions who's sole purpose is to generate +//a syscall. +##include "syscall.isa" diff --git a/src/arch/x86/isa/formats/syscall.isa b/src/arch/x86/isa/formats/syscall.isa new file mode 100644 index 000000000..8b860dba4 --- /dev/null +++ b/src/arch/x86/isa/formats/syscall.isa @@ -0,0 +1,112 @@ +// -*- mode:c++ -*- + +// 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 + +//////////////////////////////////////////////////////////////////// +// +// "Format" which describes an instruction whose only purpose is to +// call a syscall in SE mode. +// + +output header {{ + class SyscallInst : public X86ISA::X86StaticInst + { + public: + /// Constructor + SyscallInst(const char *_mnemonic, ExtMachInst _machInst, + OpClass __opClass) : + X86ISA::X86StaticInst(_mnemonic, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string SyscallInst::generateDisassembly(Addr PC, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, mnemonic); + ccprintf(response, " "); + printReg(response, _srcRegIdx[0], machInst.opSize); + return response.str(); + } +}}; + +def template SyscallExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + %(op_decl)s; + %(op_rd)s; + %(code)s; + return fault; + } +}}; + +def format SyscallInst(code, *opt_flags) {{ + iop = InstObjParams(name, Name, 'SyscallInst', code, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = SyscallExecute.subst(iop) +}}; + diff --git a/src/arch/x86/isa/insts/compare_and_test/compare.py b/src/arch/x86/isa/insts/compare_and_test/compare.py index 12b5b859f..ba421a520 100644 --- a/src/arch/x86/isa/insts/compare_and_test/compare.py +++ b/src/arch/x86/isa/insts/compare_and_test/compare.py @@ -53,8 +53,10 @@ # # Authors: Gabe Black -microcode = "" -#let {{ -# class CMP(Inst): -# "GenFault ${new UnimpInstFault}" -#}}; +microcode = ''' +def macroop CMP_R_I +{ + limm t1, imm + sub t0, reg, t1, flags=(OF, SF, ZF, AF, PF, CF) +}; +''' diff --git a/src/arch/x86/isa/insts/compare_and_test/test.py b/src/arch/x86/isa/insts/compare_and_test/test.py index 1d2364f0f..8da33899a 100644 --- a/src/arch/x86/isa/insts/compare_and_test/test.py +++ b/src/arch/x86/isa/insts/compare_and_test/test.py @@ -63,7 +63,7 @@ def macroop TEST_M_R def macroop TEST_P_R { rdip t7 - ld t1, ds, [scale, index, base], disp + ld t1, ds, [0, t0, t7], disp and t0, t1, reg, flags=(SF, ZF, PF) }; @@ -82,7 +82,7 @@ def macroop TEST_M_I def macroop TEST_P_I { rdip t7 - ld t1, ds, [scale, index, base], disp + ld t1, ds, [0, t0, t7], disp limm t2, imm and t0, t1, t2, flags=(SF, ZF, PF) }; diff --git a/src/arch/x86/isa/insts/control_transfer/jump.py b/src/arch/x86/isa/insts/control_transfer/jump.py index 15f00e083..e01925f41 100644 --- a/src/arch/x86/isa/insts/control_transfer/jump.py +++ b/src/arch/x86/isa/insts/control_transfer/jump.py @@ -56,6 +56,9 @@ microcode = ''' def macroop JZ_I { + # Make the defualt data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + rdip t1 limm t2, imm wrip t1, t2, flags=(CZF,) @@ -63,8 +66,53 @@ def macroop JZ_I def macroop JNZ_I { + # Make the defualt data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + rdip t1 limm t2, imm wrip t1, t2, flags=(nCZF,) }; + +def macroop JNB_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(nCCF,) +}; + +def macroop JBE_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(CCvZF,) +}; + +def macroop JMP_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2 +}; + +def macroop JMP_R +{ + wripi reg, 0 +}; + +def macroop JMP_M +{ + ld t1, ds, [scale, index, base], disp + wripi t1, 0 +}; + ''' diff --git a/src/arch/x86/isa/insts/data_transfer/move.py b/src/arch/x86/isa/insts/data_transfer/move.py index c85dd7cc4..9856b5051 100644 --- a/src/arch/x86/isa/insts/data_transfer/move.py +++ b/src/arch/x86/isa/insts/data_transfer/move.py @@ -64,7 +64,7 @@ def macroop MOV_M_R { def macroop MOV_P_R { rdip t7 - st reg, ds, [scale, index, base], disp + st reg, ds, [0, t0, t7], disp }; def macroop MOV_R_M { @@ -73,7 +73,7 @@ def macroop MOV_R_M { def macroop MOV_R_P { rdip t7 - ld reg, ds, [scale, index, base], disp + ld reg, ds, [0, t0, t7], disp }; def macroop MOV_R_I { @@ -88,7 +88,7 @@ def macroop MOV_M_I { def macroop MOV_P_I { rdip t7 limm t1, imm - st t1, ds, [scale, index, base], disp + st t1, ds, [0, t0, t7], disp }; def macroop MOVSXD_R_R { @@ -102,9 +102,67 @@ def macroop MOVSXD_R_M { def macroop MOVSXD_R_P { rdip t7 - ld t1, ds, [scale, index, base], disp + ld t1, ds, [0, t0, t7], disp sext reg, t1, dsz }; + +def macroop MOVZX_B_R_R { + mov reg, reg, t0 + mov reg, reg, regm, dataSize=1 +}; + +def macroop MOVZX_B_R_M { + mov reg, reg, t0 + ld reg, ds, [scale, index, base], disp, dataSize=1 +}; + +def macroop MOVZX_B_R_P { + rdip t7 + mov reg, reg, t0 + ld reg, ds, [0, t0, t7], disp, dataSize=1 +}; + +def macroop MOVZX_B_M_R { + mov t1, t1, t0 + mov t1, t1, reg, dataSize=1 + st t1, ds, [scale, index, base], disp +}; + +def macroop MOVZX_B_P_R { + rdip t7 + mov t1, t1, t0 + mov t1, t1, reg, dataSize=1 + st t1, ds, [0, t0, t7], disp +}; + +def macroop MOVZX_W_R_R { + mov reg, reg, t0 + mov reg, reg, regm, dataSize=2 +}; + +def macroop MOVZX_W_R_M { + mov reg, reg, t0 + ld reg, ds, [scale, index, base], disp, dataSize=2 +}; + +def macroop MOVZX_W_R_P { + rdip t7 + mov reg, reg, t0 + ld reg, ds, [0, t0, t7], disp, dataSize=2 +}; + +def macroop MOVZX_W_M_R { + mov t1, t1, t0 + mov t1, t1, reg, dataSize=2 + st t1, ds, [scale, index, base], disp +}; + +def macroop MOVZX_W_P_R { + rdip t7 + mov t1, t1, t0 + mov t1, t1, reg, dataSize=2 + st t1, ds, [0, t0, t7], disp +}; ''' #let {{ # class MOV(Inst): diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 9ceaaac19..baa692f83 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -325,12 +325,12 @@ def template MicroLdStOpConstructor {{ let {{ class LdStOp(X86Microop): - def __init__(self, data, segment, addr, disp): + def __init__(self, data, segment, addr, disp, dataSize): self.data = data [self.scale, self.index, self.base] = addr self.disp = disp self.segment = segment - self.dataSize = "env.dataSize" + self.dataSize = dataSize self.addressSize = "env.addressSize" def getAllocator(self, *microFlags): @@ -376,8 +376,10 @@ let {{ exec_output += MicroLoadCompleteAcc.subst(iop) class LoadOp(LdStOp): - def __init__(self, data, segment, addr, disp = 0): - super(LoadOp, self).__init__(data, segment, addr, disp) + def __init__(self, data, segment, addr, + disp = 0, dataSize="env.dataSize"): + super(LoadOp, self).__init__(data, segment, + addr, disp, dataSize) self.className = Name self.mnemonic = name @@ -403,8 +405,10 @@ let {{ exec_output += MicroStoreCompleteAcc.subst(iop) class StoreOp(LdStOp): - def __init__(self, data, segment, addr, disp = 0): - super(StoreOp, self).__init__(data, segment, addr, disp) + def __init__(self, data, segment, addr, + disp = 0, dataSize="env.dataSize"): + super(StoreOp, self).__init__(data, segment, + addr, disp, dataSize) self.className = Name self.mnemonic = name @@ -419,8 +423,10 @@ let {{ exec_output += MicroLeaExecute.subst(iop) class LeaOp(LdStOp): - def __init__(self, data, segment, addr, disp = 0): - super(LeaOp, self).__init__(data, segment, addr, disp) + def __init__(self, data, segment, addr, + disp = 0, dataSize="env.dataSize"): + super(LeaOp, self).__init__(data, segment, + addr, disp, dataSize) self.className = "Lea" self.mnemonic = "lea" diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 37cbaa8c6..f833f89be 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -126,12 +126,12 @@ def template MicroRegOpDeclare {{ const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, RegIndex _src1, RegIndex _src2, RegIndex _dest, - uint8_t _dataSize, uint8_t _ext); + uint8_t _dataSize, uint16_t _ext); %(class_name)s(ExtMachInst _machInst, const char * instMnem, RegIndex _src1, RegIndex _src2, RegIndex _dest, - uint8_t _dataSize, uint8_t _ext); + uint8_t _dataSize, uint16_t _ext); %(BasicExecDeclare)s }; @@ -149,12 +149,12 @@ def template MicroRegOpImmDeclare {{ const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, RegIndex _src1, uint8_t _imm8, RegIndex _dest, - uint8_t _dataSize, uint8_t _ext); + uint8_t _dataSize, uint16_t _ext); %(class_name)sImm(ExtMachInst _machInst, const char * instMnem, RegIndex _src1, uint8_t _imm8, RegIndex _dest, - uint8_t _dataSize, uint8_t _ext); + uint8_t _dataSize, uint16_t _ext); %(BasicExecDeclare)s }; @@ -170,7 +170,7 @@ def template MicroRegOpConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, RegIndex _src1, RegIndex _src2, RegIndex _dest, - uint8_t _dataSize, uint8_t _ext) : + uint8_t _dataSize, uint16_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, false, false, false, false, _src1, _src2, _dest, _dataSize, _ext, @@ -183,7 +183,7 @@ def template MicroRegOpConstructor {{ ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, RegIndex _src1, RegIndex _src2, RegIndex _dest, - uint8_t _dataSize, uint8_t _ext) : + uint8_t _dataSize, uint16_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, isMicro, isDelayed, isFirst, isLast, _src1, _src2, _dest, _dataSize, _ext, @@ -203,7 +203,7 @@ def template MicroRegOpImmConstructor {{ inline %(class_name)sImm::%(class_name)sImm( ExtMachInst machInst, const char * instMnem, RegIndex _src1, uint8_t _imm8, RegIndex _dest, - uint8_t _dataSize, uint8_t _ext) : + uint8_t _dataSize, uint16_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, false, false, false, false, _src1, _imm8, _dest, _dataSize, _ext, @@ -216,7 +216,7 @@ def template MicroRegOpImmConstructor {{ ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, RegIndex _src1, uint8_t _imm8, RegIndex _dest, - uint8_t _dataSize, uint8_t _ext) : + uint8_t _dataSize, uint16_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, isMicro, isDelayed, isFirst, isLast, _src1, _imm8, _dest, _dataSize, _ext, diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 83df583ea..406c74a1f 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -102,6 +102,7 @@ def operands {{ 'Base': ('IntReg', 'uqw', 'base', 'IsInteger', 4), 'Index': ('IntReg', 'uqw', 'index', 'IsInteger', 5), 'Data': ('IntReg', 'uqw', 'data', 'IsInteger', 6), + 'rax': ('IntReg', 'uqw', 'INTREG_RAX', 'IsInteger', 7), 'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 10), 'ccFlagBits': ('IntReg', 'uqw', 'NUM_INTREGS + NumMicroIntRegs', None, 20), 'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100) diff --git a/src/arch/x86/syscallreturn.hh b/src/arch/x86/syscallreturn.hh index 9f0d20e2a..6a7fdba58 100644 --- a/src/arch/x86/syscallreturn.hh +++ b/src/arch/x86/syscallreturn.hh @@ -59,16 +59,15 @@ #define __ARCH_X86_SYSCALLRETURN_HH__ #include "base/misc.hh" +#include "cpu/thread_context.hh" #include "sim/syscallreturn.hh" -class ThreadContext; - namespace X86ISA { static inline void setSyscallReturn(SyscallReturn return_value, ThreadContext * tc) { - panic("setSyscallReturn not implemented!\n"); + tc->setIntReg(INTREG_RAX, return_value.value()); } }; -- cgit v1.2.3 From 0781609693ef3ec0ee12aa6031c62d8a2e67d49c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 14:52:44 -0700 Subject: Fixed width parameter and provided a parameter to flip the carry bit on subtract. --HG-- extra : convert_revision : d01bb791b000a2fdfc8600f8fb2f8aadd52b0b63 --- src/arch/x86/insts/microregop.cc | 30 +++++++++++++++++++----------- src/arch/x86/insts/microregop.hh | 3 ++- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/arch/x86/insts/microregop.cc b/src/arch/x86/insts/microregop.cc index f4559d95f..976b04688 100644 --- a/src/arch/x86/insts/microregop.cc +++ b/src/arch/x86/insts/microregop.cc @@ -63,24 +63,32 @@ namespace X86ISA { uint64_t RegOpBase::genFlags(uint64_t oldFlags, uint64_t flagMask, - uint64_t _dest, uint64_t _src1, uint64_t _src2) const + uint64_t _dest, uint64_t _src1, uint64_t _src2, + bool subtract) const { + DPRINTF(Sparc, "flagMask = %#x\n", flagMask); uint64_t flags = oldFlags & ~flagMask; - if(flagMask & CFBit && findCarry(dataSize, _dest, _src1, _src2)) - flags |= CFBit; - if(flagMask & PFBit && findParity(dataSize, _dest)) + if(flagMask & CFBit) + if(findCarry(dataSize*8, _dest, _src1, _src2)) + flags |= CFBit; + if(subtract) + flags ^= CFBit; + if(flagMask & PFBit && findParity(dataSize*8, _dest)) flags |= PFBit; - if(flagMask & ECFBit && findCarry(dataSize, _dest, _src1, _src2)) + if(flagMask & ECFBit && findCarry(dataSize*8, _dest, _src1, _src2)) flags |= ECFBit; - if(flagMask & AFBit && findCarry(4, _dest, _src1, _src2)) - flags |= AFBit; - if(flagMask & EZFBit && findZero(dataSize, _dest)) + if(flagMask & AFBit) + if(findCarry(4, _dest, _src1, _src2)) + flags |= AFBit; + if(subtract) + flags ^= AFBit; + if(flagMask & EZFBit && findZero(dataSize*8, _dest)) flags |= EZFBit; - if(flagMask & ZFBit && findZero(dataSize, _dest)) + if(flagMask & ZFBit && findZero(dataSize*8, _dest)) flags |= ZFBit; - if(flagMask & SFBit && findNegative(dataSize, _dest)) + if(flagMask & SFBit && findNegative(dataSize*8, _dest)) flags |= SFBit; - if(flagMask & OFBit && findOverflow(dataSize, _dest, _src1, _src2)) + if(flagMask & OFBit && findOverflow(dataSize*8, _dest, _src1, _src2)) flags |= OFBit; return flags; } diff --git a/src/arch/x86/insts/microregop.hh b/src/arch/x86/insts/microregop.hh index a8049ba19..f411c0775 100644 --- a/src/arch/x86/insts/microregop.hh +++ b/src/arch/x86/insts/microregop.hh @@ -132,7 +132,8 @@ namespace X86ISA //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) const; + uint64_t _dest, uint64_t _src1, uint64_t _src2, + bool subtract = false) const; bool checkCondition(uint64_t flags) const; }; -- cgit v1.2.3 From 0baae59c0902d17158fc592bf4dbd0e97fe6d33e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 14:53:38 -0700 Subject: Fix carry flag for subtracts, and clean up code slightly. --HG-- extra : convert_revision : 668f5d5aeba888488b41284de6c72a0d055c4ef4 --- src/arch/x86/isa/microops/regop.isa | 42 ++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index f833f89be..a0e8adc9a 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -309,7 +309,7 @@ let {{ exec_output = "" # A function which builds the C++ classes that implement the microops - def setUpMicroRegOp(name, Name, base, code, flagCode, condCheck, elseCode): + def setUpMicroRegOp(name, Name, base, code, flagCode = "", condCheck = "true", elseCode = ";"): global header_output global decoder_output global exec_output @@ -331,7 +331,7 @@ let {{ # This creates a python representations of a microop which are a cross # product of reg/immediate and flag/no flag versions. - def defineMicroRegOp(mnemonic, code, secondSrc = "op2", cc=False, elseCode=";"): + def defineMicroRegOp(mnemonic, code, subtract = False, cc=False, elseCode=";"): Name = mnemonic name = mnemonic.lower() @@ -342,6 +342,11 @@ let {{ regCode = matcher.sub("SrcReg2", code) immCode = matcher.sub("imm8", code) + if subtract: + secondSrc = "-op2, true" + else: + secondSrc = "op2" + if not cc: flagCode = genCCFlagBits % secondSrc condCode = "true" @@ -360,8 +365,9 @@ let {{ microopClasses[name] = RegOpChild - setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, "", "true", elseCode); - setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, regFlagCode, condCode, elseCode); + setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode); + setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, + flagCode = regFlagCode, condCheck = condCode, elseCode = elseCode); class RegOpChildImm(RegOpImm): mnemonic = name + 'i' @@ -371,17 +377,19 @@ let {{ microopClasses[name + 'i'] = RegOpChildImm - setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode, "", "true", elseCode); - setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode, immFlagCode, condCode, elseCode); + setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode); + setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode, + flagCode = immFlagCode, condCheck = condCode, elseCode = elseCode); defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)') defineMicroRegOp('Adc', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') - defineMicroRegOp('Sbb', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', '-op2') + defineMicroRegOp('Sbb', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True) defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)') - defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', '-op2') + defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True) defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)') - defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', '-op2') + defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True) + defineMicroRegOp('mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)') defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', elseCode='DestReg=DestReg;', cc=True) @@ -405,8 +413,9 @@ let {{ microopClasses[name] = RegOpChild - setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, "", "true", elseCode); - setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, "", checkCCFlagBits, elseCode); + setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode); + setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, + condCheck = checkCCFlagBits, elseCode = elseCode); class RegOpChildImm(RegOpImm): mnemonic = name + 'i' @@ -416,8 +425,9 @@ let {{ microopClasses[name + 'i'] = RegOpChildImm - setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", immCode, "", "true", elseCode); - setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode, "", checkCCFlagBits, elseCode); + setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", immCode); + setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode, + condCheck = checkCCFlagBits, elseCode = elseCode); defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;") @@ -434,7 +444,7 @@ let {{ microopClasses[name] = RegOpChild - setUpMicroRegOp(name, Name, "X86ISA::RegOp", code, "", "true", ";"); + setUpMicroRegOp(name, Name, "X86ISA::RegOp", code); defineMicroRegOpRd('Rdip', 'DestReg = RIP') @@ -450,11 +460,13 @@ let {{ microopClasses[name] = RegOpChild - setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, "", "true", ";"); + setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code); defineMicroRegOpImm('Sext', ''' IntReg val = SrcReg1; int sign_bit = bits(val, imm8-1, imm8-1); val = sign_bit ? (val | ~mask(imm8)) : val; DestReg = merge(DestReg, val, dataSize);''') + + defineMicroRegOpImm('Zext', 'DestReg = bits(SrcReg1, imm8-1, 0);') }}; -- cgit v1.2.3 From ee22bcd60940ed8cd23865e40ed8debc6c1f4288 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 14:54:17 -0700 Subject: Fix function which calculates the carry flag. --HG-- extra : convert_revision : aeb4f2d4c3936089421dbe80647f28ae36178283 --- src/base/condcodes.hh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/base/condcodes.hh b/src/base/condcodes.hh index 10109e4ad..efff12dc8 100644 --- a/src/base/condcodes.hh +++ b/src/base/condcodes.hh @@ -32,6 +32,7 @@ #define __BASE_CONDCODE_HH__ #include "base/bitfield.hh" +#include "base/trace.hh" /** * Calculate the carry flag from an addition. This should work even when @@ -41,7 +42,9 @@ inline bool findCarry(int width, uint64_t dest, uint64_t src1, uint64_t src2) { int shift = width - 1; - return (~(dest >> shift) + (src1 >> shift) + (src2 >> shift)) & 0x2; + return ((~(dest >> shift) & 1) + + ((src1 >> shift) & 1) + + ((src2 >> shift) & 1)) & 0x2; } /** -- cgit v1.2.3 From dcfaa348b190c97a2476b0e9c099160c8c1e0202 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 14:55:16 -0700 Subject: Add a parameter type to read a register index from the opcode itself. --HG-- extra : convert_revision : d2b5468ebf5df5a6ccadb57a30c52c8d16417b9a --- src/arch/x86/isa/specialize.isa | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/arch/x86/isa/specialize.isa b/src/arch/x86/isa/specialize.isa index 3183f32ba..5165ea206 100644 --- a/src/arch/x86/isa/specialize.isa +++ b/src/arch/x86/isa/specialize.isa @@ -118,6 +118,7 @@ let {{ ModRMRegIndex = "(MODRM_REG | (REX_R << 3))" ModRMRMIndex = "(MODRM_RM | (REX_B << 3))" + InstRegIndex = "(OPCODE_OP_BOTTOM3 | (REX_B << 3))" # This function specializes the given piece of code to use a particular # set of argument types described by "opTypes". @@ -143,6 +144,10 @@ let {{ else: print "Didn't recognize fixed register size %s!" % opType.rsize Name += "_R" + elif opType.tag == "B": + # This refers to registers whose index is encoded as part of the opcode + Name += "_R" + env.addReg(InstRegIndex) elif opType.tag == "M": # This refers to memory. The macroop constructor sets up modrm # addressing. Non memory modrm settings should cause an error. -- cgit v1.2.3 From 5d882984d197e8edc59678d6699c9e205cd77a89 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 14:57:04 -0700 Subject: Add a bitfield to decode based on what prefixes are used. --HG-- extra : convert_revision : 7ff4998b3249ccfe86ae9cbcc63fb910683707f5 --- src/arch/x86/isa/bitfields.isa | 3 ++- src/arch/x86/types.hh | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/arch/x86/isa/bitfields.isa b/src/arch/x86/isa/bitfields.isa index 8707bbb4c..43fee5fef 100644 --- a/src/arch/x86/isa/bitfields.isa +++ b/src/arch/x86/isa/bitfields.isa @@ -67,11 +67,12 @@ def bitfield REX_B rex.b; //Legacy prefixes def bitfield LEGACY legacy; +def bitfield LEGACY_DECODEVAL legacy.decodeVal; def bitfield LEGACY_REPNE legacy.repne; def bitfield LEGACY_REP legacy.rep; def bitfield LEGACY_LOCK legacy.lock; -def bitfield LEGACY_ADDR legacy.addr; def bitfield LEGACY_OP legacy.op; +def bitfield LEGACY_ADDR legacy.addr; def bitfield LEGACY_SEG legacy.seg; // Pieces of the opcode diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh index 9d927679d..a509ff57a 100644 --- a/src/arch/x86/types.hh +++ b/src/arch/x86/types.hh @@ -86,11 +86,12 @@ namespace X86ISA }; BitUnion8(LegacyPrefixVector) + Bitfield<7, 4> decodeVal; Bitfield<7> repne; Bitfield<6> rep; Bitfield<5> lock; - Bitfield<4> addr; - Bitfield<3> op; + Bitfield<4> op; + Bitfield<3> addr; //There can be only one segment override, so they share the //first 3 bits in the legacyPrefixes bitfield. Bitfield<2,0> seg; -- cgit v1.2.3 From ec5f66190e7169acf76edd715ccda309806daf87 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 14:57:34 -0700 Subject: Fix code that computes displacement size. --HG-- extra : convert_revision : a9be3eb2b90b88086936aeb4dcf87ec7b58a48cb --- src/arch/x86/predecoder.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc index 6052d8392..b6c488e45 100644 --- a/src/arch/x86/predecoder.cc +++ b/src/arch/x86/predecoder.cc @@ -305,8 +305,7 @@ namespace X86ISA displacementSize = 0; } else { //figure out 32/64 bit displacement size - if(modRM.mod == 0 && (modRM.rm == 4 || modRM.rm == 5) - || modRM.mod == 2) + if(modRM.mod == 0 && modRM.rm == 5 || modRM.mod == 2) displacementSize = 4; else if(modRM.mod == 1) displacementSize = 1; -- cgit v1.2.3 From d926de462a6580b09a05d7a2fdf7eae699f51915 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 14:59:14 -0700 Subject: Implement the increment and decrement instructions, and the two operand form of signed multiplication. --HG-- extra : convert_revision : d87df4b1b5470bed1d963dfe8e2ffa1403718342 --- .../insts/arithmetic/increment_and_decrement.py | 42 +++++++++++++++++++++- .../isa/insts/arithmetic/multiply_and_divide.py | 26 +++++++++++++- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/isa/insts/arithmetic/increment_and_decrement.py b/src/arch/x86/isa/insts/arithmetic/increment_and_decrement.py index c504d47ce..eed39c10c 100644 --- a/src/arch/x86/isa/insts/arithmetic/increment_and_decrement.py +++ b/src/arch/x86/isa/insts/arithmetic/increment_and_decrement.py @@ -53,7 +53,47 @@ # # Authors: Gabe Black -microcode = "" +microcode = ''' +def macroop INC_R +{ + addi reg, reg, 1, flags=(OF, SF, ZF, AF, PF) +}; + +def macroop INC_M +{ + ld t1, ds, [scale, index, base], disp + addi t1, t1, 1, flags=(OF, SF, ZF, AF, PF) + st t1, ds, [scale, index, base], disp +}; + +def macroop INC_P +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + addi reg, reg, 1, flags=(OF, SF, ZF, AF, PF) + st t1, ds, [0, t0, t7], disp +}; + +def macroop DEC_R +{ + subi reg, reg, 1, flags=(OF, SF, ZF, AF, PF) +}; + +def macroop DEC_M +{ + ld t1, ds, [scale, index, base], disp + subi t1, t1, 1, flags=(OF, SF, ZF, AF, PF) + st t1, ds, [scale, index, base], disp +}; + +def macroop DEC_P +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + subi reg, reg, 1, flags=(OF, SF, ZF, AF, PF) + st t1, ds, [0, t0, t7], disp +}; +''' #let {{ # class DEC(Inst): # "GenFault ${new UnimpInstFault}" diff --git a/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py b/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py index 662022e6a..8697bef65 100644 --- a/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py +++ b/src/arch/x86/isa/insts/arithmetic/multiply_and_divide.py @@ -53,7 +53,31 @@ # # Authors: Gabe Black -microcode = "" +microcode = ''' + +# +# Two operand signed multiply. These should set the CF and OF flags if the +# result is too large for the destination register +# + +def macroop IMUL_R_R +{ + mul1s reg, reg, regm +}; + +def macroop IMUL_R_M +{ + ld t1, ds, [scale, index, base], disp + mul1s reg, reg, t1 +}; + +def macroop IMUL_R_P +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + mul1s reg, reg, t1 +}; +''' #let {{ # class MUL(Inst): # "GenFault ${new UnimpInstFault}" -- cgit v1.2.3 From f09847c7a69c25ab553dd95c73af05bbe4b01859 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 15:02:09 -0700 Subject: Make load and store ops use the appropriate sized data access. --HG-- extra : convert_revision : 6b808586fab10ca433ef04b062bf701b906634b9 --- src/arch/x86/isa/microops/ldstop.isa | 81 +++++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 6 deletions(-) diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index baa692f83..ccf519963 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -123,7 +123,25 @@ def template MicroLoadExecute {{ %(ea_code)s; DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); - fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0); + unsigned flags = 0; + switch(dataSize) + { + case 1: + fault = xc->read(EA, (uint8_t&)Mem, flags); + break; + case 2: + fault = xc->read(EA, (uint16_t&)Mem, flags); + break; + case 4: + fault = xc->read(EA, (uint32_t&)Mem, flags); + break; + case 8: + fault = xc->read(EA, (uint64_t&)Mem, flags); + break; + default: + panic("Bad operand size!\n"); + } + if(fault == NoFault) { %(code)s; @@ -149,7 +167,24 @@ def template MicroLoadInitiateAcc {{ %(ea_code)s; DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); - fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0); + unsigned flags = 0; + switch(dataSize) + { + case 1: + fault = xc->read(EA, (uint8_t&)Mem, flags); + break; + case 2: + fault = xc->read(EA, (uint16_t&)Mem, flags); + break; + case 4: + fault = xc->read(EA, (uint32_t&)Mem, flags); + break; + case 8: + fault = xc->read(EA, (uint64_t&)Mem, flags); + break; + default: + panic("Bad operand size!\n"); + } return fault; } @@ -195,8 +230,25 @@ def template MicroStoreExecute {{ if(fault == NoFault) { - fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem, - EA, 0, 0); + unsigned flags = 0; + uint64_t *res = 0; + switch(dataSize) + { + case 1: + fault = xc->write((uint8_t&)Mem, EA, flags, res); + break; + case 2: + fault = xc->write((uint16_t&)Mem, EA, flags, res); + break; + case 4: + fault = xc->write((uint32_t&)Mem, EA, flags, res); + break; + case 8: + fault = xc->write((uint64_t&)Mem, EA, flags, res); + break; + default: + panic("Bad operand size!\n"); + } } if(fault == NoFault) { @@ -223,8 +275,25 @@ def template MicroStoreInitiateAcc {{ if(fault == NoFault) { - fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem, - EA, 0, 0); + unsigned flags = 0; + uint64_t *res = 0; + switch(dataSize) + { + case 1: + fault = xc->write((uint8_t&)Mem, EA, flags, res); + break; + case 2: + fault = xc->write((uint16_t&)Mem, EA, flags, res); + break; + case 4: + fault = xc->write((uint32_t&)Mem, EA, flags, res); + break; + case 8: + fault = xc->write((uint64_t&)Mem, EA, flags, res); + break; + default: + panic("Bad operand size!\n"); + } } if(fault == NoFault) { -- cgit v1.2.3 From 79b3208aa585e04f3ccf7559777854c2fae1a698 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 15:03:03 -0700 Subject: Appended _NEAR to the near version of call and return. --HG-- extra : convert_revision : 70adb38d59ff7b5d103e58a9f0773dfb911fec6d --- src/arch/x86/isa/insts/control_transfer/call.py | 2 +- src/arch/x86/isa/insts/control_transfer/xreturn.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/isa/insts/control_transfer/call.py b/src/arch/x86/isa/insts/control_transfer/call.py index b9ba621e5..c40080d85 100644 --- a/src/arch/x86/isa/insts/control_transfer/call.py +++ b/src/arch/x86/isa/insts/control_transfer/call.py @@ -54,7 +54,7 @@ # Authors: Gabe Black microcode = ''' -def macroop CALL_I +def macroop CALL_NEAR_I { # Make the default data size of calls 64 bits in 64 bit mode .adjust_env oszIn64Override diff --git a/src/arch/x86/isa/insts/control_transfer/xreturn.py b/src/arch/x86/isa/insts/control_transfer/xreturn.py index 1e8e0ba55..c4442ea02 100644 --- a/src/arch/x86/isa/insts/control_transfer/xreturn.py +++ b/src/arch/x86/isa/insts/control_transfer/xreturn.py @@ -54,7 +54,7 @@ # Authors: Gabe Black microcode = ''' -def macroop RET +def macroop RET_NEAR { # Make the default data size of rets 64 bits in 64 bit mode .adjust_env oszIn64Override -- cgit v1.2.3 From fcc23891bbfd06cff9d3f486a6c73eb9d159aa07 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 15:03:36 -0700 Subject: Implement jnbe. --HG-- extra : convert_revision : cdbf1ff5ed3a63787cbd2187a8a3455a41cc5085 --- src/arch/x86/isa/insts/control_transfer/jump.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/arch/x86/isa/insts/control_transfer/jump.py b/src/arch/x86/isa/insts/control_transfer/jump.py index e01925f41..b191730d5 100644 --- a/src/arch/x86/isa/insts/control_transfer/jump.py +++ b/src/arch/x86/isa/insts/control_transfer/jump.py @@ -94,6 +94,16 @@ def macroop JBE_I wrip t1, t2, flags=(CCvZF,) }; +def macroop JNBE_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(nCCvZF,) +}; + def macroop JMP_I { # Make the default data size of jumps 64 bits in 64 bit mode -- cgit v1.2.3 From dfcb2ffa462c37497579bd2bab88af8ba09c3f56 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 15:04:41 -0700 Subject: Comment, implement, fix, and trim the move microassembly. --HG-- extra : convert_revision : aa5ee7270e740bfbe42e70c4dfccc4c91ecacb33 --- src/arch/x86/isa/insts/data_transfer/move.py | 89 ++++++++++++++++------------ 1 file changed, 52 insertions(+), 37 deletions(-) diff --git a/src/arch/x86/isa/insts/data_transfer/move.py b/src/arch/x86/isa/insts/data_transfer/move.py index 9856b5051..bbc55e47c 100644 --- a/src/arch/x86/isa/insts/data_transfer/move.py +++ b/src/arch/x86/isa/insts/data_transfer/move.py @@ -54,6 +54,11 @@ # Authors: Gabe Black microcode = ''' + +# +# Regular moves +# + def macroop MOV_R_R { mov reg, reg, regm }; @@ -91,77 +96,87 @@ def macroop MOV_P_I { st t1, ds, [0, t0, t7], disp }; +# +# Sign extending moves +# + def macroop MOVSXD_R_R { - sext reg, regm, dsz + sext reg, regm, 32 }; def macroop MOVSXD_R_M { - ld t1, ds, [scale, index, base], disp - sext reg, t1, dsz + ld t1, ds, [scale, index, base], disp, dataSize=4 + sext reg, t1, 32 }; def macroop MOVSXD_R_P { rdip t7 - ld t1, ds, [0, t0, t7], disp - sext reg, t1, dsz + ld t1, ds, [0, t0, t7], disp, dataSize=4 + sext reg, t1, 32 }; -def macroop MOVZX_B_R_R { - mov reg, reg, t0 - mov reg, reg, regm, dataSize=1 +def macroop MOVSX_B_R_R { + sext reg, regm, 8 }; -def macroop MOVZX_B_R_M { - mov reg, reg, t0 +def macroop MOVSX_B_R_M { ld reg, ds, [scale, index, base], disp, dataSize=1 + sext reg, reg, 8 }; -def macroop MOVZX_B_R_P { +def macroop MOVSX_B_R_P { rdip t7 - mov reg, reg, t0 ld reg, ds, [0, t0, t7], disp, dataSize=1 + sext reg, reg, 8 }; -def macroop MOVZX_B_M_R { - mov t1, t1, t0 - mov t1, t1, reg, dataSize=1 - st t1, ds, [scale, index, base], disp +def macroop MOVSX_W_R_R { + sext reg, regm, 16 +}; + +def macroop MOVSX_W_R_M { + ld reg, ds, [scale, index, base], disp, dataSize=2 + sext reg, reg, 16 }; -def macroop MOVZX_B_P_R { +def macroop MOVSX_W_R_P { rdip t7 - mov t1, t1, t0 - mov t1, t1, reg, dataSize=1 - st t1, ds, [0, t0, t7], disp + ld reg, ds, [0, t0, t7], disp, dataSize=2 + sext reg, reg, 16 }; -def macroop MOVZX_W_R_R { - mov reg, reg, t0 - mov reg, reg, regm, dataSize=2 +# +# Zero extending moves +# + +def macroop MOVZX_B_R_R { + zext reg, regm, 8 }; -def macroop MOVZX_W_R_M { - mov reg, reg, t0 - ld reg, ds, [scale, index, base], disp, dataSize=2 +def macroop MOVZX_B_R_M { + ld t1, ds, [scale, index, base], disp, dataSize=1 + zext reg, t1, 8 }; -def macroop MOVZX_W_R_P { +def macroop MOVZX_B_R_P { rdip t7 - mov reg, reg, t0 - ld reg, ds, [0, t0, t7], disp, dataSize=2 + ld t1, ds, [0, t0, t7], disp, dataSize=1 + zext reg, t1, 8 }; -def macroop MOVZX_W_M_R { - mov t1, t1, t0 - mov t1, t1, reg, dataSize=2 - st t1, ds, [scale, index, base], disp +def macroop MOVZX_W_R_R { + zext reg, regm, 16 +}; + +def macroop MOVZX_W_R_M { + ld t1, ds, [scale, index, base], disp, dataSize=2 + zext reg, t1, 16 }; -def macroop MOVZX_W_P_R { +def macroop MOVZX_W_R_P { rdip t7 - mov t1, t1, t0 - mov t1, t1, reg, dataSize=2 - st t1, ds, [0, t0, t7], disp + ld t1, ds, [0, t0, t7], disp, dataSize=2 + zext reg, t1, 16 }; ''' #let {{ -- cgit v1.2.3 From 705a22b999b92283ab1df0c7b3476022f8b0c0d2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 15:05:37 -0700 Subject: Hook in newly implemented instructions. --HG-- extra : convert_revision : 53319d2363211af407dabaa2b63ad8a4df09c369 --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 50 ++++++++++++++++----------- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 8 ++--- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index ee6072454..b897a225b 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -176,28 +176,28 @@ 0x0: M5InternalError::error ( {{"Tried to execute an REX prefix!"}}); default: decode OPCODE_OP_BOTTOM3 { - 0x0: inc_eAX(); - 0x1: inc_eCX(); - 0x2: inc_eDX(); - 0x3: inc_eBX(); - 0x4: inc_eSP(); - 0x5: inc_eBP(); - 0x6: inc_eSI(); - 0x7: inc_eDI(); + 0x0: Inst::INC(rAx); + 0x1: Inst::INC(rCx); + 0x2: Inst::INC(rDx); + 0x3: Inst::INC(rBx); + 0x4: Inst::INC(rSP); + 0x5: Inst::INC(rBP); + 0x6: Inst::INC(rSI); + 0x7: Inst::INC(rDI); } } 0x09: decode MODE_SUBMODE { 0x0: M5InternalError::error ( {{"Tried to execute an REX prefix!"}}); default: decode OPCODE_OP_BOTTOM3 { - 0x0: dec_eAX(); - 0x1: dec_eCX(); - 0x2: dec_eDX(); - 0x3: dec_eBX(); - 0x4: dec_eSP(); - 0x5: dec_eBP(); - 0x6: dec_eSI(); - 0x7: dec_eDI(); + 0x0: Inst::DEC(rAx); + 0x1: Inst::DEC(rCX); + 0x2: Inst::DEC(rDx); + 0x3: Inst::DEC(rBx); + 0x4: Inst::DEC(rSP); + 0x5: Inst::DEC(rBP); + 0x6: Inst::DEC(rSI); + 0x7: Inst::DEC(rDI); } } format Inst { @@ -266,7 +266,7 @@ 0x4: Inst::JZ(Jb); 0x5: Inst::JNZ(Jb); 0x6: Inst::JBE(Jb); - 0x7: jnbe_Jb(); + 0x7: Inst::JNBE(Jb); } 0x0F: decode OPCODE_OP_BOTTOM3 { 0x0: js_Jb(); @@ -398,7 +398,7 @@ 0x0: group2_Eb_Ib(); 0x1: group2_Ev_Ib(); 0x2: ret_near_Iw(); - 0x3: Inst::RET(); + 0x3: Inst::RET_NEAR(); 0x4: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); default: les_Gz_Mp(); @@ -469,7 +469,7 @@ 0x7: out_Ib_eAX(); } 0x1D: decode OPCODE_OP_BOTTOM3 { - 0x0: Inst::CALL(Jz); + 0x0: Inst::CALL_NEAR(Jz); 0x1: jmp_Jz(); 0x2: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); @@ -502,7 +502,17 @@ 0x4: cld(); 0x5: std(); 0x6: group4(); - 0x7: group5(); + //0x7: group5(); + 0x7: decode MODRM_REG { + 0x0: Inst::INC(Ev); + 0x1: dev_Ev(); + 0x2: call_Ev(); + 0x3: call_Mp(); + 0x4: jmp_Ev(); + 0x5: jmp_Mp(); + 0x6: push_Ev(); + 0x7: This_should_be_an_illegal_instruction(); + } } } default: FailUnimpl::oneByteOps(); diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index e042893bb..6adcf866f 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -235,7 +235,7 @@ 0x4: Inst::JZ(Jz); 0x5: Inst::JNZ(Jz); 0x6: Inst::JBE(Jz); - 0x7: jnbe_Jz(); + 0x7: Inst::JNBE(Jz); } 0x11: decode OPCODE_OP_BOTTOM3 { 0x0: js_Jz(); @@ -285,7 +285,7 @@ 0x4: shrd_Ev_Gv_Ib(); 0x5: shrd_Ev_Gv_rCl(); 0x6: group16(); - 0x7: imul_Gv_Ev(); + 0x7: Inst::IMUL(Gv,Ev); } 0x16: decode OPCODE_OP_BOTTOM3 { 0x0: cmpxchg_Eb_Gb(); @@ -304,8 +304,8 @@ 0x3: btc_Ev_Gv(); 0x4: bsf_Gv_Ev(); 0x5: bsr_Gv_Ev(); - 0x6: movsx_Gv_Eb(); - 0x7: movsx_Gv_Ew(); + 0x6: Inst::MOVSX_B(Gv,Eb); + 0x7: Inst::MOVSX_W(Gv,Ew); } 0x18: decode OPCODE_OP_BOTTOM3 { 0x0: holder(); -- cgit v1.2.3 From 1ed6a8ed79d9a89437d47d52390aa5c7a8ebd5d5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 16:39:07 -0700 Subject: Define and fill out a lot of different instructions and instruction versions. Added two of the shift microops. --HG-- extra : convert_revision : 0b76953dbb1dc3366242d4d209cccebde86bbe4e --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 110 +++++++++++++-------- .../x86/isa/insts/arithmetic/add_and_subtract.py | 66 +++++++++++++ src/arch/x86/isa/insts/compare_and_test/compare.py | 46 +++++++++ src/arch/x86/isa/insts/control_transfer/jump.py | 10 ++ src/arch/x86/isa/insts/logical.py | 106 ++++++++++++++++++++ src/arch/x86/isa/insts/rotate_and_shift/shift.py | 22 ++++- src/arch/x86/isa/microops/regop.isa | 12 ++- 7 files changed, 331 insertions(+), 41 deletions(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index b897a225b..80031a7fc 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -61,8 +61,6 @@ 0x1: decode OPCODE_OP_TOP5 { format WarnUnimpl { 0x00: decode OPCODE_OP_BOTTOM3 { - 0x4: ADD(); - 0x5: ADD(); 0x6: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); default: push_ES(); @@ -71,15 +69,12 @@ 0x0: This_should_be_an_illegal_instruction(); default: pop_ES(); } - default: ADD(); + default: MultiInst::ADD(OPCODE_OP_BOTTOM3, + [Eb,Gb], [Ev,Gv], + [Gb,Eb], [Gv,Ev], + [rAl,Ib], [rAx,Iz]); } 0x01: decode OPCODE_OP_BOTTOM3 { - 0x0: or_Eb_Gb(); - 0x1: or_Ev_Gv(); - 0x2: or_Gb_Eb(); - 0x3: or_Gv_Ev(); - 0x4: or_Al_Ib(); - 0x5: or_rAX_Iz(); 0x6: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); default: push_CS(); @@ -87,6 +82,10 @@ //Any time this is seen, it should generate a two byte opcode 0x7: M5InternalError::error( {{"Saw a one byte opcode whose value was 0x0F!"}}); + default: MultiInst::OR(OPCODE_OP_BOTTOM3, + [Eb,Gb], [Ev,Gv], + [Gb,Eb], [Gv,Ev], + [rAl,Ib], [rAx,Iz]); } 0x02: decode OPCODE_OP_BOTTOM3 { 0x0: adc_Eb_Gb(); @@ -121,33 +120,27 @@ } } 0x04: decode OPCODE_OP_BOTTOM3 { - 0x0: and_Eb_Gb(); - 0x1: and_Ev_Gv(); - 0x2: and_Gb_Eb(); - 0x3: and_Gv_Ev(); - 0x4: and_Al_Ib(); - 0x5: and_rAX_Iz(); 0x6: M5InternalError::error( {{"Tried to execute the ES segment override prefix!"}}); 0x7: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); default: daa(); } + default: MultiInst::AND(OPCODE_OP_BOTTOM3, + [Eb,Gb], [Ev,Gv], + [Gb,Eb], [Gv,Ev], + [rAl,Ib], [rAx,Iz]); } 0x05: decode OPCODE_OP_BOTTOM3 { - 0x0: sub_Eb_Gb(); - 0x1: sub_Ev_Gv(); - 0x2: sub_Gb_Eb(); - 0x3: sub_Gv_Ev(); - 0x4: sub_Al_Ib(); - 0x5: sub_rAX_Iz(); 0x6: M5InternalError::error( {{"Tried to execute the CS segment override prefix!"}}); 0x7: das(); + default: MultiInst::SUB(OPCODE_OP_BOTTOM3, + [Eb,Gb], [Ev,Gv], + [Gb,Eb], [Gv,Ev], + [rAl,Ib], [rAx,Iz]); } 0x06: decode OPCODE_OP_BOTTOM3 { - 0x4: Inst::XOR(rAl,Ib); - 0x5: Inst::XOR(rAx,Iz); 0x6: M5InternalError::error( {{"Tried to execute the SS segment override prefix!"}}); 0x7: decode MODE_SUBMODE { @@ -156,21 +149,20 @@ } default: MultiInst::XOR(OPCODE_OP_BOTTOM3, [Eb,Gb], [Ev,Gv], - [Gb,Eb], [Gv,Ev]); + [Gb,Eb], [Gv,Ev], + [rAl,Ib], [rAx,Iz]); } 0x07: decode OPCODE_OP_BOTTOM3 { - 0x0: cmp_Eb_Gb(); - 0x1: cmp_Ev_Gv(); - 0x2: cmp_Gb_Eb(); - 0x3: cmp_Gv_Ev(); - 0x4: Inst::CMP(rAl,Ib); - 0x5: Inst::CMP(rAX,Iz); 0x6: M5InternalError::error( {{"Tried to execute the DS segment override prefix!"}}); 0x7: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); default: aas(); } + default: MultiInst::CMP(OPCODE_OP_BOTTOM3, + [Eb,Gb], [Ev,Gv], + [Gb,Eb], [Gv,Ev], + [rAl,Ib], [rAx,Iz]); } 0x08: decode MODE_SUBMODE { 0x0: M5InternalError::error ( @@ -276,10 +268,20 @@ 0x4: jl_Jb(); 0x5: jnl_Jb(); 0x6: jle_Jb(); - 0x7: jnke_Jb(); + 0x7: Inst::JNLE(Jb); } 0x10: decode OPCODE_OP_BOTTOM3 { - 0x0: group1_Eb_Ib(); + //0x0: group1_Eb_Ib(); + 0x0: decode MODRM_REG { + 0x0: Inst::ADD(Eb,Ib); + 0x1: Inst::OR(Eb,Ib); + 0x2: adc_Eb_Ib(); + 0x3: sbb_Eb_Ib(); + 0x4: Inst::AND(Eb,Ib); + 0x5: Inst::SUB(Eb,Ib); + 0x6: Inst::XOR(Eb,Ib); + 0x7: Inst::CMP(Eb,Ib); + } //0x1: group1_Ev_Iz(); 0x1: decode MODRM_REG { 0x0: add_Ev_Iz(); @@ -289,11 +291,21 @@ 0x4: Inst::AND(Ev,Iz); 0x5: Inst::SUB(Ev,Iz); 0x6: xor_Ev_Iz(); - 0x7: cmp_Ev_Iz(); + 0x7: Inst::CMP(Ev,Iz); } 0x2: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); - default: group1_Eb_Ib(); + //default: group1_Eb_Ib(); + default: decode MODRM_REG { + 0x0: Inst::ADD(Eb,Ib); + 0x1: Inst::OR(Eb,Ib); + 0x2: adc_Eb_Ib(); + 0x3: sbb_Eb_Ib(); + 0x4: Inst::AND(Eb,Ib); + 0x5: Inst::SUB(Eb,Ib); + 0x6: Inst::XOR(Eb,Ib); + 0x7: Inst::CMP(Eb,Ib); + } } //0x3: group1_Ev_Ib(); 0x3: decode MODRM_REG { @@ -304,7 +316,7 @@ 0x4: Inst::AND(Ev,Ib); 0x5: sub_Ev_Ib(); 0x6: xor_Ev_Ib(); - 0x7: cmp_Ev_Ib(); + 0x7: Inst::CMP(Ev,Ib); } 0x4: Inst::TEST(Eb,Gb); 0x5: Inst::TEST(Ev,Gv); @@ -322,10 +334,10 @@ 0x7: group10_Ev(); //Make sure this is Ev } 0x12: decode OPCODE_OP_BOTTOM3 { - default: Inst::NOP(); //XXX repe makes this a "pause" + 0x0: Inst::NOP(); //XXX repe makes this a "pause" 0x1: xchg_rCX_rAX(); 0x2: xchg_rDX_rAX(); - 0x3: xchg_rVX_rAX(); + 0x3: xchg_rBX_rAX(); 0x4: xchg_rSP_rAX(); 0x5: xchg_rBP_rAX(); 0x6: xchg_rSI_rAX(); @@ -395,8 +407,28 @@ } } 0x18: decode OPCODE_OP_BOTTOM3 { - 0x0: group2_Eb_Ib(); - 0x1: group2_Ev_Ib(); + //0x0: group2_Eb_Ib(); + 0x0: decode MODRM_REG { + 0x0: rol_Eb_Ib(); + 0x1: ror_Eb_Ib(); + 0x2: rcl_Eb_Ib(); + 0x3: rcr_Eb_Ib(); + 0x4: Inst::SAL(Eb,Ib); + 0x5: shr_Eb_Ib(); + 0x6: Inst::SAL(Eb,Ib); + 0x7: sar_Eb_Ib(); + } + //0x1: group2_Ev_Ib(); + 0x1: decode MODRM_REG { + 0x0: rol_Ev_Ib(); + 0x1: ror_Ev_Ib(); + 0x2: rcl_Ev_Ib(); + 0x3: rcr_Ev_Ib(); + 0x4: Inst::SAL(Ev,Ib); + 0x5: shr_Ev_Ib(); + 0x6: Inst::SAL(Ev,Ib); + 0x7: sar_Ev_Ib(); + } 0x2: ret_near_Iw(); 0x3: Inst::RET_NEAR(); 0x4: decode MODE_SUBMODE { diff --git a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py index 4d6e40c74..a8bad4653 100644 --- a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py +++ b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py @@ -54,6 +54,11 @@ # Authors: Gabe Black microcode = ''' +def macroop ADD_R_R +{ + add reg, reg, regm +}; + def macroop ADD_R_I { limm t1, imm @@ -77,12 +82,58 @@ def macroop ADD_P_I st t1, ds, [scale, index, base], disp }; +def macroop ADD_M_R +{ + ld t1, ds, [scale, index, base], disp + add t1, t1, reg + st t1, ds, [scale, index, base], disp +}; + +def macroop ADD_P_R +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + add t1, t1, reg + st t1, ds, [scale, index, base], disp +}; + +def macroop ADD_R_M +{ + ld t1, ds, [scale, index, base], disp + add reg, reg, t1 +}; + +def macroop ADD_R_P +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + add reg, reg, t1 +}; + +def macroop SUB_R_R +{ + sub reg, reg, regm +}; + def macroop SUB_R_I { limm t1, imm sub reg, reg, t1 }; +def macroop SUB_R_M +{ + ld t1, ds, [scale, index, base], disp + sub reg, reg, t1 +}; + +def macroop SUB_R_P +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + sub reg, reg, t1 +}; + def macroop SUB_M_I { limm t2, imm @@ -99,6 +150,21 @@ def macroop SUB_P_I sub t1, t1, t2 st t1, ds, [scale, index, base], disp }; + +def macroop SUB_M_R +{ + ld t1, ds, [scale, index, base], disp + sub t1, t1, reg + st t1, ds, [scale, index, base], disp +}; + +def macroop SUB_P_R +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + sub t1, t1, reg + st t1, ds, [scale, index, base], disp +}; ''' #let {{ # class ADC(Inst): diff --git a/src/arch/x86/isa/insts/compare_and_test/compare.py b/src/arch/x86/isa/insts/compare_and_test/compare.py index ba421a520..8f5890b23 100644 --- a/src/arch/x86/isa/insts/compare_and_test/compare.py +++ b/src/arch/x86/isa/insts/compare_and_test/compare.py @@ -54,6 +54,52 @@ # Authors: Gabe Black microcode = ''' +def macroop CMP_R_M +{ + ld t1, ds, [scale, index, base], disp + sub t0, reg, t1, flags=(OF, SF, ZF, AF, PF, CF) +}; + +def macroop CMP_R_P +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + sub t0, reg, t1, flags=(OF, SF, ZF, AF, PF, CF) +}; + +def macroop CMP_M_I +{ + limm t2, imm + ld t1, ds, [scale, index, base], disp + sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF) +}; + +def macroop CMP_P_I +{ + limm t2, imm + rdip t7 + ld t1, ds, [0, t0, t7], disp + sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF) +}; + +def macroop CMP_M_R +{ + ld t1, ds, [scale, index, base], disp + sub t0, t1, reg, flags=(OF, SF, ZF, AF, PF, CF) +}; + +def macroop CMP_P_R +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + sub t0, t1, reg, flags=(OF, SF, ZF, AF, PF, CF) +}; + +def macroop CMP_R_R +{ + sub t0, reg, regm, flags=(OF, SF, ZF, AF, PF, CF) +}; + def macroop CMP_R_I { limm t1, imm diff --git a/src/arch/x86/isa/insts/control_transfer/jump.py b/src/arch/x86/isa/insts/control_transfer/jump.py index b191730d5..3d69643ae 100644 --- a/src/arch/x86/isa/insts/control_transfer/jump.py +++ b/src/arch/x86/isa/insts/control_transfer/jump.py @@ -104,6 +104,16 @@ def macroop JNBE_I wrip t1, t2, flags=(nCCvZF,) }; +def macroop JNLE_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(nCSxOvZF,) +}; + def macroop JMP_I { # Make the default data size of jumps 64 bits in 64 bit mode diff --git a/src/arch/x86/isa/insts/logical.py b/src/arch/x86/isa/insts/logical.py index 2fd369d60..f99638cac 100644 --- a/src/arch/x86/isa/insts/logical.py +++ b/src/arch/x86/isa/insts/logical.py @@ -54,6 +54,62 @@ # Authors: Gabe Black microcode = ''' +def macroop OR_R_R +{ + or reg, reg, regm +}; + +def macroop OR_M_I +{ + limm t2, imm + ld t1, ds, [scale, index, base], disp + or t1, t1, t2 + st t1, ds, [scale, index, base], disp +}; + +def macroop OR_P_I +{ + limm t2, imm + rdip t7 + ld t1, ds, [0, t0, t7], disp + or t1, t1, t2 + st t1, ds, [0, t0, t7], disp +}; + +def macroop OR_M_R +{ + ld t1, ds, [scale, index, base], disp + or t1, t1, reg + st t1, ds, [scale, index, base], disp +}; + +def macroop OR_P_R +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + or t1, t1, reg + st t1, ds, [0, t0, t7], disp +}; + +def macroop OR_R_M +{ + ld t1, ds, [scale, index, base], disp + or reg, reg, t1 +}; + +def macroop OR_R_P +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + or reg, reg, t1 +}; + +def macroop OR_R_I +{ + limm t1, imm + or reg, reg, t1 +}; + def macroop XOR_R_R { xor reg, reg, regm @@ -65,6 +121,23 @@ def macroop XOR_R_I xor reg, reg, t1 }; +def macroop XOR_M_I +{ + limm t2, imm + ld t1, ds, [scale, index, base], disp + xor t1, t1, t2 + st t1, ds, [scale, index, base], disp +}; + +def macroop XOR_P_I +{ + limm t2, imm + rdip t7 + ld t1, ds, [scale, index, base], disp + xor t1, t1, t2 + st t1, ds, [scale, index, base], disp +}; + def macroop XOR_M_R { ld t1, ds, [scale, index, base], disp @@ -93,6 +166,24 @@ def macroop XOR_R_P xor reg, reg, t1 }; +def macroop AND_R_R +{ + and reg, reg, regm +}; + +def macroop AND_R_M +{ + ld t1, ds, [scale, index, base], disp + and reg, reg, t1 +}; + +def macroop AND_R_P +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + and reg, reg, t1 +}; + def macroop AND_R_I { limm t1, imm @@ -115,6 +206,21 @@ def macroop AND_P_I and t2, t2, t1 st t2, ds, [scale, index, base], disp }; + +def macroop AND_M_R +{ + ld t1, ds, [scale, index, base], disp + and t1, t1, reg + st t1, ds, [scale, index, base], disp +}; + +def macroop AND_P_R +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + and t1, t1, reg + st t1, ds, [scale, index, base], disp +}; ''' #let {{ #microcodeString = ''' diff --git a/src/arch/x86/isa/insts/rotate_and_shift/shift.py b/src/arch/x86/isa/insts/rotate_and_shift/shift.py index f72794657..b1c86a921 100644 --- a/src/arch/x86/isa/insts/rotate_and_shift/shift.py +++ b/src/arch/x86/isa/insts/rotate_and_shift/shift.py @@ -53,7 +53,27 @@ # # Authors: Gabe Black -microcode = "" +microcode = ''' +def macroop SAL_R_I +{ + sll reg, reg, imm +}; + +def macroop SAL_M_I +{ + ld t1, ds, [scale, index, base], disp + sll t1, t1, imm + st t1, ds, [scale, index, base], disp +}; + +def macroop SAL_P_I +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + sll t1, t1, imm + st t1, ds, [0, t0, t7], disp +}; +''' #let {{ # class SAL(Inst): # "GenFault ${new UnimpInstFault}" diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index a0e8adc9a..31ca8344d 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -389,10 +389,20 @@ let {{ defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True) defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)') defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True) - defineMicroRegOp('mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)') + defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)') defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', elseCode='DestReg=DestReg;', cc=True) + # Shift instructions + defineMicroRegOp('Sll', ''' + uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3))); + DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize); + ''') + # There are special rules for the flag for a single bit shift + defineMicroRegOp('Bll', ''' + DestReg = merge(DestReg, SrcReg1 << 1, dataSize); + ''') + # This has it's own function because Wr ops have implicit destinations def defineMicroRegOpWr(mnemonic, code, elseCode=";"): Name = mnemonic -- cgit v1.2.3 From 231cc3effb193c27ae10009444c5ee7cf2509a06 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 16:48:59 -0700 Subject: Make the decoder take advantage of the new "B" operand format which takes a register index from the opcode itself. --HG-- extra : convert_revision : 35f9be6559ee9833049eda1817982efdde7082be --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 77 +++++---------------------- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 11 +--- 2 files changed, 13 insertions(+), 75 deletions(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 80031a7fc..42404ab91 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -167,52 +167,16 @@ 0x08: decode MODE_SUBMODE { 0x0: M5InternalError::error ( {{"Tried to execute an REX prefix!"}}); - default: decode OPCODE_OP_BOTTOM3 { - 0x0: Inst::INC(rAx); - 0x1: Inst::INC(rCx); - 0x2: Inst::INC(rDx); - 0x3: Inst::INC(rBx); - 0x4: Inst::INC(rSP); - 0x5: Inst::INC(rBP); - 0x6: Inst::INC(rSI); - 0x7: Inst::INC(rDI); - } + default: Inst::INC(B); } 0x09: decode MODE_SUBMODE { 0x0: M5InternalError::error ( {{"Tried to execute an REX prefix!"}}); - default: decode OPCODE_OP_BOTTOM3 { - 0x0: Inst::DEC(rAx); - 0x1: Inst::DEC(rCX); - 0x2: Inst::DEC(rDx); - 0x3: Inst::DEC(rBx); - 0x4: Inst::DEC(rSP); - 0x5: Inst::DEC(rBP); - 0x6: Inst::DEC(rSI); - 0x7: Inst::DEC(rDI); - } + default: Inst::DEC(B); } format Inst { - 0x0A: decode OPCODE_OP_BOTTOM3 { - 0x0: PUSH(rAx); - 0x1: PUSH(rCx); - 0x2: PUSH(rDx); - 0x3: PUSH(rBx); - 0x4: PUSH(rSP); - 0x5: PUSH(rBP); - 0x6: PUSH(rSI); - 0x7: PUSH(rDI); - } - 0x0B: decode OPCODE_OP_BOTTOM3 { - 0x0: POP(rAx); - 0x1: POP(rCx); - 0x2: POP(rDx); - 0x3: POP(rBx); - 0x4: POP(rSP); - 0x5: POP(rBP); - 0x6: POP(rSI); - 0x7: POP(rDI); - } + 0x0A: PUSH(B); + 0x0B: POP(B); } 0x0C: decode OPCODE_OP_BOTTOM3 { 0x0: decode MODE_SUBMODE { @@ -284,13 +248,13 @@ } //0x1: group1_Ev_Iz(); 0x1: decode MODRM_REG { - 0x0: add_Ev_Iz(); - 0x1: or_Ev_Ibz(); + 0x0: Inst::ADD(Ev,Iz); + 0x1: Inst::OR(Ev,Iz); 0x2: adc_Ev_Iz(); 0x3: sbb_Ev_Iz(); 0x4: Inst::AND(Ev,Iz); 0x5: Inst::SUB(Ev,Iz); - 0x6: xor_Ev_Iz(); + 0x6: Inst::XOR(Ev,Iz); 0x7: Inst::CMP(Ev,Iz); } 0x2: decode MODE_SUBMODE { @@ -310,12 +274,12 @@ //0x3: group1_Ev_Ib(); 0x3: decode MODRM_REG { 0x0: Inst::ADD(Ev,Ib); - 0x1: or_Ev_Ib(); + 0x1: Inst::OR(Ev,Ib); 0x2: adc_Ev_Ib(); 0x3: sbb_Ev_Ib(); 0x4: Inst::AND(Ev,Ib); - 0x5: sub_Ev_Ib(); - 0x6: xor_Ev_Ib(); + 0x5: Inst::SUB(Ev,Ib); + 0x6: Inst::XOR(Ev,Ib); 0x7: Inst::CMP(Ev,Ib); } 0x4: Inst::TEST(Eb,Gb); @@ -335,13 +299,7 @@ } 0x12: decode OPCODE_OP_BOTTOM3 { 0x0: Inst::NOP(); //XXX repe makes this a "pause" - 0x1: xchg_rCX_rAX(); - 0x2: xchg_rDX_rAX(); - 0x3: xchg_rBX_rAX(); - 0x4: xchg_rSP_rAX(); - 0x5: xchg_rBP_rAX(); - 0x6: xchg_rSI_rAX(); - 0x7: xchg_rDI_rAX(); + default: xchg_B_rAX(); } 0x13: decode OPCODE_OP_BOTTOM3 { 0x0: cbw_or_cwde_or_cdqe_rAX(); @@ -394,18 +352,7 @@ 0x6: mov_Dh_Ib(); 0x7: mov_Bh_Ib(); } - format Inst { - 0x17: decode OPCODE_OP_BOTTOM3 { - 0x0: MOV(rAX,Iv); - 0x1: MOV(rCX,Iv); - 0x2: MOV(rDX,Iv); - 0x3: MOV(rBX,Iv); - 0x4: MOV(rSP,Iv); - 0x5: MOV(rBP,Iv); - 0x6: MOV(rSI,Iv); - 0x7: MOV(rDI,Iv); - } - } + 0x17: Inst::MOV(B,Iv); 0x18: decode OPCODE_OP_BOTTOM3 { //0x0: group2_Eb_Ib(); 0x0: decode MODRM_REG { diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 6adcf866f..a62e911e2 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -317,16 +317,7 @@ 0x6: holder(); 0x7: holder(); } - 0x19: decode OPCODE_OP_BOTTOM3 { - 0x0: bswap_rAx(); - 0x1: bswap_rCx(); - 0x2: bswap_rDx(); - 0x3: bswap_rBx(); - 0x4: bswap_rSP(); - 0x5: bswap_rBP(); - 0x6: bswap_rSI(); - 0x7: bswap_rDI(); - } + 0x19: bswap_B(); 0x1A: decode OPCODE_OP_BOTTOM3 { 0x0: holder(); 0x1: holder(); -- cgit v1.2.3 From c3669b892548ed3e1e8f4016f1e18202c5e7f484 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 17:02:39 -0700 Subject: Implement the rest of the conditional jump instructions and hook them into the decoder. --HG-- extra : convert_revision : 8d1d6abce29371def560e1c3f31dabb4de01366f --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 40 +++++----- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 40 +++++----- src/arch/x86/isa/insts/control_transfer/jump.py | 100 ++++++++++++++++++++++++ 3 files changed, 142 insertions(+), 38 deletions(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 42404ab91..d1ef8d48e 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -214,25 +214,27 @@ 0x6: outs_Dx_Xb(); 0x7: outs_Dx_Xz(); } - 0x0E: decode OPCODE_OP_BOTTOM3 { - 0x0: jo_Jb(); - 0x1: jno_Jb(); - 0x2: jb_Jb(); - 0x3: Inst::JNB(Jb); - 0x4: Inst::JZ(Jb); - 0x5: Inst::JNZ(Jb); - 0x6: Inst::JBE(Jb); - 0x7: Inst::JNBE(Jb); - } - 0x0F: decode OPCODE_OP_BOTTOM3 { - 0x0: js_Jb(); - 0x1: jns_Jb(); - 0x2: jp_Jb(); - 0x3: jnp_Jb(); - 0x4: jl_Jb(); - 0x5: jnl_Jb(); - 0x6: jle_Jb(); - 0x7: Inst::JNLE(Jb); + format Inst { + 0x0E: decode OPCODE_OP_BOTTOM3 { + 0x0: JO(Jb); + 0x1: JNO(Jb); + 0x2: JB(Jb); + 0x3: JNB(Jb); + 0x4: JZ(Jb); + 0x5: JNZ(Jb); + 0x6: JBE(Jb); + 0x7: JNBE(Jb); + } + 0x0F: decode OPCODE_OP_BOTTOM3 { + 0x0: JS(Jb); + 0x1: JNS(Jb); + 0x2: JP(Jb); + 0x3: JNP(Jb); + 0x4: JL(Jb); + 0x5: JNL(Jb); + 0x6: JLE(Jb); + 0x7: JNLE(Jb); + } } 0x10: decode OPCODE_OP_BOTTOM3 { //0x0: group1_Eb_Ib(); diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index a62e911e2..383d64e5a 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -227,25 +227,27 @@ 0x6: holder(); 0x7: holder(); } - 0x10: decode OPCODE_OP_BOTTOM3 { - 0x0: jo_Jz(); - 0x1: jno_Jz(); - 0x2: jb_Jz(); - 0x3: Inst::JNB(Jz); - 0x4: Inst::JZ(Jz); - 0x5: Inst::JNZ(Jz); - 0x6: Inst::JBE(Jz); - 0x7: Inst::JNBE(Jz); - } - 0x11: decode OPCODE_OP_BOTTOM3 { - 0x0: js_Jz(); - 0x1: jns_Jz(); - 0x2: jp_Jz(); - 0x3: jnp_Jz(); - 0x4: jl_Jz(); - 0x5: jnl_Jz(); - 0x6: jle_Jz(); - 0x7: jnle_Jz(); + format Inst { + 0x10: decode OPCODE_OP_BOTTOM3 { + 0x0: JO(Jz); + 0x1: JNO(Jz); + 0x2: JB(Jz); + 0x3: JNB(Jz); + 0x4: JZ(Jz); + 0x5: JNZ(Jz); + 0x6: JBE(Jz); + 0x7: JNBE(Jz); + } + 0x11: decode OPCODE_OP_BOTTOM3 { + 0x0: JS(Jz); + 0x1: JNS(Jz); + 0x2: JP(Jz); + 0x3: JNP(Jz); + 0x4: JL(Jz); + 0x5: JNL(Jz); + 0x6: JLE(Jz); + 0x7: JNLE(Jz); + } } 0x12: decode OPCODE_OP_BOTTOM3 { 0x0: seto_Eb(); diff --git a/src/arch/x86/isa/insts/control_transfer/jump.py b/src/arch/x86/isa/insts/control_transfer/jump.py index 3d69643ae..489eb9e39 100644 --- a/src/arch/x86/isa/insts/control_transfer/jump.py +++ b/src/arch/x86/isa/insts/control_transfer/jump.py @@ -74,6 +74,16 @@ def macroop JNZ_I wrip t1, t2, flags=(nCZF,) }; +def macroop JB_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(CCF,) +}; + def macroop JNB_I { # Make the default data size of jumps 64 bits in 64 bit mode @@ -104,6 +114,76 @@ def macroop JNBE_I wrip t1, t2, flags=(nCCvZF,) }; +def macroop JS_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(CSF,) +}; + +def macroop JNS_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(nCSF,) +}; + +def macroop JP_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(CPF,) +}; + +def macroop JNP_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(nCPF,) +}; + +def macroop JL_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(CSxOF,) +}; + +def macroop JNL_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(nCSxOF,) +}; + +def macroop JLE_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(CSxOvZF,) +}; + def macroop JNLE_I { # Make the default data size of jumps 64 bits in 64 bit mode @@ -114,6 +194,26 @@ def macroop JNLE_I wrip t1, t2, flags=(nCSxOvZF,) }; +def macroop JO_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(COF,) +}; + +def macroop JNO_I +{ + # Make the default data size of jumps 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t1 + limm t2, imm + wrip t1, t2, flags=(nCOF,) +}; + def macroop JMP_I { # Make the default data size of jumps 64 bits in 64 bit mode -- cgit v1.2.3 From 9093cb79a1a96867cae677f529a0d4bb19b288af Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 17:17:11 -0700 Subject: Implement adc and sbb instructions and microops. --HG-- extra : convert_revision : a2d3068c5b487f4fa7bf5c9cebba7753bc390bfa --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 114 ++++++++++----------- .../x86/isa/insts/arithmetic/add_and_subtract.py | 112 ++++++++++++++++++++ src/arch/x86/isa/microops/regop.isa | 12 ++- 3 files changed, 177 insertions(+), 61 deletions(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index d1ef8d48e..11d8425ce 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -88,12 +88,6 @@ [rAl,Ib], [rAx,Iz]); } 0x02: decode OPCODE_OP_BOTTOM3 { - 0x0: adc_Eb_Gb(); - 0x1: adc_Ev_Gv(); - 0x2: adc_Gb_Eb(); - 0x3: adc_Gv_Ev(); - 0x4: adc_Al_Ib(); - 0x5: adc_rAX_Iz(); 0x6: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); default: push_SS(); @@ -102,14 +96,12 @@ 0x0: This_should_be_an_illegal_instruction(); default: pop_SS(); } + default: MultiInst::ADC(OPCODE_OP_BOTTOM3, + [Eb,Gb], [Ev,Gv], + [Gb,Eb], [Gv,Ev], + [rAl,Ib], [rAx,Iz]); } 0x03: decode OPCODE_OP_BOTTOM3 { - 0x0: sbb_Eb_Gb(); - 0x1: sbb_Ev_Gv(); - 0x2: sbb_Gb_Eb(); - 0x3: sbb_Gv_Ev(); - 0x4: sbb_Al_Ib(); - 0x5: sbb_rAX_Iz(); 0x6: decode MODE_SUBMODE { 0x0: This_should_be_an_illegal_instruction(); default: push_DS(); @@ -118,6 +110,10 @@ 0x0: This_should_be_an_illegal_instruction(); default: pop_DS(); } + default: MultiInst::SBB(OPCODE_OP_BOTTOM3, + [Eb,Gb], [Ev,Gv], + [Gb,Eb], [Gv,Ev], + [rAl,Ib], [rAx,Iz]); } 0x04: decode OPCODE_OP_BOTTOM3 { 0x6: M5InternalError::error( @@ -237,52 +233,54 @@ } } 0x10: decode OPCODE_OP_BOTTOM3 { - //0x0: group1_Eb_Ib(); - 0x0: decode MODRM_REG { - 0x0: Inst::ADD(Eb,Ib); - 0x1: Inst::OR(Eb,Ib); - 0x2: adc_Eb_Ib(); - 0x3: sbb_Eb_Ib(); - 0x4: Inst::AND(Eb,Ib); - 0x5: Inst::SUB(Eb,Ib); - 0x6: Inst::XOR(Eb,Ib); - 0x7: Inst::CMP(Eb,Ib); - } - //0x1: group1_Ev_Iz(); - 0x1: decode MODRM_REG { - 0x0: Inst::ADD(Ev,Iz); - 0x1: Inst::OR(Ev,Iz); - 0x2: adc_Ev_Iz(); - 0x3: sbb_Ev_Iz(); - 0x4: Inst::AND(Ev,Iz); - 0x5: Inst::SUB(Ev,Iz); - 0x6: Inst::XOR(Ev,Iz); - 0x7: Inst::CMP(Ev,Iz); - } - 0x2: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); - //default: group1_Eb_Ib(); - default: decode MODRM_REG { - 0x0: Inst::ADD(Eb,Ib); - 0x1: Inst::OR(Eb,Ib); - 0x2: adc_Eb_Ib(); - 0x3: sbb_Eb_Ib(); - 0x4: Inst::AND(Eb,Ib); - 0x5: Inst::SUB(Eb,Ib); - 0x6: Inst::XOR(Eb,Ib); - 0x7: Inst::CMP(Eb,Ib); + format Inst { + //0x0: group1_Eb_Ib(); + 0x0: decode MODRM_REG { + 0x0: ADD(Eb,Ib); + 0x1: OR(Eb,Ib); + 0x2: ADC(Eb,Ib); + 0x3: SBB(Eb,Ib); + 0x4: AND(Eb,Ib); + 0x5: SUB(Eb,Ib); + 0x6: XOR(Eb,Ib); + 0x7: CMP(Eb,Ib); + } + //0x1: group1_Ev_Iz(); + 0x1: decode MODRM_REG { + 0x0: ADD(Ev,Iz); + 0x1: OR(Ev,Iz); + 0x2: ADC(Ev,Iz); + 0x3: SBB(Ev,Iz); + 0x4: AND(Ev,Iz); + 0x5: SUB(Ev,Iz); + 0x6: XOR(Ev,Iz); + 0x7: CMP(Ev,Iz); + } + 0x2: decode MODE_SUBMODE { + 0x0: WarnUnimpl::This_should_be_an_illegal_instruction(); + //default: group1_Eb_Ib(); + default: decode MODRM_REG { + 0x0: ADD(Eb,Ib); + 0x1: OR(Eb,Ib); + 0x2: ADC(Eb,Ib); + 0x3: SBB(Eb,Ib); + 0x4: AND(Eb,Ib); + 0x5: SUB(Eb,Ib); + 0x6: XOR(Eb,Ib); + 0x7: CMP(Eb,Ib); + } + } + //0x3: group1_Ev_Ib(); + 0x3: decode MODRM_REG { + 0x0: ADD(Ev,Ib); + 0x1: OR(Ev,Ib); + 0x2: ADC(Ev,Ib); + 0x3: SBB(Ev,Ib); + 0x4: AND(Ev,Ib); + 0x5: SUB(Ev,Ib); + 0x6: XOR(Ev,Ib); + 0x7: CMP(Ev,Ib); } - } - //0x3: group1_Ev_Ib(); - 0x3: decode MODRM_REG { - 0x0: Inst::ADD(Ev,Ib); - 0x1: Inst::OR(Ev,Ib); - 0x2: adc_Ev_Ib(); - 0x3: sbb_Ev_Ib(); - 0x4: Inst::AND(Ev,Ib); - 0x5: Inst::SUB(Ev,Ib); - 0x6: Inst::XOR(Ev,Ib); - 0x7: Inst::CMP(Ev,Ib); } 0x4: Inst::TEST(Eb,Gb); 0x5: Inst::TEST(Ev,Gv); @@ -492,7 +490,7 @@ 0x4: jmp_Ev(); 0x5: jmp_Mp(); 0x6: push_Ev(); - 0x7: This_should_be_an_illegal_instruction(); + 0x7: WarnUnimpl::This_should_be_an_illegal_instruction(); } } } diff --git a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py index a8bad4653..05aa6cd69 100644 --- a/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py +++ b/src/arch/x86/isa/insts/arithmetic/add_and_subtract.py @@ -165,6 +165,118 @@ def macroop SUB_P_R sub t1, t1, reg st t1, ds, [scale, index, base], disp }; + +def macroop ADC_R_R +{ + adc reg, reg, regm +}; + +def macroop ADC_R_I +{ + limm t1, imm + adc reg, reg, t1 +}; + +def macroop ADC_M_I +{ + limm t2, imm + ld t1, ds, [scale, index, base], disp + adc t1, t1, t2 + st t1, ds, [scale, index, base], disp +}; + +def macroop ADC_P_I +{ + rdip t7 + limm t2, imm + ld t1, ds, [scale, index, base], disp + adc t1, t1, t2 + st t1, ds, [scale, index, base], disp +}; + +def macroop ADC_M_R +{ + ld t1, ds, [scale, index, base], disp + adc t1, t1, reg + st t1, ds, [scale, index, base], disp +}; + +def macroop ADC_P_R +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + adc t1, t1, reg + st t1, ds, [scale, index, base], disp +}; + +def macroop ADC_R_M +{ + ld t1, ds, [scale, index, base], disp + adc reg, reg, t1 +}; + +def macroop ADC_R_P +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + adc reg, reg, t1 +}; + +def macroop SBB_R_R +{ + sbb reg, reg, regm +}; + +def macroop SBB_R_I +{ + limm t1, imm + sbb reg, reg, t1 +}; + +def macroop SBB_R_M +{ + ld t1, ds, [scale, index, base], disp + sbb reg, reg, t1 +}; + +def macroop SBB_R_P +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + sbb reg, reg, t1 +}; + +def macroop SBB_M_I +{ + limm t2, imm + ld t1, ds, [scale, index, base], disp + sbb t1, t1, t2 + st t1, ds, [scale, index, base], disp +}; + +def macroop SBB_P_I +{ + rdip t7 + limm t2, imm + ld t1, ds, [scale, index, base], disp + sbb t1, t1, t2 + st t1, ds, [scale, index, base], disp +}; + +def macroop SBB_M_R +{ + ld t1, ds, [scale, index, base], disp + sbb t1, t1, reg + st t1, ds, [scale, index, base], disp +}; + +def macroop SBB_P_R +{ + rdip t7 + ld t1, ds, [scale, index, base], disp + sbb t1, t1, reg + st t1, ds, [scale, index, base], disp +}; ''' #let {{ # class ADC(Inst): diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 31ca8344d..d2002b4fb 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -383,12 +383,18 @@ let {{ defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)') - defineMicroRegOp('Adc', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') - defineMicroRegOp('Sbb', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True) + defineMicroRegOp('Adc', ''' + CCFlagBits flags = ccFlagBits; + DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize); + ''') + defineMicroRegOp('Sbb', ''' + CCFlagBits flags = ccFlagBits; + DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize); + ''', True) defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)') defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True) defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)') - defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True) + # defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True) defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)') defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', elseCode='DestReg=DestReg;', cc=True) -- cgit v1.2.3 From 8dd93f32e42f3823837b705ef0a405c55a95c2ad Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 18:24:46 -0700 Subject: Make the "name" function const. --HG-- extra : convert_revision : eb71bc3edd92a544a5333786635fce550aaef233 --- src/arch/x86/faults.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index 8c9afcdb5..51c34cebd 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -66,7 +66,7 @@ namespace X86ISA class X86Fault : public FaultBase { protected: - const char * name() + const char * name() const { return "generic_x86_fault"; } @@ -80,7 +80,7 @@ namespace X86ISA class UnimpInstFault : public FaultBase { public: - const char * name() + const char * name() const { return "unimplemented_micro"; } -- cgit v1.2.3 From 75f6c6a0166c87fd0ac795197355248e6e565ddd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 18:27:02 -0700 Subject: Implement UD2 and replace the place holder in the decoder. --HG-- extra : convert_revision : 16d0d2b2ddad8759698fa4aa668c22063307c72b --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 65 ++++++++++++---------- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 8 +-- src/arch/x86/isa/insts/__init__.py | 3 +- src/arch/x86/isa/insts/system/__init__.py | 62 +++++++++++++++++++++ .../x86/isa/insts/system/undefined_operation.py | 61 ++++++++++++++++++++ 5 files changed, 164 insertions(+), 35 deletions(-) create mode 100644 src/arch/x86/isa/insts/system/__init__.py create mode 100644 src/arch/x86/isa/insts/system/undefined_operation.py diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 11d8425ce..2c2d68785 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -62,11 +62,11 @@ format WarnUnimpl { 0x00: decode OPCODE_OP_BOTTOM3 { 0x6: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: push_ES(); } 0x7: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: pop_ES(); } default: MultiInst::ADD(OPCODE_OP_BOTTOM3, @@ -76,7 +76,7 @@ } 0x01: decode OPCODE_OP_BOTTOM3 { 0x6: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: push_CS(); } //Any time this is seen, it should generate a two byte opcode @@ -89,11 +89,11 @@ } 0x02: decode OPCODE_OP_BOTTOM3 { 0x6: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: push_SS(); } 0x7: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: pop_SS(); } default: MultiInst::ADC(OPCODE_OP_BOTTOM3, @@ -103,11 +103,11 @@ } 0x03: decode OPCODE_OP_BOTTOM3 { 0x6: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: push_DS(); } 0x7: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: pop_DS(); } default: MultiInst::SBB(OPCODE_OP_BOTTOM3, @@ -119,7 +119,7 @@ 0x6: M5InternalError::error( {{"Tried to execute the ES segment override prefix!"}}); 0x7: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: daa(); } default: MultiInst::AND(OPCODE_OP_BOTTOM3, @@ -140,7 +140,7 @@ 0x6: M5InternalError::error( {{"Tried to execute the SS segment override prefix!"}}); 0x7: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: aaa(); } default: MultiInst::XOR(OPCODE_OP_BOTTOM3, @@ -152,7 +152,7 @@ 0x6: M5InternalError::error( {{"Tried to execute the DS segment override prefix!"}}); 0x7: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: aas(); } default: MultiInst::CMP(OPCODE_OP_BOTTOM3, @@ -176,15 +176,15 @@ } 0x0C: decode OPCODE_OP_BOTTOM3 { 0x0: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: pusha(); } 0x1: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: popa(); } 0x2: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: bound_Gv_Ma(); } 0x3: decode MODE_SUBMODE { @@ -257,7 +257,7 @@ 0x7: CMP(Ev,Iz); } 0x2: decode MODE_SUBMODE { - 0x0: WarnUnimpl::This_should_be_an_illegal_instruction(); + 0x0: UD2(); //default: group1_Eb_Ib(); default: decode MODRM_REG { 0x0: ADD(Eb,Ib); @@ -281,9 +281,9 @@ 0x6: XOR(Ev,Ib); 0x7: CMP(Ev,Ib); } + 0x4: Inst::TEST(Eb,Gb); + 0x5: Inst::TEST(Ev,Gv); } - 0x4: Inst::TEST(Eb,Gb); - 0x5: Inst::TEST(Ev,Gv); 0x6: xchg_Eb_Gb(); 0x7: xchg_Ev_Gv(); } @@ -305,7 +305,7 @@ 0x0: cbw_or_cwde_or_cdqe_rAX(); 0x1: cwd_or_cdq_or_cqo_rAX_rDX(); 0x2: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: call_Ap(); } 0x3: fwait(); //aka wait @@ -314,11 +314,11 @@ //Both of these should be illegal only if CPUID.AHF64=0, //according to sandpile.org 0x6: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: sahf(); } 0x7: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: lahf(); } } @@ -379,11 +379,11 @@ 0x2: ret_near_Iw(); 0x3: Inst::RET_NEAR(); 0x4: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: les_Gz_Mp(); } 0x5: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: lds_Gz_Mp(); } //0x6: group12_Eb_Ib(); @@ -403,7 +403,7 @@ 0x4: int3(); 0x5: int_Ib(); 0x6: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: into(); } 0x7: iret(); @@ -414,15 +414,15 @@ 0x2: group2_Eb_Cl(); 0x3: group2_Ev_Cl(); 0x4: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: aam_Ib(); } 0x5: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: aad_Ib(); } 0x6: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: salc(); } 0x7: xlat(); @@ -449,9 +449,9 @@ } 0x1D: decode OPCODE_OP_BOTTOM3 { 0x0: Inst::CALL_NEAR(Jz); - 0x1: jmp_Jz(); + 0x1: Inst::JMP(Jz); 0x2: decode MODE_SUBMODE { - 0x0: This_should_be_an_illegal_instruction(); + 0x0: Inst::UD2(); default: jmp_Ap(); } 0x3: Inst::JMP(Jb); @@ -480,17 +480,22 @@ 0x3: sti(); 0x4: cld(); 0x5: std(); - 0x6: group4(); + //0x6: group4(); + 0x6: decode MODRM_REG { + 0x0: Inst::INC(Eb); + 0x1: Inst::DEC(Eb); + default: Inst::UD2(); + } //0x7: group5(); 0x7: decode MODRM_REG { 0x0: Inst::INC(Ev); - 0x1: dev_Ev(); + 0x1: Inst::DEC(Ev); 0x2: call_Ev(); 0x3: call_Mp(); 0x4: jmp_Ev(); 0x5: jmp_Mp(); 0x6: push_Ev(); - 0x7: WarnUnimpl::This_should_be_an_illegal_instruction(); + 0x7: Inst::UD2(); } } } diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 383d64e5a..e5631d37b 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -80,9 +80,9 @@ 0x01: decode OPCODE_OP_BOTTOM3 { 0x0: invd(); 0x1: wbinvd(); - 0x2: This_should_be_an_illegal_instruction(); - 0x3: UD1(); - 0x4: This_should_be_an_illegal_instruction(); + 0x2: Inst::UD2(); + 0x3: UD2(); + 0x4: Inst::UD2(); 0x5: threednow(); 0x6: threednow(); 0x7: threednow(); @@ -134,7 +134,7 @@ 0x3: rdpmc(); 0x4: sysenter(); 0x5: sysexit(); - 0x6: This_should_be_an_illegal_instruction(); + 0x6: Inst::UD2(); 0x7: getsec(); } 0x07: decode OPCODE_OP_BOTTOM3 { diff --git a/src/arch/x86/isa/insts/__init__.py b/src/arch/x86/isa/insts/__init__.py index 717690926..f5c4e3113 100644 --- a/src/arch/x86/isa/insts/__init__.py +++ b/src/arch/x86/isa/insts/__init__.py @@ -69,7 +69,8 @@ categories = ["arithmetic", "rotate_and_shift", "semaphores", "string", - "system_calls"] + "system_calls", + "system"] microcode = ''' # X86 microcode diff --git a/src/arch/x86/isa/insts/system/__init__.py b/src/arch/x86/isa/insts/system/__init__.py new file mode 100644 index 000000000..72e3bdf0a --- /dev/null +++ b/src/arch/x86/isa/insts/system/__init__.py @@ -0,0 +1,62 @@ +# 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 + +categories = ["undefined_operation"] + +microcode = "" +for category in categories: + exec "import %s as cat" % category + microcode += cat.microcode + diff --git a/src/arch/x86/isa/insts/system/undefined_operation.py b/src/arch/x86/isa/insts/system/undefined_operation.py new file mode 100644 index 000000000..e5544b6e7 --- /dev/null +++ b/src/arch/x86/isa/insts/system/undefined_operation.py @@ -0,0 +1,61 @@ +# 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 + +microcode = ''' +def macroop UD2 +{ + fault "new X86Fault" +}; +''' -- cgit v1.2.3 From 009df5ff1e19276433975fddd43a306ff653a20e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 23:12:26 -0700 Subject: Fixed line number accounting --HG-- extra : convert_revision : 4c046493b98ce4a766c2121710d70650cb6a801e --- src/arch/isa_parser.py | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index 754a64fdb..64a120c4c 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -134,7 +134,7 @@ def t_INTLIT(t): try: t.value = int(t.value,0) except ValueError: - error(t.lineno, 'Integer value "%s" too large' % t.value) + error(t.lexer.lineno, 'Integer value "%s" too large' % t.value) t.value = 0 return t @@ -144,7 +144,7 @@ def t_STRLIT(t): r"(?m)'([^'])+'" # strip off quotes t.value = t.value[1:-1] - t.lineno += t.value.count('\n') + t.lexer.lineno += t.value.count('\n') return t @@ -154,22 +154,22 @@ def t_CODELIT(t): r"(?m)\{\{([^\}]|}(?!\}))+\}\}" # strip off {{ & }} t.value = t.value[2:-2] - t.lineno += t.value.count('\n') + t.lexer.lineno += t.value.count('\n') return t def t_CPPDIRECTIVE(t): r'^\#[^\#].*\n' - t.lineno += t.value.count('\n') + t.lexer.lineno += t.value.count('\n') return t def t_NEWFILE(t): r'^\#\#newfile\s+"[\w/.-]*"' - fileNameStack.push((t.value[11:-1], t.lineno)) - t.lineno = 0 + fileNameStack.push((t.value[11:-1], t.lexer.lineno)) + t.lexer.lineno = 0 def t_ENDFILE(t): r'^\#\#endfile' - (old_filename, t.lineno) = fileNameStack.pop() + (old_filename, t.lexer.lineno) = fileNameStack.pop() # # The functions t_NEWLINE, t_ignore, and t_error are @@ -179,7 +179,7 @@ def t_ENDFILE(t): # Newlines def t_NEWLINE(t): r'\n+' - t.lineno += t.value.count('\n') + t.lexer.lineno += t.value.count('\n') # Comments def t_comment(t): @@ -190,7 +190,7 @@ t_ignore = ' \t\x0c' # Error handler def t_error(t): - error(t.lineno, "illegal character '%s'" % t.value[0]) + error(t.lexer.lineno, "illegal character '%s'" % t.value[0]) t.skip(1) # Build the lexer @@ -318,7 +318,7 @@ def p_global_let(t): try: exec fixPythonIndentation(t[2]) in exportContext except Exception, exc: - error(t.lineno(1), + error(t.lexer.lineno, 'error: %s in global let block "%s".' % (exc, t[2])) t[0] = GenCode(header_output = exportContext["header_output"], decoder_output = exportContext["decoder_output"], @@ -332,9 +332,9 @@ def p_def_operand_types(t): try: userDict = eval('{' + t[3] + '}') except Exception, exc: - error(t.lineno(1), + error(t.lexer.lineno, 'error: %s in def operand_types block "%s".' % (exc, t[3])) - buildOperandTypeMap(userDict, t.lineno(1)) + buildOperandTypeMap(userDict, t.lexer.lineno) t[0] = GenCode() # contributes nothing to the output C++ file # Define the mapping from operand names to operand classes and other @@ -342,14 +342,14 @@ def p_def_operand_types(t): def p_def_operands(t): 'def_operands : DEF OPERANDS CODELIT SEMI' if not globals().has_key('operandTypeMap'): - error(t.lineno(1), + error(t.lexer.lineno, 'error: operand types must be defined before operands') try: userDict = eval('{' + t[3] + '}') except Exception, exc: - error(t.lineno(1), + error(t.lexer.lineno, 'error: %s in def operands block "%s".' % (exc, t[3])) - buildOperandNameMap(userDict, t.lineno(1)) + buildOperandNameMap(userDict, t.lexer.lineno) t[0] = GenCode() # contributes nothing to the output C++ file # A bitfield definition looks like: @@ -376,7 +376,7 @@ def p_def_bitfield_1(t): def p_def_bitfield_struct(t): 'def_bitfield_struct : DEF opt_signed BITFIELD ID id_with_dot SEMI' if (t[2] != ''): - error(t.lineno(1), 'error: structure bitfields are always unsigned.') + error(t.lexer.lineno, 'error: structure bitfields are always unsigned.') expr = 'machInst.%s' % t[5] hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) t[0] = GenCode(header_output = hash_define) @@ -410,7 +410,7 @@ def p_def_template(t): def p_def_format(t): 'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI' (id, params, code) = (t[3], t[5], t[7]) - defFormat(id, params, code, t.lineno(1)) + defFormat(id, params, code, t.lexer.lineno) t[0] = GenCode() # The formal parameter list for an instruction format is a possibly @@ -520,7 +520,7 @@ def p_decode_stmt_list_0(t): def p_decode_stmt_list_1(t): 'decode_stmt_list : decode_stmt decode_stmt_list' if (t[1].has_decode_default and t[2].has_decode_default): - error(t.lineno(1), 'Two default cases in decode block') + error(t.lexer.lineno, 'Two default cases in decode block') t[0] = t[1] + t[2] # @@ -565,7 +565,7 @@ def p_push_format_id(t): formatStack.push(formatMap[t[1]]) t[0] = ('', '// format %s' % t[1]) except KeyError: - error(t.lineno(1), 'instruction format "%s" not defined.' % t[1]) + error(t.lexer.lineno, 'instruction format "%s" not defined.' % t[1]) # Nested decode block: if the value of the current field matches the # specified constant, do a nested decode on some other field. @@ -617,7 +617,7 @@ def p_inst_0(t): 'inst : ID LPAREN arg_list RPAREN' # Pass the ID and arg list to the current format class to deal with. currentFormat = formatStack.top() - codeObj = currentFormat.defineInst(t[1], t[3], t.lineno(1)) + codeObj = currentFormat.defineInst(t[1], t[3], t.lexer.lineno) args = ','.join(map(str, t[3])) args = re.sub('(?m)^', '//', args) args = re.sub('^//', '', args) @@ -632,8 +632,8 @@ def p_inst_1(t): try: format = formatMap[t[1]] except KeyError: - error(t.lineno(1), 'instruction format "%s" not defined.' % t[1]) - codeObj = format.defineInst(t[3], t[5], t.lineno(1)) + error(t.lexer.lineno, 'instruction format "%s" not defined.' % t[1]) + codeObj = format.defineInst(t[3], t[5], t.lexer.lineno) comment = '\n// %s::%s(%s)\n' % (t[1], t[3], t[5]) codeObj.prepend_all(comment) t[0] = codeObj @@ -722,7 +722,7 @@ def p_empty(t): # *token*, not a grammar symbol (hence the need to use t.value) def p_error(t): if t: - error(t.lineno, "syntax error at '%s'" % t.value) + error(t.lexer.lineno, "syntax error at '%s'" % t.value) else: error(0, "unknown syntax error", True) -- cgit v1.2.3 From fc1b7d62b7e8e5cf59956875720dbd1deb68af93 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 20 Jul 2007 23:16:03 -0700 Subject: Fixed the distinction between far and near versions of jmp, call and ret. Implemented some shifts, rotates, and pushes. --HG-- extra : convert_revision : fcb06189ff213e82da16ac43231feb308cb3a285 --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 54 ++++++----- src/arch/x86/isa/insts/control_transfer/call.py | 39 +++++++- src/arch/x86/isa/insts/control_transfer/jump.py | 6 ++ .../isa/insts/data_transfer/stack_operations.py | 19 ++++ src/arch/x86/isa/insts/rotate_and_shift/rotate.py | 46 ++++++++- src/arch/x86/isa/insts/rotate_and_shift/shift.py | 40 ++++++++ src/arch/x86/isa/microops/regop.isa | 106 ++++++++++++++------- 7 files changed, 245 insertions(+), 65 deletions(-) diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 2c2d68785..329a03f40 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -306,7 +306,7 @@ 0x1: cwd_or_cdq_or_cqo_rAX_rDX(); 0x2: decode MODE_SUBMODE { 0x0: Inst::UD2(); - default: call_Ap(); + default: call_far_Ap(); } 0x3: fwait(); //aka wait 0x4: pushf_Fv(); @@ -356,25 +356,25 @@ 0x18: decode OPCODE_OP_BOTTOM3 { //0x0: group2_Eb_Ib(); 0x0: decode MODRM_REG { - 0x0: rol_Eb_Ib(); - 0x1: ror_Eb_Ib(); + 0x0: Inst::ROL(Eb,Ib); + 0x1: Inst::ROR(Eb,Ib); 0x2: rcl_Eb_Ib(); 0x3: rcr_Eb_Ib(); 0x4: Inst::SAL(Eb,Ib); - 0x5: shr_Eb_Ib(); + 0x5: Inst::SHR(Eb,Ib); 0x6: Inst::SAL(Eb,Ib); - 0x7: sar_Eb_Ib(); + 0x7: Inst::SAR(Eb,Ib); } //0x1: group2_Ev_Ib(); 0x1: decode MODRM_REG { - 0x0: rol_Ev_Ib(); - 0x1: ror_Ev_Ib(); + 0x0: Inst::ROL(Ev,Ib); + 0x1: Inst::ROR(Ev,Ib); 0x2: rcl_Ev_Ib(); 0x3: rcr_Ev_Ib(); 0x4: Inst::SAL(Ev,Ib); - 0x5: shr_Ev_Ib(); + 0x5: Inst::SHR(Ev,Ib); 0x6: Inst::SAL(Ev,Ib); - 0x7: sar_Ev_Ib(); + 0x7: Inst::SAR(Ev,Ib); } 0x2: ret_near_Iw(); 0x3: Inst::RET_NEAR(); @@ -452,7 +452,7 @@ 0x1: Inst::JMP(Jz); 0x2: decode MODE_SUBMODE { 0x0: Inst::UD2(); - default: jmp_Ap(); + default: jmp_far_Ap(); } 0x3: Inst::JMP(Jb); 0x4: in_Al_Dx(); @@ -480,22 +480,24 @@ 0x3: sti(); 0x4: cld(); 0x5: std(); - //0x6: group4(); - 0x6: decode MODRM_REG { - 0x0: Inst::INC(Eb); - 0x1: Inst::DEC(Eb); - default: Inst::UD2(); - } - //0x7: group5(); - 0x7: decode MODRM_REG { - 0x0: Inst::INC(Ev); - 0x1: Inst::DEC(Ev); - 0x2: call_Ev(); - 0x3: call_Mp(); - 0x4: jmp_Ev(); - 0x5: jmp_Mp(); - 0x6: push_Ev(); - 0x7: Inst::UD2(); + format Inst { + //0x6: group4(); + 0x6: decode MODRM_REG { + 0x0: INC(Eb); + 0x1: DEC(Eb); + default: UD2(); + } + //0x7: group5(); + 0x7: decode MODRM_REG { + 0x0: INC(Ev); + 0x1: DEC(Ev); + 0x2: CALL_NEAR(Ev); + 0x3: WarnUnimpl::call_far_Mp(); + 0x4: JMP(Ev); + 0x5: WarnUnimpl::jmp_far_Mp(); + 0x6: PUSH(Ev); + 0x7: UD2(); + } } } } diff --git a/src/arch/x86/isa/insts/control_transfer/call.py b/src/arch/x86/isa/insts/control_transfer/call.py index c40080d85..c5bb66e58 100644 --- a/src/arch/x86/isa/insts/control_transfer/call.py +++ b/src/arch/x86/isa/insts/control_transfer/call.py @@ -59,11 +59,46 @@ def macroop CALL_NEAR_I # Make the default data size of calls 64 bits in 64 bit mode .adjust_env oszIn64Override - limm t2, imm + limm t1, imm + rdip t7 + subi rsp, rsp, dsz + st t7, ss, [0, t0, rsp] + wrip t7, t1 +}; + +def macroop CALL_NEAR_R +{ + # Make the default data size of calls 64 bits in 64 bit mode + .adjust_env oszIn64Override + rdip t1 subi rsp, rsp, dsz st t1, ss, [0, t0, rsp] - wrip t1, t2 + wripi reg, 0 +}; + +def macroop CALL_NEAR_M +{ + # Make the default data size of calls 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t7 + ld t1, ds, [scale, index, base], disp + subi rsp, rsp, dsz + st t7, ss, [0, t0, rsp] + wripi t1, 0 +}; + +def macroop CALL_NEAR_P +{ + # Make the default data size of calls 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t7 + ld t1, ds, [0, t0, t7], disp + subi rsp, rsp, dsz + st t7, ss, [0, t0, rsp] + wripi t1, 0 }; ''' #let {{ diff --git a/src/arch/x86/isa/insts/control_transfer/jump.py b/src/arch/x86/isa/insts/control_transfer/jump.py index 489eb9e39..158861a3d 100644 --- a/src/arch/x86/isa/insts/control_transfer/jump.py +++ b/src/arch/x86/isa/insts/control_transfer/jump.py @@ -235,4 +235,10 @@ def macroop JMP_M wripi t1, 0 }; +def macroop JMP_P +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + wripi t1, 0 +}; ''' diff --git a/src/arch/x86/isa/insts/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/data_transfer/stack_operations.py index 585437b8c..c381dc4f4 100644 --- a/src/arch/x86/isa/insts/data_transfer/stack_operations.py +++ b/src/arch/x86/isa/insts/data_transfer/stack_operations.py @@ -69,6 +69,25 @@ def macroop PUSH_R { subi rsp, rsp, dsz st reg, ss, [0, t0, rsp] }; + +def macroop PUSH_M { + # Make the default data size of pops 64 bits in 64 bit mode + .adjust_env oszIn64Override + + ld t1, ds, [scale, index, base], disp + subi rsp, rsp, dsz + st t1, ss, [0, t0, rsp] +}; + +def macroop PUSH_P { + # Make the default data size of pops 64 bits in 64 bit mode + .adjust_env oszIn64Override + + rdip t7 + ld t1, ds, [0, t0, t7], disp + subi rsp, rsp, dsz + st t1, ss, [0, t0, rsp] +}; ''' #let {{ # class POPA(Inst): diff --git a/src/arch/x86/isa/insts/rotate_and_shift/rotate.py b/src/arch/x86/isa/insts/rotate_and_shift/rotate.py index e3aaf0043..5330b1ac5 100644 --- a/src/arch/x86/isa/insts/rotate_and_shift/rotate.py +++ b/src/arch/x86/isa/insts/rotate_and_shift/rotate.py @@ -53,14 +53,50 @@ # # Authors: Gabe Black -microcode = "" +microcode = ''' +def macroop ROL_R_I +{ + rol reg, reg, imm +}; + +def macroop ROL_M_I +{ + ld t1, ds, [scale, index, base], disp + rol t1, t1, imm + st t1, ds, [scale, index, base], disp +}; + +def macroop ROL_P_I +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + rol t1, t1, imm + st t1, ds, [0, t0, t7], disp +}; + +def macroop ROR_R_I +{ + ror reg, reg, imm +}; + +def macroop ROR_M_I +{ + ld t1, ds, [scale, index, base], disp + ror t1, t1, imm + st t1, ds, [scale, index, base], disp +}; + +def macroop ROR_P_I +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + ror t1, t1, imm + st t1, ds, [0, t0, t7], disp +}; +''' #let {{ # class RCL(Inst): # "GenFault ${new UnimpInstFault}" # class RCR(Inst): # "GenFault ${new UnimpInstFault}" -# class ROL(Inst): -# "GenFault ${new UnimpInstFault}" -# class ROR(Inst): -# "GenFault ${new UnimpInstFault}" #}}; diff --git a/src/arch/x86/isa/insts/rotate_and_shift/shift.py b/src/arch/x86/isa/insts/rotate_and_shift/shift.py index b1c86a921..5a04317d9 100644 --- a/src/arch/x86/isa/insts/rotate_and_shift/shift.py +++ b/src/arch/x86/isa/insts/rotate_and_shift/shift.py @@ -73,6 +73,46 @@ def macroop SAL_P_I sll t1, t1, imm st t1, ds, [0, t0, t7], disp }; + +def macroop SHR_R_I +{ + srl reg, reg, imm +}; + +def macroop SHR_M_I +{ + ld t1, ds, [scale, index, base], disp + srl t1, t1, imm + st t1, ds, [scale, index, base], disp +}; + +def macroop SHR_P_I +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + srl t1, t1, imm + st t1, ds, [0, t0, t7], disp +}; + +def macroop SAR_R_I +{ + sra reg, reg, imm +}; + +def macroop SAR_M_I +{ + ld t1, ds, [scale, index, base], disp + sra t1, t1, imm + st t1, ds, [scale, index, base], disp +}; + +def macroop SAR_P_I +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + sra t1, t1, imm + st t1, ds, [0, t0, t7], disp +}; ''' #let {{ # class SAL(Inst): diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index d2002b4fb..1f4de5642 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -381,34 +381,6 @@ let {{ setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode, flagCode = immFlagCode, condCheck = condCode, elseCode = elseCode); - defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') - defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)') - defineMicroRegOp('Adc', ''' - CCFlagBits flags = ccFlagBits; - DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize); - ''') - defineMicroRegOp('Sbb', ''' - CCFlagBits flags = ccFlagBits; - DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize); - ''', True) - defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)') - defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True) - defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)') - # defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True) - defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)') - defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', - elseCode='DestReg=DestReg;', cc=True) - - # Shift instructions - defineMicroRegOp('Sll', ''' - uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3))); - DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize); - ''') - # There are special rules for the flag for a single bit shift - defineMicroRegOp('Bll', ''' - DestReg = merge(DestReg, SrcReg1 << 1, dataSize); - ''') - # This has it's own function because Wr ops have implicit destinations def defineMicroRegOpWr(mnemonic, code, elseCode=";"): Name = mnemonic @@ -445,8 +417,6 @@ let {{ setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode, condCheck = checkCCFlagBits, elseCode = elseCode); - defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;") - # This has it's own function because Rd ops don't always have two parameters def defineMicroRegOpRd(mnemonic, code): Name = mnemonic @@ -462,8 +432,6 @@ let {{ setUpMicroRegOp(name, Name, "X86ISA::RegOp", code); - defineMicroRegOpRd('Rdip', 'DestReg = RIP') - def defineMicroRegOpImm(mnemonic, code): Name = mnemonic name = mnemonic.lower() @@ -478,6 +446,80 @@ let {{ setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code); + defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') + defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)') + defineMicroRegOp('Adc', ''' + CCFlagBits flags = ccFlagBits; + DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize); + ''') + defineMicroRegOp('Sbb', ''' + CCFlagBits flags = ccFlagBits; + DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize); + ''', True) + defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)') + defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True) + defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)') + # defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True) + defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)') + defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', + elseCode='DestReg=DestReg;', cc=True) + + # Shift instructions + defineMicroRegOp('Sll', ''' + uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3))); + DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize); + ''') + defineMicroRegOp('Srl', ''' + uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3))); + // Because what happens to the bits shift -in- on a right shift + // is not defined in the C/C++ standard, we have to mask them out + // to be sure they're zero. + uint64_t logicalMask = mask(dataSize * 8 - shiftAmt); + DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) & logicalMask, dataSize); + ''') + defineMicroRegOp('Sra', ''' + uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3))); + // Because what happens to the bits shift -in- on a right shift + // is not defined in the C/C++ standard, we have to sign extend + // them manually to be sure. + uint64_t arithMask = + -bits(op2, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt); + DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) | arithMask, dataSize); + ''') + defineMicroRegOp('Ror', ''' + uint8_t shiftAmt = + (op2 & ((dataSize == 8) ? mask(4) : mask(3))); + if(shiftAmt) + { + uint64_t top = SrcReg1 << (dataSize * 8 - shiftAmt); + uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt); + DestReg = merge(DestReg, top | bottom, dataSize); + } + else + DestReg = DestReg; + ''') + defineMicroRegOp('Rcr', ''' + ''') + defineMicroRegOp('Rol', ''' + uint8_t shiftAmt = + (op2 & ((dataSize == 8) ? mask(4) : mask(3))); + if(shiftAmt) + { + uint64_t top = SrcReg1 << shiftAmt; + uint64_t bottom = + bits(SrcReg1, dataSize * 8 - 1, dataSize * 8 - shiftAmt); + DestReg = merge(DestReg, top | bottom, dataSize); + } + else + DestReg = DestReg; + ''') + defineMicroRegOp('Rcl', ''' + ''') + + defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;") + + defineMicroRegOpRd('Rdip', 'DestReg = RIP') + defineMicroRegOpImm('Sext', ''' IntReg val = SrcReg1; int sign_bit = bits(val, imm8-1, imm8-1); -- cgit v1.2.3 From ee6fbdc28b911f0899a93c7711f97b28d22b1039 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 21 Jul 2007 19:27:38 -0700 Subject: Implement rotate with carry microops. --HG-- extra : convert_revision : 1d7ff6611e5b4766a5257c1e73681fabbe5f6d76 --- src/arch/x86/isa/microops/regop.isa | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 1f4de5642..dbbe11c90 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -499,6 +499,19 @@ let {{ DestReg = DestReg; ''') defineMicroRegOp('Rcr', ''' + uint8_t shiftAmt = + (op2 & ((dataSize == 8) ? mask(4) : mask(3))); + if(shiftAmt) + { + CCFlagBits flags = ccFlagBits; + uint64_t top = flags.CF << (dataSize * 8 - shiftAmt); + if(shiftAmt > 1) + top |= SrcReg1 << (dataSize * 8 - shiftAmt - 1); + uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt); + DestReg = merge(DestReg, top | bottom, dataSize); + } + else + DestReg = DestReg; ''') defineMicroRegOp('Rol', ''' uint8_t shiftAmt = @@ -514,6 +527,21 @@ let {{ DestReg = DestReg; ''') defineMicroRegOp('Rcl', ''' + uint8_t shiftAmt = + (op2 & ((dataSize == 8) ? mask(4) : mask(3))); + if(shiftAmt) + { + CCFlagBits flags = ccFlagBits; + uint64_t top = SrcReg1 << shiftAmt; + uint64_t bottom = flags.CF << (shiftAmt - 1); + if(shiftAmt > 1) + bottom |= + bits(SrcReg1, dataSize * 8 - 1, + dataSize * 8 - shiftAmt + 1); + DestReg = merge(DestReg, top | bottom, dataSize); + } + else + DestReg = DestReg; ''') defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;") -- cgit v1.2.3 From f7ff068b3044706a874459afac859a38307828c9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 21 Jul 2007 19:29:39 -0700 Subject: Implemented and hooked in xchg, rotate with carry, and ret instructions --HG-- extra : convert_revision : a8e67b0ab4072308f01e0df7f7ee05b31f605a35 --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 109 ++++++++++----------- src/arch/x86/isa/insts/control_transfer/xreturn.py | 12 +++ src/arch/x86/isa/insts/data_transfer/__init__.py | 3 +- src/arch/x86/isa/insts/data_transfer/xchg.py | 98 ++++++++++++++++++ src/arch/x86/isa/insts/rotate_and_shift/rotate.py | 40 ++++++++ 5 files changed, 204 insertions(+), 58 deletions(-) create mode 100644 src/arch/x86/isa/insts/data_transfer/xchg.py diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 329a03f40..b28f2029c 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -232,8 +232,8 @@ 0x7: JNLE(Jb); } } - 0x10: decode OPCODE_OP_BOTTOM3 { - format Inst { + format Inst { + 0x10: decode OPCODE_OP_BOTTOM3 { //0x0: group1_Eb_Ib(); 0x0: decode MODRM_REG { 0x0: ADD(Eb,Ib); @@ -281,11 +281,11 @@ 0x6: XOR(Ev,Ib); 0x7: CMP(Ev,Ib); } - 0x4: Inst::TEST(Eb,Gb); - 0x5: Inst::TEST(Ev,Gv); + 0x4: TEST(Eb,Gb); + 0x5: TEST(Ev,Gv); + 0x6: XCHG(Eb,Gb); + 0x7: XCHG(Ev,Gv); } - 0x6: xchg_Eb_Gb(); - 0x7: xchg_Ev_Gv(); } 0x11: decode OPCODE_OP_BOTTOM3 { 0x0: Inst::MOV(Eb,Gb); @@ -342,57 +342,52 @@ 0x6: scas_Yb_Al(); 0x7: scas_Yv_rAX(); } - 0x16: decode OPCODE_OP_BOTTOM3 { - 0x0: mov_Al_Ib(); - 0x1: mov_Cl_Ib(); - 0x2: mov_Dl_Ib(); - 0x3: mov_Bl_Ib(); - 0x4: mov_Ah_Ib(); - 0x5: mov_Ch_Ib(); - 0x6: mov_Dh_Ib(); - 0x7: mov_Bh_Ib(); - } - 0x17: Inst::MOV(B,Iv); - 0x18: decode OPCODE_OP_BOTTOM3 { - //0x0: group2_Eb_Ib(); - 0x0: decode MODRM_REG { - 0x0: Inst::ROL(Eb,Ib); - 0x1: Inst::ROR(Eb,Ib); - 0x2: rcl_Eb_Ib(); - 0x3: rcr_Eb_Ib(); - 0x4: Inst::SAL(Eb,Ib); - 0x5: Inst::SHR(Eb,Ib); - 0x6: Inst::SAL(Eb,Ib); - 0x7: Inst::SAR(Eb,Ib); - } - //0x1: group2_Ev_Ib(); - 0x1: decode MODRM_REG { - 0x0: Inst::ROL(Ev,Ib); - 0x1: Inst::ROR(Ev,Ib); - 0x2: rcl_Ev_Ib(); - 0x3: rcr_Ev_Ib(); - 0x4: Inst::SAL(Ev,Ib); - 0x5: Inst::SHR(Ev,Ib); - 0x6: Inst::SAL(Ev,Ib); - 0x7: Inst::SAR(Ev,Ib); - } - 0x2: ret_near_Iw(); - 0x3: Inst::RET_NEAR(); - 0x4: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: les_Gz_Mp(); - } - 0x5: decode MODE_SUBMODE { - 0x0: Inst::UD2(); - default: lds_Gz_Mp(); - } - //0x6: group12_Eb_Ib(); - 0x6: decode MODRM_REG { - 0x0: Inst::MOV(Eb,Ib); - } - //0x7: group12_Ev_Iz(); - 0x7: decode MODRM_REG { - 0x0: Inst::MOV(Ev,Iz); + format Inst { + 0x16: MOV(B,Ib); + 0x17: MOV(B,Iv); + 0x18: decode OPCODE_OP_BOTTOM3 { + //0x0: group2_Eb_Ib(); + 0x0: decode MODRM_REG { + 0x0: ROL(Eb,Ib); + 0x1: ROR(Eb,Ib); + 0x2: RCL(Eb,Ib); + 0x3: RCR(Eb,Ib); + 0x4: SAL(Eb,Ib); + 0x5: SHR(Eb,Ib); + 0x6: SAL(Eb,Ib); + 0x7: SAR(Eb,Ib); + } + //0x1: group2_Ev_Ib(); + 0x1: decode MODRM_REG { + 0x0: ROL(Ev,Ib); + 0x1: ROR(Ev,Ib); + 0x2: RCL(Ev,Ib); + 0x3: RCR(Ev,Ib); + 0x4: SAL(Ev,Ib); + 0x5: SHR(Ev,Ib); + 0x6: SAL(Ev,Ib); + 0x7: SAR(Ev,Ib); + } + 0x2: RET_NEAR(Iw); + 0x3: RET_NEAR(); + 0x4: decode MODE_SUBMODE { + 0x0: UD2(); + default: WarnUnimpl::les_Gz_Mp(); + } + 0x5: decode MODE_SUBMODE { + 0x0: UD2(); + default: WarnUnimpl::lds_Gz_Mp(); + } + //0x6: group12_Eb_Ib(); + 0x6: decode MODRM_REG { + 0x0: MOV(Eb,Ib); + default: UD2(); + } + //0x7: group12_Ev_Iz(); + 0x7: decode MODRM_REG { + 0x0: MOV(Ev,Iz); + default: UD2(); + } } } 0x19: decode OPCODE_OP_BOTTOM3 { diff --git a/src/arch/x86/isa/insts/control_transfer/xreturn.py b/src/arch/x86/isa/insts/control_transfer/xreturn.py index c4442ea02..0000cd3c1 100644 --- a/src/arch/x86/isa/insts/control_transfer/xreturn.py +++ b/src/arch/x86/isa/insts/control_transfer/xreturn.py @@ -63,4 +63,16 @@ def macroop RET_NEAR addi rsp, rsp, dsz wripi t1, 0 }; + +def macroop RET_NEAR_I +{ + # Make the default data size of rets 64 bits in 64 bit mode + .adjust_env oszIn64Override + + limm t2, imm + ld t1, ss, [0, t0, rsp] + addi rsp, rsp, dsz + add rsp, rsp, t2 + wripi t1, 0 +}; ''' diff --git a/src/arch/x86/isa/insts/data_transfer/__init__.py b/src/arch/x86/isa/insts/data_transfer/__init__.py index eda173b34..365f95eaa 100644 --- a/src/arch/x86/isa/insts/data_transfer/__init__.py +++ b/src/arch/x86/isa/insts/data_transfer/__init__.py @@ -55,7 +55,8 @@ categories = ["conditional_move", "move", - "stack_operations"] + "stack_operations", + "xchg"] microcode = "" for category in categories: diff --git a/src/arch/x86/isa/insts/data_transfer/xchg.py b/src/arch/x86/isa/insts/data_transfer/xchg.py new file mode 100644 index 000000000..4f401deb7 --- /dev/null +++ b/src/arch/x86/isa/insts/data_transfer/xchg.py @@ -0,0 +1,98 @@ +# 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 + +microcode = ''' + +# All the memory versions need to use LOCK, regardless of if it was set + +def macroop XCHG_R_R +{ + # Use the xor trick instead of moves to reduce register pressure. + # This probably doesn't make much of a difference, but it's easy. + xor reg, reg, regm + xor regm, regm, reg + xor reg, reg, regm +}; + +def macroop XCHG_R_M +{ + ld t1, ds, [scale, index, base], disp + st reg, ds, [scale, index, base], disp + mov reg, reg, t1 +}; + +def macroop XCHG_R_P +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + st reg, ds, [0, t0, t7], disp + mov reg, reg, t1 +}; + +def macroop XCHG_M_R +{ + ld t1, ds, [scale, index, base], disp + st reg, ds, [scale, index, base], disp + mov reg, reg, t1 +}; + +def macroop XCHG_P_R +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + st reg, ds, [0, t0, t7], disp + mov reg, reg, t1 +}; +''' diff --git a/src/arch/x86/isa/insts/rotate_and_shift/rotate.py b/src/arch/x86/isa/insts/rotate_and_shift/rotate.py index 5330b1ac5..0988f8815 100644 --- a/src/arch/x86/isa/insts/rotate_and_shift/rotate.py +++ b/src/arch/x86/isa/insts/rotate_and_shift/rotate.py @@ -93,6 +93,46 @@ def macroop ROR_P_I ror t1, t1, imm st t1, ds, [0, t0, t7], disp }; + +def macroop RCL_R_I +{ + rcl reg, reg, imm +}; + +def macroop RCL_M_I +{ + ld t1, ds, [scale, index, base], disp + rcl t1, t1, imm + st t1, ds, [scale, index, base], disp +}; + +def macroop RCL_P_I +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + rcl t1, t1, imm + st t1, ds, [0, t0, t7], disp +}; + +def macroop RCR_R_I +{ + rcr reg, reg, imm +}; + +def macroop RCR_M_I +{ + ld t1, ds, [scale, index, base], disp + rcr t1, t1, imm + st t1, ds, [scale, index, base], disp +}; + +def macroop RCR_P_I +{ + rdip t7 + ld t1, ds, [0, t0, t7], disp + rcr t1, t1, imm + st t1, ds, [0, t0, t7], disp +}; ''' #let {{ # class RCL(Inst): -- cgit v1.2.3 From 4b5ba96d380cd70c103e4deee85a95633fada7da Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 21 Jul 2007 22:33:08 -0700 Subject: Add code to turn the style stuff into a mercurial hook. Nag the user during compile if they have an hg cloned copy of M5, have mercurial installed, but don't have the style hook enabled. --HG-- extra : convert_revision : 6bcbb67f1a3fcd36db7d3ef16a9ff19680f126f2 --- SConstruct | 30 ++++- util/style.py | 374 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 403 insertions(+), 1 deletion(-) create mode 100644 util/style.py diff --git a/SConstruct b/SConstruct index fa2366963..1c2dcab1c 100644 --- a/SConstruct +++ b/SConstruct @@ -67,7 +67,7 @@ import sys import os import subprocess -from os.path import join as joinpath +from os.path import isdir, join as joinpath # Check for recent-enough Python and SCons versions. If your system's # default installation of Python is not recent enough, you can use a @@ -97,6 +97,34 @@ SRCDIR = joinpath(ROOT, 'src') # tell python where to find m5 python code sys.path.append(joinpath(ROOT, 'src/python')) +def check_style_hook(ui): + ui.readconfig(joinpath(ROOT, '.hg', 'hgrc')) + style_hook = ui.config('hooks', 'pretxncommit.style', None) + + if not style_hook: + print """\ +You're missing the M5 style hook. +Please install the hook so we can ensure that all code fits a common style. + +All you'd need to do is add the following lines to your repository .hg/hgrc +or your personal .hgrc +---------------- + +[extensions] +style = %s/util/style.py + +[hooks] +pretxncommit.style = python:style.check_whitespace +""" % (ROOT) + sys.exit(1) + +if isdir(joinpath(ROOT, '.hg')): + try: + from mercurial import ui + check_style_hook(ui.ui()) + except ImportError: + pass + ################################################### # # Figure out which configurations to set up based on the path(s) of diff --git a/util/style.py b/util/style.py new file mode 100644 index 000000000..3824cd7f5 --- /dev/null +++ b/util/style.py @@ -0,0 +1,374 @@ +#! /usr/bin/env python +# Copyright (c) 2007 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. +# +# Authors: Nathan Binkert + +import re +import os +import sys + +lead = re.compile(r'^([ \t]+)') +trail = re.compile(r'([ \t]+)$') +any_control = re.compile(r'\b(if|while|for)[ \t]*[(]') +good_control = re.compile(r'\b(if|while|for) [(]') + +lang_types = { 'c' : "C", + 'h' : "C", + 'cc' : "C++", + 'hh' : "C++", + 'cxx' : "C++", + 'hxx' : "C++", + 'cpp' : "C++", + 'hpp' : "C++", + 'C' : "C++", + 'H' : "C++", + 'i' : "swig", + 'py' : "python", + 's' : "asm", + 'S' : "asm", + 'isa' : "isa" } +whitespace_types = ('C', 'C++', 'swig', 'python', 'asm', 'isa') +format_types = ( 'C', 'C++' ) + +def file_type(filename): + extension = filename.split('.') + extension = len(extension) > 1 and extension[-1] + return lang_types.get(extension, None) + +def checkwhite_line(line): + match = lead.search(line) + if match and match.group(1).find('\t') != -1: + return False + + match = trail.search(line) + if match: + return False + + return True + +def checkwhite(filename): + if file_type(filename) not in whitespace_types: + return + + try: + f = file(filename, 'r+') + except OSError, msg: + print 'could not open file %s: %s' % (filename, msg) + return + + for num,line in enumerate(f): + if not checkwhite_line(line): + yield line,num + 1 + +def fixwhite_line(line): + if lead.search(line): + newline = '' + for i,c in enumerate(line): + if c == ' ': + newline += ' ' + elif c == '\t': + newline += ' ' * (tabsize - len(newline) % tabsize) + else: + newline += line[i:] + break + + line = newline + + return line.rstrip() + '\n' + +def fixwhite(filename, tabsize, fixonly=None): + if file_type(filename) not in whitespace_types: + return + + try: + f = file(filename, 'r+') + except OSError, msg: + print 'could not open file %s: %s' % (filename, msg) + return + + lines = list(f) + + f.seek(0) + f.truncate() + + for i,line in enumerate(lines): + if fixonly is None or i in fixonly: + line = fixwhite_line(line) + + print >>f, line, + +def linelen(line): + tabs = line.count('\t') + if not tabs: + return len(line) + + count = 0 + for c in line: + if c == '\t': + count += tabsize - count % tabsize + else: + count += 1 + + return count + +class ValidationStats(object): + def __init__(self): + self.toolong = 0 + self.toolong80 = 0 + self.leadtabs = 0 + self.trailwhite = 0 + self.badcontrol = 0 + self.cret = 0 + + def dump(self): + print '''\ +%d violations of lines over 79 chars. %d of which are 80 chars exactly. +%d cases of whitespace at the end of a line. +%d cases of tabs to indent. +%d bad parens after if/while/for. +%d carriage returns found. +''' % (self.toolong, self.toolong80, self.trailwhite, self.leadtabs, + self.badcontrol, self.cret) + + def __nonzero__(self): + return self.toolong or self.toolong80 or self.leadtabs or \ + self.trailwhite or self.badcontrol or self.cret + +def validate(filename, stats, verbose, exit_code): + if file_type(filename) not in format_types: + return + + def msg(lineno, line, message): + print '%s:%d>' % (filename, lineno + 1), message + if verbose > 2: + print line + + def bad(): + if exit_code is not None: + sys.exit(exit_code) + + cpp = filename.endswith('.cc') or filename.endswith('.hh') + py = filename.endswith('.py') + + if py + cpp != 1: + raise AttributeError, \ + "I don't know how to deal with the file %s" % filename + + try: + f = file(filename, 'r') + except OSError: + if verbose > 0: + print 'could not open file %s' % filename + bad() + return + + for i,line in enumerate(f): + line = line.rstrip('\n') + + # no carriage returns + if line.find('\r') != -1: + self.cret += 1 + if verbose > 1: + msg(i, line, 'carriage return found') + bad() + + # lines max out at 79 chars + llen = linelen(line) + if llen > 79: + stats.toolong += 1 + if llen == 80: + stats.toolong80 += 1 + if verbose > 1: + msg(i, line, 'line too long (%d chars)' % llen) + bad() + + # no tabs used to indent + match = lead.search(line) + if match and match.group(1).find('\t') != -1: + stats.leadtabs += 1 + if verbose > 1: + msg(i, line, 'using tabs to indent') + bad() + + # no trailing whitespace + if trail.search(line): + stats.trailwhite +=1 + if verbose > 1: + msg(i, line, 'trailing whitespace') + bad() + + # for c++, exactly one space betwen if/while/for and ( + if cpp: + match = any_control.search(line) + if match and not good_control.search(line): + stats.badcontrol += 1 + if verbose > 1: + msg(i, line, 'improper spacing after %s' % match.group(1)) + bad() + +def check_whitespace(ui, repo, hooktype, node, parent1, parent2): + from mercurial import bdiff, mdiff, util + if hooktype != 'pretxncommit': + raise AttributeError, \ + "This hook is only meant for pretxncommit, not %s" % hooktype + + tabsize = 8 + verbose = ui.configbool('style', 'verbose', False) + def prompt(name, fixonly=None): + result = ui.prompt("(a)bort, (i)gnore, or (f)ix?", "^[aif]$", "a") + if result == 'a': + return True + elif result == 'i': + pass + elif result == 'f': + fixwhite(name, tabsize, fixonly) + else: + raise RepoError, "Invalid response: '%s'" % result + + return False + + modified, added, removed, deleted, unknown, ignore, clean = repo.status() + + for fname in added: + ok = True + for line,num in checkwhite(fname): + ui.write("invalid whitespace in %s:%d\n" % (fname, num)) + if verbose: + ui.write(">>%s<<\n" % line[-1]) + ok = False + + if not ok: + if prompt(fname): + return True + + wctx = repo.workingctx() + for fname in modified: + fctx = wctx.filectx(fname) + pctx = fctx.parents() + assert len(pctx) == 1 + + pdata = pctx[0].data() + fdata = fctx.data() + + fixonly = set() + lines = enumerate(mdiff.splitnewlines(fdata)) + for pbeg, pend, fbeg, fend in bdiff.blocks(pdata, fdata): + for i, line in lines: + if i < fbeg: + if checkwhite_line(line): + continue + + ui.write("invalid whitespace: %s:%d\n" % (fname, i+1)) + if verbose: + ui.write(">>%s<<\n" % line[:-1]) + fixonly.add(i) + elif i + 1 >= fend: + break + + if fixonly: + if prompt(fname, fixonly): + return True + +def check_format(ui, repo, hooktype, node, parent1, parent2): + if hooktype != 'pretxncommit': + raise AttributeError, \ + "This hook is only meant for pretxncommit, not %s" % hooktype + + modified, added, removed, deleted, unknown, ignore, clean = repo.status() + + verbose = 0 + stats = ValidationStats() + for f in modified + added: + validate(f, stats, verbose, None) + + if stats: + stats.dump() + result = ui.prompt("invalid formatting\n(i)gnore or (a)bort?", + "^[ia]$", "a") + if result.startswith('i'): + pass + elif result.startswith('a'): + return True + else: + raise RepoError, "Invalid response: '%s'" % result + + return False + +if __name__ == '__main__': + import getopt + + progname = sys.argv[0] + if len(sys.argv) < 2: + sys.exit('usage: %s []' % progname) + + fixwhite_usage = '%s fixwhite [-t ] [...] \n' % progname + chkformat_usage = '%s chkformat [...] \n' % progname + chkwhite_usage = '%s chkwhite [...] \n' % progname + + command = sys.argv[1] + if command == 'fixwhite': + flags = 't:' + usage = fixwhite_usage + elif command == 'chkwhite': + flags = 'nv' + usage = chkwhite_usage + elif command == 'chkformat': + flags = 'nv' + usage = chkformat_usage + else: + sys.exit(fixwhite_usage + chkwhite_usage + chkformat_usage) + + opts, args = getopt.getopt(sys.argv[2:], flags) + + code = 1 + verbose = 1 + tabsize = 8 + for opt,arg in opts: + if opt == '-n': + code = None + if opt == '-t': + tabsize = int(arg) + if opt == '-v': + verbose += 1 + + if command == 'fixwhite': + for filename in args: + fixwhite(filename, tabsize) + elif command == 'chkwhite': + for filename in args: + line = checkwhite(filename) + if line: + print 'invalid whitespace at %s:%d' % (filename, line) + elif command == 'chkformat': + stats = ValidationStats() + for filename in files: + validate(filename, stats=stats, verbose=verbose, exit_code=code) + + if verbose > 0: + stats.dump() + else: + sys.exit("command '%s' not found" % command) -- cgit v1.2.3 From bff4f765f53b371139991e531ab00a0c650410e5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 22 Jul 2007 02:23:03 +0000 Subject: Fixed displacement size bug. --HG-- extra : convert_revision : c39249ef598c1bd555098d688381dc62541a07c0 --- src/arch/x86/predecoder.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc index b6c488e45..2c997f34b 100644 --- a/src/arch/x86/predecoder.cc +++ b/src/arch/x86/predecoder.cc @@ -340,6 +340,8 @@ namespace X86ISA emi.sib = nextByte; DPRINTF(Predecoder, "Found SIB byte %#x.\n", nextByte); consumeByte(); + if(emi.modRM.mod == 0 && emi.sib.base == 5) + displacementSize = 4; if(displacementSize) { nextState = DisplacementState; } else if(immediateSize) { -- cgit v1.2.3 From 47b024261895adf02ca6428a9ba67db16d2172b1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 22 Jul 2007 02:34:52 +0000 Subject: Fixed immediate byte accounting bug. --HG-- extra : convert_revision : ee5275da14a2923b9a525ae5b5c582c15df4608a --- src/arch/x86/predecoder.cc | 12 ++++++++---- src/arch/x86/predecoder.hh | 11 ++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc index 2c997f34b..295ca10a4 100644 --- a/src/arch/x86/predecoder.cc +++ b/src/arch/x86/predecoder.cc @@ -72,7 +72,6 @@ namespace X86ISA immediateCollected = 0; emi.immediate = 0; - displacementCollected = 0; emi.displacement = 0; emi.modRM = 0; @@ -359,14 +358,16 @@ namespace X86ISA { State nextState = ErrorState; - getImmediate(displacementCollected, + getImmediate(immediateCollected, emi.displacement, displacementSize); DPRINTF(Predecoder, "Collecting %d byte displacement, got %d bytes.\n", - displacementSize, displacementCollected); + displacementSize, immediateCollected); - if(displacementSize == displacementCollected) { + if(displacementSize == immediateCollected) { + //Reset this for other immediates. + immediateCollected = 0; //Sign extend the displacement switch(displacementSize) { @@ -411,6 +412,9 @@ namespace X86ISA if(immediateSize == immediateCollected) { + //Reset this for other immediates. + immediateCollected = 0; + //XXX Warning! The following is an observed pattern and might //not always be true! diff --git a/src/arch/x86/predecoder.hh b/src/arch/x86/predecoder.hh index f34b66364..450ebd79b 100644 --- a/src/arch/x86/predecoder.hh +++ b/src/arch/x86/predecoder.hh @@ -106,13 +106,13 @@ namespace X86ISA toGet = toGet > remaining ? remaining : toGet; //Shift the bytes we want to be all the way to the right - uint64_t partialDisp = fetchChunk >> (offset * 8); + uint64_t partialImm = fetchChunk >> (offset * 8); //Mask off what we don't want - partialDisp &= mask(toGet * 8); + partialImm &= mask(toGet * 8); //Shift it over to overlay with our displacement. - partialDisp <<= (displacementCollected * 8); + partialImm <<= (immediateCollected * 8); //Put it into our displacement - current |= partialDisp; + current |= partialImm; //Update how many bytes we've collected. collected += toGet; consumeBytes(toGet); @@ -144,9 +144,10 @@ namespace X86ISA bool emiIsReady; //The size of the displacement value int displacementSize; - int displacementCollected; //The size of the immediate value int immediateSize; + //This is how much of any immediate value we've gotten. This is used + //for both the actual immediate and the displacement. int immediateCollected; enum State { -- cgit v1.2.3 From 2cd454d102b5da828b0fbf4b66ef1a24875e69f6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 22 Jul 2007 02:43:03 +0000 Subject: Add the "open" syscall. --HG-- extra : convert_revision : d405ed5d3738639809dd2887955db9253138ccbb --- src/arch/x86/linux/syscalls.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 809784635..30360e602 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -56,6 +56,7 @@ */ #include "arch/x86/linux/process.hh" +#include "arch/x86/linux/linux.hh" #include "kern/linux/linux.hh" #include "sim/syscall_emul.hh" @@ -82,7 +83,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, SyscallDesc X86LinuxProcess::syscallDescs[] = { /* 0 */ SyscallDesc("read", unimplementedFunc), /* 1 */ SyscallDesc("write", unimplementedFunc), - /* 2 */ SyscallDesc("open", unimplementedFunc), + /* 2 */ SyscallDesc("open", openFunc), /* 3 */ SyscallDesc("close", unimplementedFunc), /* 4 */ SyscallDesc("stat", unimplementedFunc), /* 5 */ SyscallDesc("fstat", unimplementedFunc), -- cgit v1.2.3