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

// 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 = ' + '|'.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;
    }

}};


