// -*- 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

////////////////////////////////////////////////////////////////////
//
// Alpha ISA description file.
//
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
//
// Output include file directives.
//

output header {{
#include <sstream>
#include <iostream>
#include <iomanip>

#include "arch/alpha/faults.hh"
#include "config/ss_compatible_fp.hh"
#include "cpu/static_inst.hh"
#include "mem/request.hh"  // some constructors use MemReq flags
#include "mem/packet.hh"
}};

output decoder {{
#include <cmath>

#include "base/cprintf.hh"
#include "base/fenv.hh"
#include "base/loader/symtab.hh"
#include "config/ss_compatible_fp.hh"
#include "cpu/thread_context.hh"  // for Jump::branchTarget()
#include "mem/packet.hh"

using namespace AlphaISA;
}};

output exec {{
#include <math.h>

#if FULL_SYSTEM
#include "sim/pseudo_inst.hh"
#endif
#include "arch/alpha/ipr.hh"
#include "base/fenv.hh"
#include "config/ss_compatible_fp.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "sim/sim_exit.hh"

using namespace AlphaISA;
}};

////////////////////////////////////////////////////////////////////
//
// Namespace statement.  Everything below this line will be in the
// AlphaISAInst namespace.
//


namespace AlphaISA;

////////////////////////////////////////////////////////////////////
//
// Bitfield definitions.
//

// Universal (format-independent) fields
def bitfield PALMODE    <32:32>;
def bitfield OPCODE	<31:26>;
def bitfield RA		<25:21>;
def bitfield RB		<20:16>;

// Memory format
def signed bitfield MEMDISP <15: 0>; // displacement
def        bitfield MEMFUNC <15: 0>; // function code (same field, unsigned)

// Memory-format jumps
def bitfield JMPFUNC	<15:14>; // function code (disp<15:14>)
def bitfield JMPHINT	<13: 0>; // tgt Icache idx hint (disp<13:0>)

// Branch format
def signed bitfield BRDISP <20: 0>; // displacement

// Integer operate format(s>;
def bitfield INTIMM	<20:13>; // integer immediate (literal)
def bitfield IMM	<12:12>; // immediate flag
def bitfield INTFUNC	<11: 5>; // function code
def bitfield RC		< 4: 0>; // dest reg

// Floating-point operate format
def bitfield FA		  <25:21>;
def bitfield FB		  <20:16>;
def bitfield FP_FULLFUNC  <15: 5>; // complete function code
    def bitfield FP_TRAPMODE  <15:13>; // trapping mode
    def bitfield FP_ROUNDMODE <12:11>; // rounding mode
    def bitfield FP_TYPEFUNC  <10: 5>; // type+func: handiest for decoding
        def bitfield FP_SRCTYPE   <10: 9>; // source reg type
        def bitfield FP_SHORTFUNC < 8: 5>; // short function code
        def bitfield FP_SHORTFUNC_TOP2 <8:7>; // top 2 bits of short func code
def bitfield FC		  < 4: 0>; // dest reg

// PALcode format
def bitfield PALFUNC	<25: 0>; // function code

// EV5 PAL instructions:
// HW_LD/HW_ST
def bitfield HW_LDST_PHYS  <15>; // address is physical
def bitfield HW_LDST_ALT   <14>; // use ALT_MODE IPR
def bitfield HW_LDST_WRTCK <13>; // HW_LD only: fault if no write acc
def bitfield HW_LDST_QUAD  <12>; // size: 0=32b, 1=64b
def bitfield HW_LDST_VPTE  <11>; // HW_LD only: is PTE fetch
def bitfield HW_LDST_LOCK  <10>; // HW_LD only: is load locked
def bitfield HW_LDST_COND  <10>; // HW_ST only: is store conditional
def signed bitfield HW_LDST_DISP  <9:0>; // signed displacement

