// -*- mode:c++ -*-

// Copyright (c) 2003-2005 The Regents of The University of Michigan
// All rights reserved.
//
// 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: Steve Reinhardt
//          Kevin Lim

////////////////////////////////////////////////////////////////////
//
// Memory-format instructions: LoadAddress, Load, Store
//

output header {{
    /**
     * Base class for general Alpha memory-format instructions.
     */
    class Memory : public AlphaStaticInst
    {
      protected:

        /// Memory request flags.  See mem_req_base.hh.
        Request::Flags memAccessFlags;

        /// Constructor
        Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
            : AlphaStaticInst(mnem, _machInst, __opClass)
        {
        }

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

    /**
     * Base class for memory-format instructions using a 32-bit
     * displacement (i.e. most of them).
     */
    class MemoryDisp32 : public Memory
    {
      protected:
        /// Displacement for EA calculation (signed).
        int32_t disp;

        /// Constructor.
        MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
            : Memory(mnem, _machInst, __opClass),
              disp(MEMDISP)
        {
        }
    };


    /**
     * Base class for a few miscellaneous memory-format insts
     * that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
     * None of these instructions has a destination register either.
     */
    class MemoryNoDisp : public Memory
    {
      protected:
        /// Constructor
        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
            : Memory(mnem, _machInst, __opClass)
        {
        }

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


output decoder {{
    std::string
    Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
    {
        return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
                        flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
    }

    std::string
    MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
    {
        return csprintf("%-10s (r%d)", mnemonic, RB);
    }
}};

def format LoadAddress(code) {{
    iop = InstObjParams(name, Name, 'MemoryDisp32', code)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    decode_block = BasicDecode.subst(iop)
    exec_output = BasicExecute.subst(iop)
}};


def template LoadStoreDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      public:

        /// Constructor.
        %(class_name)s(ExtMachInst machInst);

        Fault execute(ExecContext *, Trace::InstRecord *) const override;
        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
        Fault completeAcc(PacketPtr, ExecContext *,
                          Trace::InstRecord *) const override;
    };
}};

def template LoadStoreConstructor {{
    %(class_name)s::%(class_name)s(ExtMachInst machInst)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
    {
        %(constructor)s;
    }
}};


def template LoadExecute {{
    Fault %(class_name)s::execute(ExecContext *xc,
                                  Trace::InstRecord *traceData) const
    {
        Addr EA;
        Fault fault = NoFault;

        %(fp_enable_check)s;
        %(op_decl)s;
        %(op_rd)s;
        %(ea_code)s;

        if (fault == NoFault) {
            fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
            %(memacc_code)s;
        }

        if (fault == NoFault) {
            %(op_wb)s;
        }

        return fault;
    }
}};


def template LoadInitiateAcc {{
    Fault %(class_name)s::initiateAcc(ExecContext *xc,
                                      Trace::InstRecord *traceData) const
    {
        Addr EA;
        Fault fault = NoFault;

        %(fp_enable_check)s;
        %(op_src_decl)s;
        %(op_rd)s;
        %(ea_code)s;

        if (fault == NoFault) {
            fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
        }

        return fault;
    }
}};


def template LoadCompleteAcc {{
    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
                                      Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;

        %(fp_enable_check)s;
        %(op_decl)s;

        getMem(pkt, Mem, traceData);

        if (fault == NoFault) {
            %(memacc_code)s;
        }

        if (fault == NoFault) {
            %(op_wb)s;
        }

        return fault;
    }
}};


def template StoreExecute {{
    Fault %(class_name)s::execute(ExecContext *xc,
                                  Trace::InstRecord *traceData) const
    {
        Addr EA;
        Fault fault = NoFault;

        %(fp_enable_check)s;
        %(op_decl)s;
        %(op_rd)s;
        %(ea_code)s;

        if (fault == NoFault) {
            %(memacc_code)s;
        }

        if (fault == NoFault) {
            fault = writeMemAtomic(xc, traceData, Mem, EA,
                    memAccessFlags, NULL);
        }

        if (fault == NoFault) {
            %(postacc_code)s;
        }

        if (fault == NoFault) {
            %(op_wb)s;
        }

        return fault;
    }
}};

def template StoreCondExecute {{
    Fault %(class_name)s::execute(ExecContext *xc,
                                  Trace::InstRecord *traceData) const
    {
        Addr EA;
        Fault fault = NoFault;
        uint64_t write_result = 0;

        %(fp_enable_check)s;
        %(op_decl)s;
        %(op_rd)s;
        %(ea_code)s;

        if (fault == NoFault) {
            %(memacc_code)s;
        }

        if (fault == NoFault) {
            fault = writeMemAtomic(xc, traceData, Mem, EA,
                    memAccessFlags, &write_result);
        }

        if (fault == NoFault) {
            %(postacc_code)s;
        }

        if (fault == NoFault) {
            %(op_wb)s;
        }

        return fault;
    }
}};

