// -*- 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.
//
// Authors: Steve Reinhardt
//          Korey Sewell

////////////////////////////////////////////////////////////////////
//
// 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.
        unsigned memAccessFlags;
        /// Pointer to EAComp object.
        const StaticInstPtr eaCompPtr;
        /// Pointer to MemAcc object.
        const StaticInstPtr memAccPtr;

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

        /// Constructor
        Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
               StaticInstPtr _eaCompPtr = nullStaticInstPtr,
               StaticInstPtr _memAccPtr = nullStaticInstPtr)
            : MipsStaticInst(mnem, _machInst, __opClass),
              memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
              disp(sext<16>(OFFSET))
        {
        }

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

      public:

        const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
        const StaticInstPtr &memAccInst() const { return memAccPtr; }

        unsigned memAccFlags() { return memAccessFlags; }
    };

     /**
     * Base class for a few miscellaneous memory-format insts
     * that don't interpret the disp field
     */
    class MemoryNoDisp : public Memory
    {
      protected:
        /// Constructor
        MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
                     StaticInstPtr _eaCompPtr = nullStaticInstPtr,
                     StaticInstPtr _memAccPtr = nullStaticInstPtr)
            : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
        {
        }

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


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', RT, disp, RS);
    }

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

}};

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

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

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

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

          default:
            std::cerr << "bad store data size = " << packet->getSize() << std::endl;

            assert(0);
            return 0;
        }
    }


}};

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

        /**
         * "Fake" effective address computation class for "%(mnemonic)s".
         */
        class EAComp : public %(base_class)s
        {
          public:
            /// Constructor
            EAComp(ExtMachInst machInst);

            %(BasicExecDeclare)s
        };

        /**
         * "Fake" memory access instruction class for "%(mnemonic)s".
         */
        class MemAcc : public %(base_class)s
        {
          public:
            /// Constructor
            MemAcc(ExtMachInst machInst);

            %(BasicExecDeclare)s
        };

      public:

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

        %(BasicExecDeclare)s

        %(InitiateAccDeclare)s

        %(CompleteAccDeclare)s

        %(MemAccSizeDeclare)s
    };
}};


def template InitiateAccDeclare {{
    Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};


def template CompleteAccDeclare {{
    Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
}};

def template MemAccSizeDeclare {{
    int memAccSize(%(CPU_exec_context)s *xc);
}};


def template MiscMemAccSize {{
    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
    {
        panic("Misc instruction does not support split access method!");
        return 0;
    }
}};

def template EACompConstructor {{
    /** TODO: change op_class to AddrGenOp or something (requires
     * creating new member of OpClass enum in op_class.hh, updating
     * config files, etc.). */
    inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
        : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
    {
        %(constructor)s;
    }
}};


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


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


def template EACompExecute {{
    Fault
    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *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;

        // NOTE: Trace Data is written using execute or completeAcc templates
        if (fault == NoFault) {
            xc->setEA(EA);
        }

        return fault;
    }
}};

def template LoadStoreFPEACompExecute {{
    Fault
    %(class_name)s::EAComp::execute(%(CPU_exec_context)s *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;

        // NOTE: Trace Data is written using execute or completeAcc templates
        if (fault == NoFault) {
            xc->setEA(EA);
        }

        return fault;
    }
}};


def template LoadMemAccExecute {{
    Fault
    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *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 = xc->getEA();

        fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);

        %(memacc_code)s;

        // NOTE: Write back data using execute or completeAcc templates

        return fault;
    }
}};


def template LoadExecute {{
    Fault %(class_name)s::execute(%(CPU_exec_context)s *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 = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
            %(memacc_code)s;
        }

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

        return fault;
    }
}};


def template LoadInitiateAcc {{
    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *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 = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
        }

        return fault;
    }
}};

def template LoadCompleteAcc {{
    Fault %(class_name)s::completeAcc(Packet *pkt,
                                      %(CPU_exec_context)s *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;

        Mem = pkt->get<typeof(Mem)>();

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

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

        return fault;
    }
}};


