// -*- 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 = readMemAtomicLE(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;

        getMemLE(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 = writeMemAtomicLE(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 = writeMemAtomicLE(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 = writeMemTimingLE(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')
}};


