| // -*- mode:c++ -*- |
| |
| // Copyright (c) 2007 The Hewlett-Packard Development Company |
| // All rights reserved. |
| // |
| // The license below extends only to copyright in the software and shall |
| // not be construed as granting a license to any other intellectual |
| // property including but not limited to intellectual property relating |
| // to a hardware implementation of the functionality of the software |
| // licensed hereunder. You may use the software subject to the license |
| // terms below provided that you ensure that this notice is replicated |
| // unmodified and in its entirety in all distributions of the software, |
| // modified or unmodified, in source code or in binary form. |
| // |
| // 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. |
| |
| let {{ |
| # This will be populated with mappings between microop mnemonics and |
| # the classes that represent them. |
| microopClasses = {} |
| }}; |
| |
| ////////////////////////////////////////////////////////////////////////// |
| // |
| // Base class for the python representation of x86 microops |
| // |
| ////////////////////////////////////////////////////////////////////////// |
| |
| let {{ |
| class Operand(object): |
| @classmethod |
| def isDual(cls): |
| return False |
| |
| @classmethod |
| def cxx_class(cls): |
| return 'X86ISA::' + cls.flavor + cls.idx_name + 'Op' |
| |
| class FlavorlessOperand(Operand): |
| @classmethod |
| def cxx_class(cls): |
| return 'X86ISA::' + cls.op_type |
| |
| def __init__(self, it): |
| self.value = next(it) |
| |
| def ctor_args(self): |
| return str(self.value) |
| |
| class UpcOp(FlavorlessOperand): |
| op_type = 'Upc' |
| class FaultOp(FlavorlessOperand): |
| op_type = 'Fault' |
| class AddrOp(FlavorlessOperand): |
| op_type = 'Addr' |
| |
| def __init__(self, it): |
| self.segment = next(it) |
| [self.scale, self.index, self.base] = next(it) |
| self.disp = next(it) |
| |
| def ctor_args(self): |
| args = [self.scale, self.index, self.base, self.disp, self.segment] |
| return ', '.join(map(str, args)) |
| |
| class ImmOp(object): |
| idx_name = '' |
| |
| def __init__(self, it): |
| self.value = next(it) |
| super(ImmOp, self).__init__() |
| |
| def ctor_args(self): |
| return str(self.value) |
| |
| class Imm8Op(ImmOp, Operand): |
| flavor = 'Imm8' |
| class Imm64Op(ImmOp, Operand): |
| flavor = 'Imm64' |
| |
| class DestOp(object): |
| idx_name = 'Dest' |
| class Src1Op(object): |
| idx_name = 'Src1' |
| class Src2Op(object): |
| idx_name = 'Src2' |
| |
| class RegisterOp(object): |
| def __init__(self, it): |
| self.idx = next(it) |
| super(RegisterOp, self).__init__() |
| |
| def ctor_args(self): |
| return str(self.idx) |
| |
| class FoldedOp(RegisterOp): |
| flavor = 'Folded' |
| class DbgOp(RegisterOp): |
| flavor = 'Dbg' |
| class CrOp(RegisterOp): |
| flavor = 'Cr' |
| class SegOp(RegisterOp): |
| flavor = 'Seg' |
| class MiscOp(RegisterOp): |
| flavor = 'Misc' |
| class FloatOp(RegisterOp): |
| flavor = 'Float' |
| class IntOp(RegisterOp): |
| flavor = 'Int' |
| class DataOp(RegisterOp): |
| idx_name = 'Data' |
| class DataHiOp(RegisterOp): |
| idx_name = 'DataHi' |
| class DataLowOp(RegisterOp): |
| idx_name = 'DataLow' |
| |
| class FoldedDataOp(FoldedOp, DataOp, Operand): |
| pass |
| class FloatDataOp(FloatOp, DataOp, Operand): |
| pass |
| class FoldedDataHiOp(FoldedOp, DataHiOp, Operand): |
| pass |
| class FoldedDataLowOp(FoldedOp, DataLowOp, Operand): |
| pass |
| |
| class FoldedDestOp(FoldedOp, DestOp, Operand): |
| pass |
| class DbgDestOp(DbgOp, DestOp, Operand): |
| pass |
| class CrDestOp(CrOp, DestOp, Operand): |
| pass |
| class SegDestOp(SegOp, DestOp, Operand): |
| pass |
| class MiscDestOp(MiscOp, DestOp, Operand): |
| pass |
| class FloatDestOp(FloatOp, DestOp, Operand): |
| pass |
| class IntDestOp(IntOp, DestOp, Operand): |
| pass |
| |
| class FoldedSrc1Op(FoldedOp, Src1Op, Operand): |
| pass |
| class DbgSrc1Op(DbgOp, Src1Op, Operand): |
| pass |
| class CrSrc1Op(CrOp, Src1Op, Operand): |
| pass |
| class SegSrc1Op(SegOp, Src1Op, Operand): |
| pass |
| class MiscSrc1Op(MiscOp, Src1Op, Operand): |
| pass |
| class FloatSrc1Op(FloatOp, Src1Op, Operand): |
| pass |
| class IntSrc1Op(IntOp, Src1Op, Operand): |
| pass |
| |
| class FoldedSrc2Op(FoldedOp, Src2Op, Operand): |
| pass |
| class DbgSrc2Op(DbgOp, Src2Op, Operand): |
| pass |
| class CrSrc2Op(CrOp, Src2Op, Operand): |
| pass |
| class SegSrc2Op(SegOp, Src2Op, Operand): |
| pass |
| class MiscSrc2Op(MiscOp, Src2Op, Operand): |
| pass |
| class FloatSrc2Op(FloatOp, Src2Op, Operand): |
| pass |
| class IntSrc2Op(IntOp, Src2Op, Operand): |
| pass |
| |
| class Op2(object): |
| @classmethod |
| def isDual(cls): |
| return True |
| |
| RegType = FoldedSrc2Op |
| FloatType = FloatSrc2Op |
| ImmType = Imm8Op |
| |
| class X86Microop(object): |
| |
| generatorNameTemplate = "generate_%s_%d" |
| |
| generatorTemplate = ''' |
| StaticInstPtr |
| ''' + generatorNameTemplate + '''(StaticInstPtr curMacroop) |
| { |
| static const char *macrocodeBlock = romMnemonic; |
| static ExtMachInst dummyExtMachInst; |
| static const EmulEnv dummyEmulEnv(0, 0, 1, 1, 1); |
| |
| Macroop * macroop = dynamic_cast<Macroop *>(curMacroop.get()); |
| const ExtMachInst &machInst = |
| macroop ? macroop->getExtMachInst() : dummyExtMachInst; |
| GEM5_VAR_USED const EmulEnv &env = |
| macroop ? macroop->getEmulEnv() : dummyEmulEnv; |
| using namespace rom_labels; |
| return %s; |
| } |
| ''' |
| |
| def __init__(self, name): |
| self.name = name |
| |
| def microFlagsText(self, flags): |
| wrapped = ("(1ULL << StaticInst::%s)" % flag for flag in flags) |
| return " | ".join(wrapped) |
| |
| def getGeneratorDef(self, micropc): |
| return self.generatorTemplate % \ |
| (self.className, micropc, \ |
| self.getAllocator(["IsMicroop", "IsDelayedCommit"])) |
| |
| def getGenerator(self, micropc): |
| return self.generatorNameTemplate % (self.className, micropc) |
| }}; |