def template LoadStoreMemAccSize {{
    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
    {
        // Return the memory access size in bytes
        return (%(mem_acc_size)d / 8);
    }
}};

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

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

        EA = xc->getEA();

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

        if (fault == NoFault) {
            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
                              memAccessFlags, NULL);
            // @NOTE: Need to Call Complete Access to Set Trace Data
            //if (traceData) { traceData->setData(Mem); }
        }

        return fault;
    }
}};

def template StoreCondMemAccExecute {{
    Fault
    %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *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 = xc->getEA();

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

        if (fault == NoFault) {
            fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
                              memAccessFlags, &write_result);
            if (traceData) { traceData->setData(Mem); }
        }

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

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

        return fault;
    }
}};

def template StoreExecute {{
    Fault %(class_name)s::execute(%(CPU_exec_context)s *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 = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
                              memAccessFlags, NULL);
            if (traceData) { traceData->setData(Mem); }
        }

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

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

        return fault;
    }
}};


def template StoreFPExecute {{
    Fault %(class_name)s::execute(%(CPU_exec_context)s *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 = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
                              memAccessFlags, NULL);
            if (traceData) { traceData->setData(Mem); }
        }

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

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

        return fault;
    }
}};

def template StoreCondExecute {{
    Fault %(class_name)s::execute(%(CPU_exec_context)s *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 = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
                              memAccessFlags, &write_result);
            if (traceData) { traceData->setData(Mem); }
        }

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

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

        return fault;
    }
}};

def template StoreInitiateAcc {{
    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *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 = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
                              memAccessFlags, NULL);
            if (traceData) { traceData->setData(Mem); }
        }

        return fault;
    }
}};


def template StoreCompleteAcc {{
    Fault %(class_name)s::completeAcc(Packet *pkt,
                                      %(CPU_exec_context)s *xc,
                                      Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;

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

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

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

            if (traceData) { traceData->setData(getMemData(xc, pkt)); }
        }

        return fault;
    }
}};


def template StoreCompleteAcc {{
    Fault %(class_name)s::completeAcc(Packet *pkt,
                                      %(CPU_exec_context)s *xc,
                                      Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;

        %(op_dest_decl)s;

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

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

            if (traceData) { traceData->setData(getMemData(xc, pkt)); }
        }

        return fault;
    }
}};

def template StoreCondCompleteAcc {{
    Fault %(class_name)s::completeAcc(Packet *pkt,
                                      %(CPU_exec_context)s *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 MiscMemAccExecute {{
    Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
                                          Trace::InstRecord *traceData) const
    {
        Addr EA;
        Fault fault = NoFault;

        %(fp_enable_check)s;
        %(op_decl)s;
        %(op_rd)s;
        EA = xc->getEA();

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

        return NoFault;
    }
}};

def template MiscExecute {{
    Fault %(class_name)s::execute(%(CPU_exec_context)s *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;
        }

        return NoFault;
    }
}};

def template MiscInitiateAcc {{
    Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *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,
                                      %(CPU_exec_context)s *xc,
                                      Trace::InstRecord *traceData) const
    {
        panic("Misc instruction does not support split access method!");

        return NoFault;
    }
}};


def template MiscMemAccSize {{
    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
    {
        panic("Misc instruction does not support split access method!");
        return 0;
    }
}};

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;\n'
    decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
    decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
    decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
    decl_code += '\tbyte_offset ^= 3;\n'
    decl_code += '#endif\n'

    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;\n'
    decl_code += 'uint32_t unaligned_addr = Rs + disp;\n'
    decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n'
    decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
    decl_code += '\tbyte_offset ^= 3;\n'
    decl_code += '#endif\n'
    decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n'
    #decl_code += 'xc->readFunctional(EA,(uint32_t&)mem_word);'
    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 + ['NO_FAULT']
    pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
                                  'IsDataPrefetch', 'MemReadOp']

    (header_output, decoder_output, decode_block, exec_output) = \
        LoadStoreBase(name, Name, ea_code,
                      'xc->prefetch(EA, memAccessFlags);',
                      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')
}};