// HW_REI
def bitfield HW_REI_TYP <15:14>; // type: stalling vs. non-stallingk
def bitfield HW_REI_MBZ <13: 0>; // must be zero

// HW_MTPR/MW_MFPR
def bitfield HW_IPR_IDX <15:0>;	 // IPR index

// M5 instructions
def bitfield M5FUNC <7:0>;

def operand_types {{
    'sb' : ('signed int', 8),
    'ub' : ('unsigned int', 8),
    'sw' : ('signed int', 16),
    'uw' : ('unsigned int', 16),
    'sl' : ('signed int', 32),
    'ul' : ('unsigned int', 32),
    'sq' : ('signed int', 64),
    'uq' : ('unsigned int', 64),
    'sf' : ('float', 32),
    'df' : ('float', 64)
}};

def operands {{
    # Int regs default to unsigned, but code should not count on this.
    # For clarity, descriptions that depend on unsigned behavior should
    # explicitly specify '.uq'.
    'Ra': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RA] : RA',
           'IsInteger', 1),
    'Rb': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RB] : RB',
           'IsInteger', 2),
    'Rc': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RC] : RC',
           'IsInteger', 3),
    'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1),
    'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2),
    'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3),
    'Mem': ('Mem', 'uq', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
    'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4),
    'Runiq': ('ControlReg', 'uq', 'MISCREG_UNIQ', None, 1),
    'FPCR':  ('ControlReg', 'uq', 'MISCREG_FPCR', None, 1),
    'IntrFlag': ('ControlReg', 'uq', 'MISCREG_INTR', None, 1),
    # The next two are hacks for non-full-system call-pal emulation
    'R0':  ('IntReg', 'uq', '0', None, 1),
    'R16': ('IntReg', 'uq', '16', None, 1),
    'R17': ('IntReg', 'uq', '17', None, 1),
    'R18': ('IntReg', 'uq', '18', None, 1)
}};

////////////////////////////////////////////////////////////////////
//
// Basic instruction classes/templates/formats etc.
//

