// -*- 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 CombinationalMacroop, RomMacroop
    class X86Macroop(CombinationalMacroop):
        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().__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 == int_reg::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_idx::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
}};
