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

// Copyright (c) 2007 MIPS Technologies, Inc.
// 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.

////////////////////////////////////////////////////////////////////
//
// Memory-format instructions
//

output header {{
    /**
     * Base class for general Mips memory-format instructions.
     */
    class Memory : public MipsStaticInst
    {
      protected:
        /// Memory request flags.  See mem_req_base.hh.
        Request::Flags memAccessFlags;

        /// Displacement for EA calculation (signed).
        int32_t disp;

        Memory(const char *mnem, MachInst _machInst, OpClass __opClass)
            : MipsStaticInst(mnem, _machInst, __opClass),
              disp(sext<16>(OFFSET))
        {
        }

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

     /**
     * Base class for a few miscellaneous memory-format insts
     * that don't interpret the disp field
     */
    class MemoryNoDisp : public Memory
    {
      protected:
        using Memory::Memory;

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


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

    std::string
    MemoryNoDisp::generateDisassembly(
            Addr pc, const Loader::SymbolTable *symtab) const
    {
        return csprintf("%-10s %c%d, r%d(r%d)", mnemonic,
                        flags[IsFloating] ? 'f' : 'r',
                        flags[IsFloating] ? FD : RD,
                        RS, RT);
    }

}};

output header {{
    uint64_t getMemData(ExecContext *xc, Packet *packet);

}};

output exec {{
    /** return data in cases where there the size of data is only
        known in the packet
    */
    uint64_t getMemData(ExecContext *xc, Packet *packet) {
        switch (packet->getSize())
        {
          case 1:
            return packet->getLE<uint8_t>();

          case 2:
            return packet->getLE<uint16_t>();

          case 4:
            return packet->getLE<uint32_t>();

          case 8:
            return packet->getLE<uint64_t>();

          default:
            panic("bad store data size = %d", packet->getSize());
            return 0;
        }
    }


}};

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(Packet *, 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;

        if (this->isFloating()) {
            %(fp_enable_check)s;

            if(fault != NoFault)
                return fault;
        }

        %(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;

        if (this->isFloating()) {
            %(fp_enable_check)s;

            if(fault != NoFault)
                return fault;
        }

        %(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(Packet *pkt, ExecContext *xc,
                                      Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;

        if (this->isFloating()) {
            %(fp_enable_check)s;

            if(fault != NoFault)
                return fault;
        }

        %(op_decl)s;
        %(op_rd)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 StoreFPExecute {{
    Fault %(class_name)s::execute(ExecContext *xc,
                                  Trace::InstRecord *traceData) const
    {
        Addr EA;
        Fault fault = NoFault;

        %(fp_enable_check)s;
        if(fault != NoFault)
          return fault;
        %(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(Packet *pkt,
                                      ExecContext *xc,
                                      Trace::InstRecord *traceData) const
    {
        return NoFault;
    }
}};

def template StoreCondCompleteAcc {{
    Fault %(class_name)s::completeAcc(Packet *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 = 0;
        Fault fault = NoFault;

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

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

        return NoFault;
    }
}};

def template MiscInitiateAcc {{
    Fault %(class_name)s::initiateAcc(ExecContext *xc,
                                      Trace::InstRecord *traceData) const
    {
        panic("Misc instruction does not support split access method!");
        return NoFault;
    }
}};


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

        return NoFault;
    }
}};

def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + 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 = ImmNopCheckDecode,
                      exec_template_base = 'Load')
}};


def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + 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 LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
                     mem_flags = [], inst_flags = []) {{
    inst_flags += ['IsIndexed']
    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
                      decode_template = ImmNopCheckDecode,
                      exec_template_base = 'Load')
}};

def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
                     mem_flags = [], inst_flags = []) {{
    inst_flags += ['IsIndexed']
    (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 LoadFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
                     mem_flags = [], inst_flags = []) {{
    inst_flags += ['IsIndexed', 'IsFloating']
    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
                      decode_template = ImmNopCheckDecode,
                      exec_template_base = 'Load')
}};

def format StoreFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
                     mem_flags = [], inst_flags = []) {{
    inst_flags += ['IsIndexed', 'IsFloating']
    (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 LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
                     mem_flags = [], inst_flags = []) {{
    decl_code = '''
        uint32_t mem_word = Mem_uw;
        uint32_t unalign_addr = Rs + disp;
        uint32_t byte_offset = unalign_addr & 3;
        if (GuestByteOrder == BigEndianByteOrder)
            byte_offset ^= 3;
    '''

    memacc_code = decl_code + memacc_code

    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
                      decode_template = ImmNopCheckDecode,
                      exec_template_base = 'Load')
}};

def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
                     mem_flags = [], inst_flags = []) {{
    decl_code = '''
        uint32_t mem_word = 0;
        uint32_t unaligned_addr = Rs + disp;
        uint32_t byte_offset = unaligned_addr & 3;
        if (GuestByteOrder == BigEndianByteOrder)
            byte_offset ^= 3;
        fault = readMemAtomicLE(xc, traceData, EA, mem_word, memAccessFlags);
    '''
    memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'

    (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 Prefetch(ea_code = {{ EA = Rs + disp; }},
                          mem_flags = [], pf_flags = [], inst_flags = []) {{
    pf_mem_flags = mem_flags + pf_flags + ['PREFETCH']
    pf_inst_flags = inst_flags

    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name, ea_code,
                      'warn_once("Prefetching not implemented for MIPS\\n");',
                      pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')

}};

def format StoreCond(memacc_code, postacc_code,
                     ea_code = {{ EA = Rs + 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')
}};
