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

// Copyright (c) 2003-2005 The Regents of The University of Michigan
// Copyright (c) 2009 The University of Edinburgh
// 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
//          Timothy M. Jones

// Some instructions ignore the contents of Ra if Ra == 0,
// so check for this.
def template CheckRaDecode {{
 {
     if (RA == 0) {
         return new %(class_name)sRaZero(machInst);
     } else {
         return new %(class_name)s(machInst);
     }
 }
}};


// Some instructions have extra behaviour if Rc is set.
def template CheckRcDecode {{
 {
     if (RC31 == 0) {
         return new %(class_name)s(machInst);
     } else {
         return new %(class_name)sRcSet(machInst);
     }
 }
}};


// Some instructions have extra behaviour if Rc and OE are set.
def template CheckRcOeDecode {{
 {
     if (RC31 == 0) {
         if (OE == 0) {
             return new %(class_name)s(machInst);
         } else {
             return new %(class_name)sOeSet(machInst);
         }
     } else {
         if (OE == 0) {
             return new %(class_name)sRcSet(machInst);
         } else {
             return new %(class_name)sRcSetOeSet(machInst);
         }
     }
 }
}};

// Branch instructions always have two versions, one which sets the link
// register (LR).
def template CheckLkDecode {{
 {
     if (LK == 0) {
         return new %(class_name)s(machInst);
     } else {
         return new %(class_name)sUpdateLr(machInst);
     }
 }
}};


let {{

def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
                  base_class = 'MemOp',
                  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)

    # Generate InstObjParams for the memory access.
    iop = InstObjParams(name, Name, base_class,
                        {'ea_code': ea_code,
                         'memacc_code': memacc_code},
                        inst_flags)

    if mem_flags:
        s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
        iop.constructor += s

    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))


# The generic ALU instruction generator. Integer and fp formats calls this
# to generate the different output sections.
def GenAluOp(name, Name, base_class, code, inst_flags, decode_template,
             constructor_template):
    iop = InstObjParams(name, Name, base_class,
                        {"code": code},
                        inst_flags)
    header_output = BasicDeclare.subst(iop)
    exec_output = BasicExecute.subst(iop)

    # We use constructors dependent on the Rc and OE bits being set
    decoder_output = constructor_template.subst(iop)

    # The decode block defines which version to use
    decode_block = decode_template.subst(iop)
    return (header_output, decoder_output, decode_block, exec_output)

}};


output header {{
    std::string
    inst2string(MachInst machInst);
}};

output decoder {{

    std::string
    inst2string(MachInst machInst)
    {
        std::string str = "";
        uint32_t mask = 0x80000000;

        for(int i=0; i < 32; i++) {
            if ((machInst & mask) == 0) {
                str += "0";
            } else {
                str += "1";
            }

            mask = mask >> 1;
        }

        return str;
    }

}};


