// -*- 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.

//////////////////////////////////////////////////////////////////////////////
//
//  Architecture independent
//

// Execute method for macroops.
def template MacroExecPanic {{
    Fault
    execute(ExecContext *, Trace::InstRecord *) const override
    {
        panic("Tried to execute macroop directly!");
        return NoFault;
    }
}};

output header {{
    // Base class for combinationally generated macroops
    class Macroop : public X86ISA::MacroopBase
    {
      public:
        Macroop(const char *mnem, ExtMachInst _machInst,
                uint32_t _numMicroops, X86ISA::EmulEnv _env)
                    : MacroopBase(mnem, _machInst, _numMicroops, _env)
        {}

        Fault
        execute(ExecContext *, Trace::InstRecord *) const override
        {
            panic("Tried to execute macroop directly!");
        }
    };
}};

//////////////////////////////////////////////////////////////////////////////
//
//  X86 specific
//
//////////////////////////////////////////////////////////////////////////////

// Basic instruction class declaration template.
def template MacroDeclare {{
    GEM5_DEPRECATED_NAMESPACE(X86Macroop, x86_macroop);
    namespace x86_macroop
    {
        /**
         * Static instruction class for "%(mnemonic)s".
         */
        class %(class_name)s : public %(base_class)s
        {
          private:
            %(declareLabels)s
          public:
            // Constructor.
            %(class_name)s(ExtMachInst machInst, X86ISA::EmulEnv _env);

            std::string generateDisassembly(
                    Addr pc, const loader::SymbolTable *symtab) const override;
        };
    }
}};

def template MacroDisassembly {{
    std::string
    x86_macroop::%(class_name)s::generateDisassembly(
            Addr pc, const loader::SymbolTable *symtab) const
    {
        std::stringstream out;
        out << mnemonic << "\t";

        int regSize = %(regSize)s;
        %(disassembly)s
        // Shut up gcc.
        regSize = regSize;
        return out.str();
    }
}};

// Basic instruction class constructor template.
def template MacroConstructor {{
        x86_macroop::%(class_name)s::%(class_name)s(
                ExtMachInst machInst, EmulEnv _env)
            : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s, _env)
        {
            %(adjust_env)s;
            %(adjust_imm)s;
            %(adjust_disp)s;
            %(init_env)s;
            %(constructor)s;
            const char *macrocodeBlock = "%(class_name)s";
            //alloc_microops is the code that sets up the microops
            //array in the parent class.
            %(alloc_microops)s;
        }
}};

let {{
    from micro_asm import Combinational_Macroop, Rom_Macroop
    class X86Macroop(Combinational_Macroop):
        def add_microop(self, mnemonic, microop):
            microop.mnemonic = mnemonic
            microop.micropc = len(self.microops)
            self.microops.append(microop)
        def setAdjustEnv(self, val):
            self.adjust_env = val
        def adjustImm(self, val):
            self.adjust_imm += val
        def adjustDisp(self, val):
            self.adjust_disp += val
        def serializeBefore(self):
            self.serialize_before = True
        def serializeAfter(self):
            self.serialize_after = True

        def function_call(self):
            self.function_call = True
        def function_return(self):
            self.function_return = True
        def control_direct(self):
            self.control_direct = True
        def control_indirect(self):
            self.control_indirect = True

        def __init__(self, name):
            super(X86Macroop, self).__init__(name)
            self.directives = {
                "adjust_env" : self.setAdjustEnv,
                "adjust_imm" : self.adjustImm,
                "adjust_disp" : self.adjustDisp,
                "serialize_before" : self.serializeBefore,
                "serialize_after" : self.serializeAfter,
                "function_call" : self.function_call,
                "function_return" : self.function_return,
                "control_direct" : self.control_direct,
                "control_indirect" : self.control_indirect
            }
            self.declared = False
            self.adjust_env = ""
            self.init_env = ""
            self.adjust_imm = '''
                uint64_t adjustedImm = IMMEDIATE;
                //This is to pacify gcc in case the immediate isn't used.
                adjustedImm = adjustedImm;
            '''
            self.adjust_disp = '''
                uint64_t adjustedDisp = DISPLACEMENT;
                //This is to pacify gcc in case the displacement isn't used.
                adjustedDisp = adjustedDisp;
            '''
            self.serialize_before = False
            self.serialize_after = False
            self.function_call = False
            self.function_return = False
            self.control_direct = False
            self.control_indirect = False

        def getAllocator(self, env):
            return "new x86_macroop::%s(machInst, %s)" % \
                    (self.name, env.getAllocator())
        def getMnemonic(self):
            mnemonic = self.name.lower()
            mnemonic = re.match(r'[^_]*', mnemonic).group(0)
            return mnemonic
        def getDeclaration(self):
            #FIXME This first parameter should be the mnemonic. I need to
            #write some code which pulls that out
            declareLabels = ""
            for (label, microop) in self.labels.items():
                declareLabels += "const static uint64_t label_%s = %d;\n" \
                                  % (label, microop.micropc)
            iop = InstObjParams(self.getMnemonic(), self.name, "Macroop",
                    {"code" : "",
                     "declareLabels" : declareLabels
                    })
            return MacroDeclare.subst(iop);
        def getDefinition(self, env):
            #FIXME This first parameter should be the mnemonic. I need to
            #write some code which pulls that out
            numMicroops = len(self.microops)
            allocMicroops = ''
            micropc = 0
            for op in self.microops:
                flags = ["IsMicroop"]
                if micropc == 0:
                    flags.append("IsFirstMicroop")

                    if self.serialize_before:
                        flags.append("IsSerializing")
                        flags.append("IsSerializeBefore")

                if micropc == numMicroops - 1:
                    flags.append("IsLastMicroop")

                    if self.serialize_after:
                        flags.append("IsSerializing")
                        flags.append("IsSerializeAfter")

                    if self.function_call:
                        flags.append("IsCall")
                        flags.append("IsUncondControl")
                    if self.function_return:
                        flags.append("IsReturn")
                        flags.append("IsUncondControl")
                    if self.control_direct:
                        flags.append("IsDirectControl")
                    if self.control_indirect:
                        flags.append("IsIndirectControl")
                else:
                    flags.append("IsDelayedCommit")

                allocMicroops += \
                    "microops[%d] = %s;\n" % \
                    (micropc, op.getAllocator(flags))
                micropc += 1
            if env.useStackSize:
                useStackSize = "true"
            else:
                useStackSize = "false"
            if env.memoryInst:
                memoryInst = "true"
            else:
                memoryInst = "false"
            regSize = '''(%s || (env.base == INTREG_RSP && %s) ?
                         env.stackSize :
                         env.dataSize)''' % (useStackSize, memoryInst)
            iop = InstObjParams(self.getMnemonic(), self.name, "Macroop",
                                {"code" : "", "num_microops" : numMicroops,
                                 "alloc_microops" : allocMicroops,
                                 "adjust_env" : self.adjust_env,
                                 "adjust_imm" : self.adjust_imm,
                                 "adjust_disp" : self.adjust_disp,
                                 "disassembly" : env.disassembly,
                                 "regSize" : regSize,
                                 "init_env" : self.initEnv})
            return MacroConstructor.subst(iop) + \
                   MacroDisassembly.subst(iop);
}};