output header {{
// uncomment the following to get SimpleScalar-compatible disassembly
// (useful for diffing output traces).
// #define SS_COMPATIBLE_DISASSEMBLY

    /**
     * Base class for all Alpha static instructions.
     */
    class AlphaStaticInst : public StaticInst
    {
      protected:

        /// Make AlphaISA register dependence tags directly visible in
        /// this class and derived classes.  Maybe these should really
        /// live here and not in the AlphaISA namespace.
        enum DependenceTags {
            FP_Base_DepTag = AlphaISA::FP_Base_DepTag,
        };

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

        /// Print a register name for disassembly given the unique
        /// dependence tag number (FP or int).
        void printReg(std::ostream &os, int reg) const;

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

output decoder {{
    void
    AlphaStaticInst::printReg(std::ostream &os, int reg) const
    {
        if (reg < FP_Base_DepTag) {
            ccprintf(os, "r%d", reg);
        }
        else {
            ccprintf(os, "f%d", reg - FP_Base_DepTag);
        }
    }

    std::string
    AlphaStaticInst::generateDisassembly(Addr pc,
                                         const SymbolTable *symtab) const
    {
        std::stringstream ss;

        ccprintf(ss, "%-10s ", mnemonic);

        // just print the first two source regs... if there's
        // a third one, it's a read-modify-write dest (Rc),
        // e.g. for CMOVxx
        if (_numSrcRegs > 0) {
            printReg(ss, _srcRegIdx[0]);
        }
        if (_numSrcRegs > 1) {
            ss << ",";
            printReg(ss, _srcRegIdx[1]);
        }

        // just print the first dest... if there's a second one,
        // it's generally implicit
        if (_numDestRegs > 0) {
            if (_numSrcRegs > 0)
                ss << ",";
            printReg(ss, _destRegIdx[0]);
        }

        return ss.str();
    }
}};

// Declarations for execute() methods.
def template BasicExecDeclare {{
    Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};

// Basic instruction class declaration template.
def template BasicDeclare {{
    /**
     * Static instruction class for "%(mnemonic)s".
     */
    class %(class_name)s : public %(base_class)s
    {
      public:
        /// Constructor.
        %(class_name)s(ExtMachInst machInst);

        %(BasicExecDeclare)s
    };
}};

// Basic instruction class constructor template.
def template BasicConstructor {{
    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
         : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
    {
        %(constructor)s;
    }
}};

// Basic instruction class execute method template.
def template BasicExecute {{
    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
                                  Trace::InstRecord *traceData) const
    {
        Fault fault = NoFault;

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

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

        return fault;
    }
}};

// Basic decode template.
def template BasicDecode {{
    return new %(class_name)s(machInst);
}};

// Basic decode template, passing mnemonic in as string arg to constructor.
def template BasicDecodeWithMnemonic {{
    return new %(class_name)s("%(mnemonic)s", machInst);
}};

// The most basic instruction format... used only for a few misc. insts
def format BasicOperate(code, *flags) {{
    iop = InstObjParams(name, Name, 'AlphaStaticInst', code, flags)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    decode_block = BasicDecode.subst(iop)
    exec_output = BasicExecute.subst(iop)
}};



////////////////////////////////////////////////////////////////////
//
// Nop
//

output header {{
    /**
     * Static instruction class for no-ops.  This is a leaf class.
     */
    class Nop : public AlphaStaticInst
    {
        /// Disassembly of original instruction.
        const std::string originalDisassembly;

      public:
        /// Constructor
        Nop(const std::string _originalDisassembly, ExtMachInst _machInst)
            : AlphaStaticInst("nop", _machInst, No_OpClass),
              originalDisassembly(_originalDisassembly)
        {
            flags[IsNop] = true;
        }

        ~Nop() { }

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

        %(BasicExecDeclare)s
    };

    /// Helper function for decoding nops.  Substitute Nop object
    /// for original inst passed in as arg (and delete latter).
    static inline
    AlphaStaticInst *
    makeNop(AlphaStaticInst *inst)
    {
        AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst);
        delete inst;
        return nop;
    }
}};

output decoder {{
    std::string Nop::generateDisassembly(Addr pc,
                                         const SymbolTable *symtab) const
    {
#ifdef SS_COMPATIBLE_DISASSEMBLY
        return originalDisassembly;
#else
        return csprintf("%-10s (%s)", "nop", originalDisassembly);
#endif
    }
}};

output exec {{
    Fault
    Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
    {
        return NoFault;
    }
}};

// integer & FP operate instructions use Rc as dest, so check for
// Rc == 31 to detect nops
def template OperateNopCheckDecode {{
 {
     AlphaStaticInst *i = new %(class_name)s(machInst);
     if (RC == 31) {
         i = makeNop(i);
     }
     return i;
 }
}};

// Like BasicOperate format, but generates NOP if RC/FC == 31
def format BasicOperateWithNopCheck(code, *opt_args) {{
    iop = InstObjParams(name, Name, 'AlphaStaticInst', code, opt_args)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    decode_block = OperateNopCheckDecode.subst(iop)
    exec_output = BasicExecute.subst(iop)
}};

// Integer instruction templates, formats, etc.
##include "int.isa"

// Floating-point instruction templates, formats, etc.
##include "fp.isa"

// Memory instruction templates, formats, etc.
##include "mem.isa"

// Branch/jump instruction templates, formats, etc.
##include "branch.isa"

// PAL instruction templates, formats, etc.
##include "pal.isa"

// Opcdec fault instruction templates, formats, etc.
##include "opcdec.isa"

// Unimplemented instruction templates, formats, etc.
##include "unimp.isa"

// Unknown instruction templates, formats, etc.
##include "unknown.isa"

// Execution utility functions
##include "util.isa"

// The actual decoder
##include "decoder.isa"