def template StoreInitiateAcc {{
    Fault %(class_name)s::initiateAcc(ExecContext *xc,
                                      Trace::InstRecord *traceData) const
    {
        Addr EA;
        Fault fault = NoFault;

        %(fp_enable_check)s;
        %(op_decl)s;
        %(op_rd)s;
        %(ea_code)s;

        if (fault == NoFault) {
            %(memacc_code)s;
        }

        if (fault == NoFault) {
            fault = writeMemTiming(xc, traceData, Mem, EA,
                    memAccessFlags, NULL);
        }

        return fault;
    }
}};


def template StoreCompleteAcc {{
    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
                                      Trace::InstRecord *traceData) const
    {
        return NoFault;
    }
}};


def template StoreCondCompleteAcc {{
    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
                                      Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;

        %(fp_enable_check)s;
        %(op_dest_decl)s;

        uint64_t write_result = pkt->req->getExtraData();

        if (fault == NoFault) {
            %(postacc_code)s;
        }

        if (fault == NoFault) {
            %(op_wb)s;
        }

        return fault;
    }
}};


def template MiscExecute {{
    Fault %(class_name)s::execute(ExecContext *xc,
                                  Trace::InstRecord *traceData) const
    {
        Addr EA M5_VAR_USED;
        Fault fault = NoFault;

        %(fp_enable_check)s;
        %(op_decl)s;
        %(op_rd)s;
        %(ea_code)s;

        warn_once("Prefetch instructions in Alpha do not do anything\n");
        if (fault == NoFault) {
            %(memacc_code)s;
        }

        return NoFault;
    }
}};

// Prefetches in Alpha don't actually do anything
// They just build an effective address and complete
def template MiscInitiateAcc {{
    Fault %(class_name)s::initiateAcc(ExecContext *xc,
                                      Trace::InstRecord *traceData) const
    {
        warn("initiateAcc undefined: Misc instruction does not support split "
             "access method!");
        return NoFault;
    }
}};


def template MiscCompleteAcc {{
    Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
                                      Trace::InstRecord *traceData) const
    {
        warn("completeAcc undefined: Misc instruction does not support split "
             "access method!");

        return NoFault;
    }
}};


// load instructions use Ra as dest, so check for
// Ra == 31 to detect nops
def template LoadNopCheckDecode {{
 {
     AlphaStaticInst *i = new %(class_name)s(machInst);
     if (RA == 31) {
         i = makeNop(i);
     }
     return i;
 }
}};


// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
def template LoadPrefetchCheckDecode {{
 {
     if (RA != 31) {
         return new %(class_name)s(machInst);
     }
     else {
         return new %(class_name)sPrefetch(machInst);
     }
 }
}};


let {{
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
                  postacc_code = '', base_class = 'MemoryDisp32',
                  decode_template = BasicDecode, exec_template_base = ''):
    # Make sure flags are in lists (convert to lists if not).
    mem_flags = makeList(mem_flags)
    inst_flags = makeList(inst_flags)

    iop = InstObjParams(name, Name, base_class,
                        { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
                        inst_flags)

    if mem_flags:
        mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
        iop.constructor += s

    # select templates

    # The InitiateAcc template is the same for StoreCond templates as the
    # corresponding Store template..
    StoreCondInitiateAcc = StoreInitiateAcc

    fullExecTemplate = eval(exec_template_base + 'Execute')
    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')

    # (header_output, decoder_output, decode_block, exec_output)
    return (LoadStoreDeclare.subst(iop),
            LoadStoreConstructor.subst(iop),
            decode_template.subst(iop),
            fullExecTemplate.subst(iop)
            + initiateAccTemplate.subst(iop)
            + completeAccTemplate.subst(iop))
}};

def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
                     mem_flags = [], inst_flags = []) {{
    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
                      decode_template = LoadNopCheckDecode,
                      exec_template_base = 'Load')
}};


// Note that the flags passed in apply only to the prefetch version
def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
                          mem_flags = [], pf_flags = [], inst_flags = []) {{
    # declare the load instruction object and generate the decode block
    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
                      decode_template = LoadPrefetchCheckDecode,
                      exec_template_base = 'Load')

    # Declare the prefetch instruction object.

    # Make sure flag args are lists so we can mess with them.
    mem_flags = makeList(mem_flags)
    pf_flags = makeList(pf_flags)
    inst_flags = makeList(inst_flags)

    pf_mem_flags = mem_flags + pf_flags + ['PREFETCH']
    pf_inst_flags = inst_flags

    (pf_header_output, pf_decoder_output, _, pf_exec_output) = \
        LoadStoreBase(name, Name + 'Prefetch', ea_code, ';',
                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')

    header_output += pf_header_output
    decoder_output += pf_decoder_output
    exec_output += pf_exec_output
}};


def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
                 mem_flags = [], inst_flags = []) {{
    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
                      exec_template_base = 'Store')
}};


def format StoreCond(memacc_code, postacc_code,
                     ea_code = {{ EA = Rb + disp; }},
                     mem_flags = [], inst_flags = []) {{
    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
                      postacc_code, exec_template_base = 'StoreCond')
}};


// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
def format MiscPrefetch(ea_code, memacc_code,
                        mem_flags = [], inst_flags = []) {{
    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
                      base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
}};


