-// Copyright (c) 2007 The Hewlett-Packard Development Company
+// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
+// Copyright (c) 2011 Mark D. Hill and David A. Wood
// 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 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.
//
-// 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
+// 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. 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 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
// 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
//////////////////////////////////////////////////////////////////////////
//
//
//////////////////////////////////////////////////////////////////////////
-def template MicroFaultExecute {{
- Fault %(class_name)s ::execute(%(CPU_exec_context)s *xc,
- Trace::InstRecord *traceData) const
+output header {{
+ class MicroFaultBase : public X86ISA::X86MicroopBase
+ {
+ protected:
+ Fault fault;
+ uint8_t cc;
+
+ public:
+ MicroFaultBase(ExtMachInst _machInst, const char * instMnem,
+ uint64_t setFlags, Fault _fault, uint8_t _cc);
+
+ std::string generateDisassembly(Addr pc,
+ const Loader::SymbolTable *symtab) const override;
+ };
+
+ class MicroHalt : public X86ISA::X86MicroopBase
+ {
+ public:
+ MicroHalt(ExtMachInst _machInst, const char * instMnem,
+ uint64_t setFlags) :
+ X86MicroopBase(_machInst, "halt", instMnem,
+ setFlags | (ULL(1) << StaticInst::IsNonSpeculative) |
+ (ULL(1) << StaticInst::IsQuiesce),
+ No_OpClass)
{
- //Return the fault we were constructed with
- return fault;
}
+
+ Fault execute(ExecContext *, Trace::InstRecord *) const override;
+
+ std::string generateDisassembly(Addr pc,
+ const Loader::SymbolTable *symtab) const override;
+ };
}};
def template MicroFaultDeclare {{
- class %(class_name)s : public X86MicroOpBase
+ class %(class_name)s : public %(base_class)s
{
- protected:
- Fault fault;
- void buildMe();
+ private:
+ %(reg_idx_arr_decl)s;
public:
- %(class_name)s(ExtMachInst _machInst,
- const char * instMnem,
- bool isMicro, bool isDelayed, bool isFirst, bool isLast,
- Fault _fault);
-
- %(class_name)s(ExtMachInst _machInst,
- const char * instMnem,
- Fault _fault);
+ %(class_name)s(ExtMachInst _machInst, const char * instMnem,
+ uint64_t setFlags, Fault _fault, uint8_t _cc);
- %(BasicExecDeclare)s
+ Fault execute(ExecContext *, Trace::InstRecord *) const override;
};
}};
-def template MicroFaultConstructor {{
+def template MicroFaultExecute {{
+ Fault %(class_name)s::execute(ExecContext *xc,
+ Trace::InstRecord *traceData) const
+ {
+ %(op_decl)s;
+ %(op_rd)s;
+ if (%(cond_test)s) {
+ //Return the fault we were constructed with
+ return fault;
+ } else {
+ return NoFault;
+ }
+ }
+}};
+
+output exec {{
+ Fault
+ MicroHalt::execute(ExecContext *xc, Trace::InstRecord * traceData) const
+ {
+ xc->tcBase()->suspend();
+ return NoFault;
+ }
+}};
- inline void %(class_name)s::buildMe()
+output decoder {{
+ MicroFaultBase::MicroFaultBase(
+ ExtMachInst machInst, const char * instMnem,
+ uint64_t setFlags, Fault _fault, uint8_t _cc) :
+ X86MicroopBase(machInst, "fault", instMnem, setFlags, No_OpClass),
+ fault(_fault), cc(_cc)
{
+ }
+}};
+
+def template MicroFaultConstructor {{
+ %(class_name)s::%(class_name)s(
+ ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
+ Fault _fault, uint8_t _cc) :
+ %(base_class)s(machInst, instMnem, setFlags, _fault, _cc)
+ {
+ %(set_reg_idx_arr)s;
%(constructor)s;
}
+}};
- inline %(class_name)s::%(class_name)s(
- ExtMachInst machInst, const char * instMnem, Fault _fault) :
- %(base_class)s(machInst, "%(mnemonic)s", instMnem,
- false, false, false, false, %(op_class)s), fault(_fault)
+output decoder {{
+ std::string
+ MicroFaultBase::generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const
{
- buildMe();
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+ if(fault)
+ response << fault->name();
+ else
+ response << "No Fault";
+
+ return response.str();
}
- inline %(class_name)s::%(class_name)s(
- ExtMachInst machInst, const char * instMnem,
- bool isMicro, bool isDelayed, bool isFirst, bool isLast,
- Fault _fault) :
- %(base_class)s(machInst, "%(mnemonic)s", instMnem,
- isMicro, isDelayed, isFirst, isLast, %(op_class)s),
- fault(_fault)
+ std::string
+ MicroHalt::generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const
{
- buildMe();
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+
+ return response.str();
}
}};
let {{
- # This microop takes in a single parameter, a fault to return.
- iop = InstObjParams("fault", "GenFault", 'X86MicroOpBase', {"code" : ""})
+ class Fault(X86Microop):
+ className = "MicroFault"
+ def __init__(self, fault, flags=None):
+ self.fault = fault
+ if flags:
+ if not isinstance(flags, (list, tuple)):
+ raise Exception("flags must be a list or tuple of flags")
+ self.cond = " | ".join(flags)
+ self.className += "Flags"
+ else:
+ self.cond = "0"
+
+ def getAllocator(self, microFlags):
+ allocator = '''new %(class_name)s(machInst, macrocodeBlock,
+ %(flags)s, %(fault)s, %(cc)s)''' % {
+ "class_name" : self.className,
+ "flags" : self.microFlagsText(microFlags),
+ "fault" : self.fault,
+ "cc" : self.cond}
+ return allocator
+
+ iop = InstObjParams("fault", "MicroFaultFlags", "MicroFaultBase",
+ {"code": "",
+ "cond_test": "checkCondition(ccFlagBits | cfofBits | dfBit | \
+ ecfBit | ezfBit, cc)"})
+ exec_output = MicroFaultExecute.subst(iop)
+ header_output = MicroFaultDeclare.subst(iop)
+ decoder_output = MicroFaultConstructor.subst(iop)
+ iop = InstObjParams("fault", "MicroFault", "MicroFaultBase",
+ {"code": "",
+ "cond_test": "true"})
+ exec_output += MicroFaultExecute.subst(iop)
header_output += MicroFaultDeclare.subst(iop)
decoder_output += MicroFaultConstructor.subst(iop)
- exec_output += MicroFaultExecute.subst(iop)
+ microopClasses["fault"] = Fault
+
+ class Halt(X86Microop):
+ className = "MicroHalt"
+ def __init__(self):
+ pass
+
+ def getAllocator(self, microFlags):
+ return "new MicroHalt(machInst, macrocodeBlock, %s)" % \
+ self.microFlagsText(microFlags)
+
+ microopClasses["halt"] = Halt
+}};
+
+def template MicroFenceOpDeclare {{
+ class %(class_name)s : public X86ISA::X86MicroopBase
+ {
+ private:
+ %(reg_idx_arr_decl)s;
+
+ public:
+ %(class_name)s(ExtMachInst _machInst,
+ const char * instMnem,
+ uint64_t setFlags);
+
+ Fault execute(ExecContext *, Trace::InstRecord *) const override;
+ };
+}};
+
+def template MicroFenceOpConstructor {{
+ %(class_name)s::%(class_name)s(
+ ExtMachInst machInst, const char * instMnem, uint64_t setFlags) :
+ %(base_class)s(machInst, "%(mnemonic)s", instMnem,
+ setFlags, %(op_class)s)
+ {
+ %(set_reg_idx_arr)s;
+ %(constructor)s;
+ }
+}};
+
+let {{
+ class MfenceOp(X86Microop):
+ def __init__(self):
+ self.className = "Mfence"
+ self.mnemonic = "mfence"
+ self.instFlags = "| (1ULL << StaticInst::IsReadBarrier)" + \
+ "| (1ULL << StaticInst::IsWriteBarrier)"
+
+ def getAllocator(self, microFlags):
+ allocString = '''
+ (StaticInstPtr)(new %(class_name)s(machInst,
+ macrocodeBlock, %(flags)s))
+ '''
+ allocator = allocString % {
+ "class_name" : self.className,
+ "mnemonic" : self.mnemonic,
+ "flags" : self.microFlagsText(microFlags) + self.instFlags}
+ return allocator
+
+ microopClasses["mfence"] = MfenceOp
+}};
+
+let {{
+ # Build up the all register version of this micro op
+ iop = InstObjParams("mfence", "Mfence", 'X86MicroopBase',
+ {"code" : ""})
+ header_output += MicroFenceOpDeclare.subst(iop)
+ decoder_output += MicroFenceOpConstructor.subst(iop)
+ exec_output += BasicExecute.subst(iop)
}};