let {{
    class EmulEnv(object):
        def __init__(self):
            self.reg = "0"
            self.regUsed = False
            self.regm = "0"
            self.regmUsed = False
            self.seg = "SEGMENT_REG_DS"
            self.size = None
            self.addressSize = "ADDRSIZE"
            self.dataSize = "OPSIZE"
            self.stackSize = "STACKSIZE"
            self.doModRM = False
            self.disassembly = ""
            self.firstArgument = True
            self.useStackSize = False
            self.memoryInst = False

        def addToDisassembly(self, code):
            if not self.firstArgument:
                self.disassembly += "out << \", \";\n"
            self.firstArgument = False
            self.disassembly += code

        def getAllocator(self):
            if self.size == 'b':
                self.dataSize = 1
            elif self.size == 'd':
                self.dataSize = 4
            #This is for "double plus" which is normally a double word unless
            #the REX W bit is set, in which case it's a quad word. It's used
            #for some SSE instructions.
            elif self.size == 'dp':
                self.dataSize = "(REX_W ? 8 : 4)"
            elif self.size == 'q':
                self.dataSize = 8
            elif self.size == 'v':
                self.dataSize = "OPSIZE"
            elif self.size == 'w':
                self.dataSize = 2
            elif self.size == 'z':
                self.dataSize = "((OPSIZE == 8) ? 4 : OPSIZE)"
            elif self.size:
                raise Exception("Unrecognized size type {}!".format(self.size))
            return '''EmulEnv(%(reg)s,
                              %(regm)s,
                              %(dataSize)s,
                              %(addressSize)s,
                              %(stackSize)s)''' % \
                self.__dict__

        def addReg(self, reg):
            if not self.regUsed:
                self.reg = reg
                self.regUsed = True
            elif not self.regmUsed:
                self.regm = reg
                self.regmUsed = True
            else:
                raise Exception("EmulEnv is out of register specialization " +
                    "spots.")
        def setSize(self, size):
            if not self.size:
                self.size = size
            else:
                if self.size != size:
                    raise Exception("Conflicting register sizes " +
                        "{} and {}!".format(self.size, size))
}};

let {{
    doModRMString = "env.doModRM(machInst);\n"
    noModRMString = "env.setSeg(machInst);\n"
    def genMacroop(Name, env):
        blocks = OutputBlocks()
        if not Name in macroopDict:
            raise Exception("Unrecognized instruction: {}".format(Name))
        macroop = macroopDict[Name]
        if not macroop.declared:
            if env.doModRM:
                macroop.initEnv = doModRMString
            else:
                macroop.initEnv = noModRMString
            blocks.header_output = macroop.getDeclaration()
            blocks.decoder_output = macroop.getDefinition(env)
            macroop.declared = True
        blocks.decode_block = "return %s;\n" % macroop.getAllocator(env)
        return blocks
}};
