// 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. // // Authors: Gabe Black ////////////////////////////////////////////////////////////////////////// // // LIMMOp Microop templates // ////////////////////////////////////////////////////////////////////////// def template MicroLimmOpExecute {{ Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const { %(op_decl)s; %(op_rd)s; %(code)s; %(op_wb)s; return NoFault; } }}; def template MicroLimmOpDeclare {{ class %(class_name)s : public X86ISA::X86MicroopBase { protected: const RegIndex dest; const uint64_t imm; const uint8_t dataSize; RegIndex foldOBit; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; public: %(class_name)s(ExtMachInst _machInst, const char * instMnem, uint64_t setFlags, InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize); %(BasicExecDeclare)s }; }}; def template MicroLimmOpDisassembly {{ std::string %(class_name)s::generateDisassembly(Addr pc, const SymbolTable *symtab) const { std::stringstream response; printMnemonic(response, instMnem, mnemonic); printDestReg(response, 0, dataSize); response << ", "; ccprintf(response, "%#x", imm); return response.str(); } }}; def template MicroLimmOpConstructor {{ %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, uint64_t setFlags, InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags, %(op_class)s), dest(_dest.regIdx), imm(_imm), dataSize(_dataSize) { foldOBit = (dataSize == 1 && !machInst.rex.present) ? 1 << 6 : 0; %(constructor)s; } }}; let {{ class LimmOp(X86Microop): def __init__(self, dest, imm, dataSize="env.dataSize"): self.className = "Limm" self.mnemonic = "limm" self.dest = dest if isinstance(imm, (int, long)): imm = "ULL(%d)" % imm self.imm = imm self.dataSize = dataSize def getAllocator(self, microFlags): allocString = ''' (%(dataSize)s >= 4) ? (StaticInstPtr)(new %(class_name)sBig(machInst, macrocodeBlock, %(flags)s, %(dest)s, %(imm)s, %(dataSize)s)) : (StaticInstPtr)(new %(class_name)s(machInst, macrocodeBlock, %(flags)s, %(dest)s, %(imm)s, %(dataSize)s)) ''' allocator = allocString % { "class_name" : self.className, "mnemonic" : self.mnemonic, "flags" : self.microFlagsText(microFlags), "dest" : self.dest, "imm" : self.imm, "dataSize" : self.dataSize} return allocator microopClasses["limm"] = LimmOp class LfpimmOp(X86Microop): def __init__(self, dest, imm, dataSize="env.dataSize"): self.className = "Lfpimm" self.mnemonic = "lfpimm" self.dest = dest if isinstance(imm, (int, long)): imm = "ULL(%d)" % imm elif isinstance(imm, float): imm = "getDoubleBits(%.16f)" % imm self.imm = imm self.dataSize = dataSize def getAllocator(self, microFlags): allocator = '''new %(class_name)s(machInst, macrocodeBlock, %(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, "dataSize" : self.dataSize} return allocator microopClasses["lfpimm"] = LfpimmOp }}; let {{ # Build up the all register version of this micro op iops = [InstObjParams("limm", "Limm", 'X86MicroopBase', {"code" : "DestReg = merge(DestReg, imm, dataSize);"}), InstObjParams("limm", "LimmBig", 'X86MicroopBase', {"code" : "DestReg = imm & mask(dataSize * 8);"})] for iop in iops: header_output += MicroLimmOpDeclare.subst(iop) decoder_output += MicroLimmOpConstructor.subst(iop) decoder_output += MicroLimmOpDisassembly.subst(iop) exec_output += MicroLimmOpExecute.subst(iop) iop = InstObjParams("lfpimm", "Lfpimm", 'X86MicroopBase', {"code" : "FpDestReg_uqw = imm"}) header_output += MicroLimmOpDeclare.subst(iop) decoder_output += MicroLimmOpConstructor.subst(iop) decoder_output += MicroLimmOpDisassembly.subst(iop) exec_output += MicroLimmOpExecute.subst(iop) }};