12089SN/A// -*- mode:c++ -*-
22089SN/A
35268Sksewell@umich.edu// Copyright (c) 2007 MIPS Technologies, Inc.
45268Sksewell@umich.edu// All rights reserved.
55268Sksewell@umich.edu//
65268Sksewell@umich.edu// Redistribution and use in source and binary forms, with or without
75268Sksewell@umich.edu// modification, are permitted provided that the following conditions are
85268Sksewell@umich.edu// met: redistributions of source code must retain the above copyright
95268Sksewell@umich.edu// notice, this list of conditions and the following disclaimer;
105268Sksewell@umich.edu// redistributions in binary form must reproduce the above copyright
115268Sksewell@umich.edu// notice, this list of conditions and the following disclaimer in the
125268Sksewell@umich.edu// documentation and/or other materials provided with the distribution;
135268Sksewell@umich.edu// neither the name of the copyright holders nor the names of its
145268Sksewell@umich.edu// contributors may be used to endorse or promote products derived from
155268Sksewell@umich.edu// this software without specific prior written permission.
165268Sksewell@umich.edu//
175268Sksewell@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
185268Sksewell@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
195268Sksewell@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
205268Sksewell@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
215268Sksewell@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
225268Sksewell@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
235268Sksewell@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
245268Sksewell@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
255268Sksewell@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
265268Sksewell@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
275268Sksewell@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
285268Sksewell@umich.edu//
295268Sksewell@umich.edu// Authors: Korey Sewell
302706Sksewell@umich.edu
312022SN/A////////////////////////////////////////////////////////////////////
322022SN/A//
332022SN/A// Integer operate instructions
342022SN/A//
352022SN/Aoutput header {{
362239SN/A#include <iostream>
374661Sksewell@umich.edu    using namespace std;
382022SN/A        /**
392022SN/A         * Base class for integer operations.
402022SN/A         */
412041SN/A        class IntOp : public MipsStaticInst
422022SN/A        {
432022SN/A                protected:
442022SN/A
452022SN/A                /// Constructor
462089SN/A                IntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
472044SN/A                                MipsStaticInst(mnem, _machInst, __opClass)
482044SN/A                {
492044SN/A                }
502044SN/A
5112616Sgabeblack@google.com                std::string generateDisassembly(
5212616Sgabeblack@google.com                        Addr pc, const SymbolTable *symtab) const override;
532044SN/A        };
542044SN/A
552686Sksewell@umich.edu
562686Sksewell@umich.edu        class HiLoOp: public IntOp
572686Sksewell@umich.edu        {
582686Sksewell@umich.edu                protected:
592686Sksewell@umich.edu
602686Sksewell@umich.edu                /// Constructor
612686Sksewell@umich.edu                HiLoOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
622686Sksewell@umich.edu                                IntOp(mnem, _machInst, __opClass)
632686Sksewell@umich.edu                {
642686Sksewell@umich.edu                }
652686Sksewell@umich.edu
6612616Sgabeblack@google.com                std::string generateDisassembly(
6712616Sgabeblack@google.com                        Addr pc, const SymbolTable *symtab) const override;
682686Sksewell@umich.edu        };
692686Sksewell@umich.edu
704661Sksewell@umich.edu        class HiLoRsSelOp: public HiLoOp
712686Sksewell@umich.edu        {
722686Sksewell@umich.edu                protected:
732686Sksewell@umich.edu
742686Sksewell@umich.edu                /// Constructor
754661Sksewell@umich.edu                HiLoRsSelOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
762686Sksewell@umich.edu                                HiLoOp(mnem, _machInst, __opClass)
772686Sksewell@umich.edu                {
782686Sksewell@umich.edu                }
792686Sksewell@umich.edu
8012616Sgabeblack@google.com                std::string generateDisassembly(
8112616Sgabeblack@google.com                        Addr pc, const SymbolTable *symtab) const override;
822686Sksewell@umich.edu        };
832686Sksewell@umich.edu
844661Sksewell@umich.edu        class HiLoRdSelOp: public HiLoOp
854661Sksewell@umich.edu        {
864661Sksewell@umich.edu                protected:
874661Sksewell@umich.edu
884661Sksewell@umich.edu                /// Constructor
894661Sksewell@umich.edu                HiLoRdSelOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
904661Sksewell@umich.edu                                HiLoOp(mnem, _machInst, __opClass)
914661Sksewell@umich.edu                {
924661Sksewell@umich.edu                }
934661Sksewell@umich.edu
9412616Sgabeblack@google.com                std::string generateDisassembly(
9512616Sgabeblack@google.com                        Addr pc, const SymbolTable *symtab) const override;
964661Sksewell@umich.edu        };
974661Sksewell@umich.edu
984661Sksewell@umich.edu        class HiLoRdSelValOp: public HiLoOp
994661Sksewell@umich.edu        {
1004661Sksewell@umich.edu                protected:
1014661Sksewell@umich.edu
1024661Sksewell@umich.edu                /// Constructor
1034661Sksewell@umich.edu                HiLoRdSelValOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
1044661Sksewell@umich.edu                                HiLoOp(mnem, _machInst, __opClass)
1054661Sksewell@umich.edu                {
1064661Sksewell@umich.edu                }
1074661Sksewell@umich.edu
10812616Sgabeblack@google.com                std::string generateDisassembly(
10912616Sgabeblack@google.com                        Addr pc, const SymbolTable *symtab) const override;
1104661Sksewell@umich.edu        };
1112686Sksewell@umich.edu
1122044SN/A        class IntImmOp : public MipsStaticInst
1132044SN/A        {
1142044SN/A                protected:
1152239SN/A
1162495SN/A                int16_t imm;
1172495SN/A                int32_t sextImm;
1182495SN/A                uint32_t zextImm;
1192044SN/A
1202044SN/A                /// Constructor
1212089SN/A                IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
1222495SN/A                    MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM),
1232495SN/A                    sextImm(INTIMM),zextImm(0x0000FFFF & INTIMM)
1242022SN/A                {
1252239SN/A                    //If Bit 15 is 1 then Sign Extend
1262495SN/A                    int32_t temp = sextImm & 0x00008000;
1275269Sksewell@umich.edu                    if (temp > 0 && strcmp(mnemonic,"lui") != 0) {
1282495SN/A                        sextImm |= 0xFFFF0000;
1292239SN/A                    }
1302022SN/A                }
1312022SN/A
13212616Sgabeblack@google.com                std::string generateDisassembly(
13312616Sgabeblack@google.com                        Addr pc, const SymbolTable *symtab) const override;
1342022SN/A        };
1352041SN/A
1362022SN/A}};
1372022SN/A
1384661Sksewell@umich.edu// HiLo instruction class execute method template.
1392686Sksewell@umich.edudef template HiLoExecute {{
14012234Sgabeblack@google.com        Fault %(class_name)s::execute(
14112234Sgabeblack@google.com            ExecContext *xc, Trace::InstRecord *traceData) const
1422686Sksewell@umich.edu        {
1432686Sksewell@umich.edu                Fault fault = NoFault;
1442686Sksewell@umich.edu
1452686Sksewell@umich.edu                %(fp_enable_check)s;
1462686Sksewell@umich.edu                %(op_decl)s;
1472686Sksewell@umich.edu                %(op_rd)s;
1482686Sksewell@umich.edu                %(code)s;
1492686Sksewell@umich.edu
1502686Sksewell@umich.edu                if(fault == NoFault)
1512686Sksewell@umich.edu                {
1522686Sksewell@umich.edu                    %(op_wb)s;
1534661Sksewell@umich.edu                }
1544661Sksewell@umich.edu                return fault;
1554661Sksewell@umich.edu        }
1564661Sksewell@umich.edu}};
1574661Sksewell@umich.edu
1584661Sksewell@umich.edu// HiLoRsSel instruction class execute method template.
1594661Sksewell@umich.edudef template HiLoRsSelExecute {{
16012234Sgabeblack@google.com        Fault %(class_name)s::execute(
16112234Sgabeblack@google.com            ExecContext *xc, Trace::InstRecord *traceData) const
1624661Sksewell@umich.edu        {
1634661Sksewell@umich.edu                Fault fault = NoFault;
1644661Sksewell@umich.edu
1654661Sksewell@umich.edu                %(op_decl)s;
1664661Sksewell@umich.edu
1674661Sksewell@umich.edu                if( ACSRC > 0 && !isDspEnabled(xc) )
1684661Sksewell@umich.edu                {
16910474Sandreas.hansson@arm.com                    fault = std::make_shared<DspStateDisabledFault>();
1704661Sksewell@umich.edu                }
1714661Sksewell@umich.edu                else
1724661Sksewell@umich.edu                {
1734661Sksewell@umich.edu                    %(op_rd)s;
1744661Sksewell@umich.edu                    %(code)s;
1754661Sksewell@umich.edu                }
1764661Sksewell@umich.edu
1774661Sksewell@umich.edu                if(fault == NoFault)
1784661Sksewell@umich.edu                {
1794661Sksewell@umich.edu                    %(op_wb)s;
1804661Sksewell@umich.edu                }
1814661Sksewell@umich.edu                return fault;
1824661Sksewell@umich.edu        }
1834661Sksewell@umich.edu}};
1844661Sksewell@umich.edu
1854661Sksewell@umich.edu// HiLoRdSel instruction class execute method template.
1864661Sksewell@umich.edudef template HiLoRdSelExecute {{
18712234Sgabeblack@google.com        Fault %(class_name)s::execute(
18812234Sgabeblack@google.com            ExecContext *xc, Trace::InstRecord *traceData) const
1894661Sksewell@umich.edu        {
1904661Sksewell@umich.edu                Fault fault = NoFault;
1914661Sksewell@umich.edu
1924661Sksewell@umich.edu                %(op_decl)s;
1934661Sksewell@umich.edu
1944661Sksewell@umich.edu                if( ACDST > 0 && !isDspEnabled(xc) )
1954661Sksewell@umich.edu                {
19610474Sandreas.hansson@arm.com                    fault = std::make_shared<DspStateDisabledFault>();
1974661Sksewell@umich.edu                }
1984661Sksewell@umich.edu                else
1994661Sksewell@umich.edu                {
2004661Sksewell@umich.edu                    %(op_rd)s;
2014661Sksewell@umich.edu                    %(code)s;
2024661Sksewell@umich.edu                }
2034661Sksewell@umich.edu
2044661Sksewell@umich.edu                if(fault == NoFault)
2054661Sksewell@umich.edu                {
2064661Sksewell@umich.edu                    %(op_wb)s;
2072686Sksewell@umich.edu                }
2082686Sksewell@umich.edu                return fault;
2092686Sksewell@umich.edu        }
2102686Sksewell@umich.edu}};
2112686Sksewell@umich.edu
2122089SN/A//Outputs to decoder.cc
2132022SN/Aoutput decoder {{
2142041SN/A        std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
2152022SN/A        {
2162239SN/A            std::stringstream ss;
2172239SN/A
2182239SN/A            ccprintf(ss, "%-10s ", mnemonic);
2192239SN/A
2202239SN/A            // just print the first dest... if there's a second one,
2212239SN/A            // it's generally implicit
2222239SN/A            if (_numDestRegs > 0) {
2232239SN/A                printReg(ss, _destRegIdx[0]);
2242686Sksewell@umich.edu                ss << ", ";
2252239SN/A            }
2262239SN/A
2272239SN/A            // just print the first two source regs... if there's
2282239SN/A            // a third one, it's a read-modify-write dest (Rc),
2292239SN/A            // e.g. for CMOVxx
2302239SN/A            if (_numSrcRegs > 0) {
2312239SN/A                printReg(ss, _srcRegIdx[0]);
2322239SN/A            }
2332239SN/A
2342239SN/A            if (_numSrcRegs > 1) {
2352686Sksewell@umich.edu                ss << ", ";
2362239SN/A                printReg(ss, _srcRegIdx[1]);
2372239SN/A            }
2382239SN/A
2392239SN/A            return ss.str();
2402022SN/A        }
2412041SN/A
2422686Sksewell@umich.edu        std::string HiLoOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
2432686Sksewell@umich.edu        {
2442686Sksewell@umich.edu            std::stringstream ss;
2452686Sksewell@umich.edu
2462686Sksewell@umich.edu            ccprintf(ss, "%-10s ", mnemonic);
2472686Sksewell@umich.edu
2482686Sksewell@umich.edu            //Destination Registers are implicit for HI/LO ops
2492686Sksewell@umich.edu            if (_numSrcRegs > 0) {
2502686Sksewell@umich.edu                printReg(ss, _srcRegIdx[0]);
2512686Sksewell@umich.edu            }
2522686Sksewell@umich.edu
2532686Sksewell@umich.edu            if (_numSrcRegs > 1) {
2542686Sksewell@umich.edu                ss << ", ";
2552686Sksewell@umich.edu                printReg(ss, _srcRegIdx[1]);
2562686Sksewell@umich.edu            }
2572686Sksewell@umich.edu
2582686Sksewell@umich.edu            return ss.str();
2592686Sksewell@umich.edu        }
2602686Sksewell@umich.edu
2614661Sksewell@umich.edu        std::string HiLoRsSelOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
2624661Sksewell@umich.edu        {
2634661Sksewell@umich.edu            std::stringstream ss;
2644661Sksewell@umich.edu
2654661Sksewell@umich.edu            ccprintf(ss, "%-10s ", mnemonic);
2664661Sksewell@umich.edu
26712106SRekai.GonzalezAlberquilla@arm.com            if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) {
2684661Sksewell@umich.edu                printReg(ss, _destRegIdx[0]);
26912106SRekai.GonzalezAlberquilla@arm.com            } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) {
2704661Sksewell@umich.edu                printReg(ss, _srcRegIdx[0]);
2714661Sksewell@umich.edu            }
2724661Sksewell@umich.edu
2734661Sksewell@umich.edu            return ss.str();
2744661Sksewell@umich.edu        }
2754661Sksewell@umich.edu
2764661Sksewell@umich.edu        std::string HiLoRdSelOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
2774661Sksewell@umich.edu        {
2784661Sksewell@umich.edu            std::stringstream ss;
2794661Sksewell@umich.edu
2804661Sksewell@umich.edu            ccprintf(ss, "%-10s ", mnemonic);
2814661Sksewell@umich.edu
28212106SRekai.GonzalezAlberquilla@arm.com            if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) {
2834661Sksewell@umich.edu                printReg(ss, _destRegIdx[0]);
28412106SRekai.GonzalezAlberquilla@arm.com            } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) {
2854661Sksewell@umich.edu                printReg(ss, _srcRegIdx[0]);
2864661Sksewell@umich.edu            }
2874661Sksewell@umich.edu
2884661Sksewell@umich.edu            return ss.str();
2894661Sksewell@umich.edu        }
2904661Sksewell@umich.edu
2914661Sksewell@umich.edu        std::string HiLoRdSelValOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
2922686Sksewell@umich.edu        {
2932686Sksewell@umich.edu            std::stringstream ss;
2942686Sksewell@umich.edu
2952686Sksewell@umich.edu            ccprintf(ss, "%-10s ", mnemonic);
2962686Sksewell@umich.edu
29712106SRekai.GonzalezAlberquilla@arm.com            if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) {
2982686Sksewell@umich.edu                printReg(ss, _destRegIdx[0]);
29912106SRekai.GonzalezAlberquilla@arm.com            } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) {
3002686Sksewell@umich.edu                printReg(ss, _srcRegIdx[0]);
3012686Sksewell@umich.edu            }
3022686Sksewell@umich.edu
3032686Sksewell@umich.edu            return ss.str();
3042686Sksewell@umich.edu        }
3052686Sksewell@umich.edu
3062043SN/A        std::string IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
3072041SN/A        {
3082239SN/A            std::stringstream ss;
3092239SN/A
3102239SN/A            ccprintf(ss, "%-10s ", mnemonic);
3112239SN/A
3122239SN/A            if (_numDestRegs > 0) {
3132239SN/A                printReg(ss, _destRegIdx[0]);
3142239SN/A            }
3152239SN/A
3162686Sksewell@umich.edu            ss << ", ";
3172239SN/A
3182239SN/A            if (_numSrcRegs > 0) {
3192239SN/A                printReg(ss, _srcRegIdx[0]);
3202686Sksewell@umich.edu                ss << ", ";
3212239SN/A            }
3222239SN/A
3235269Sksewell@umich.edu            if(strcmp(mnemonic,"lui") == 0)
3242686Sksewell@umich.edu                ccprintf(ss, "0x%x ", sextImm);
3252239SN/A            else
3262495SN/A                ss << (int) sextImm;
3272239SN/A
3282239SN/A            return ss.str();
3292041SN/A        }
3302239SN/A
3312022SN/A}};
3322022SN/A
3332043SN/Adef format IntOp(code, *opt_flags) {{
3343951Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'IntOp', code, opt_flags)
3352686Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
3362686Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
3372750Sksewell@umich.edu    decode_block = RegNopCheckDecode.subst(iop)
3382686Sksewell@umich.edu    exec_output = BasicExecute.subst(iop)
3392022SN/A}};
3402022SN/A
3412686Sksewell@umich.edudef format IntImmOp(code, *opt_flags) {{
3423951Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'IntImmOp', code, opt_flags)
3432686Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
3442686Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
3452750Sksewell@umich.edu    decode_block = ImmNopCheckDecode.subst(iop)
3462686Sksewell@umich.edu    exec_output = BasicExecute.subst(iop)
3472686Sksewell@umich.edu}};
3482044SN/A
3494661Sksewell@umich.edudef format HiLoRsSelOp(code, *opt_flags) {{
3504661Sksewell@umich.edu    iop = InstObjParams(name, Name, 'HiLoRsSelOp', code, opt_flags)
3514661Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
3524661Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
3534661Sksewell@umich.edu    decode_block = BasicDecode.subst(iop)
3544661Sksewell@umich.edu    exec_output = HiLoRsSelExecute.subst(iop)
3554661Sksewell@umich.edu}};
3564661Sksewell@umich.edu
3574661Sksewell@umich.edudef format HiLoRdSelOp(code, *opt_flags) {{
3584661Sksewell@umich.edu    iop = InstObjParams(name, Name, 'HiLoRdSelOp', code, opt_flags)
3594661Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
3604661Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
3614661Sksewell@umich.edu    decode_block = BasicDecode.subst(iop)
3624661Sksewell@umich.edu    exec_output = HiLoRdSelExecute.subst(iop)
3634661Sksewell@umich.edu}};
3644661Sksewell@umich.edu
3654661Sksewell@umich.edudef format HiLoRdSelValOp(code, *opt_flags) {{
3664661Sksewell@umich.edu
3678588Sgblack@eecs.umich.edu    if '_sd' in code:
3684661Sksewell@umich.edu        code = 'int64_t ' + code
3698588Sgblack@eecs.umich.edu    elif '_ud' in code:
3704661Sksewell@umich.edu        code = 'uint64_t ' + code
3714661Sksewell@umich.edu
3724661Sksewell@umich.edu    code += 'HI_RD_SEL = val<63:32>;\n'
3734661Sksewell@umich.edu    code += 'LO_RD_SEL = val<31:0>;\n'
3744661Sksewell@umich.edu
3754661Sksewell@umich.edu    iop = InstObjParams(name, Name, 'HiLoRdSelOp', code, opt_flags)
3764661Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
3774661Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
3784661Sksewell@umich.edu    decode_block = BasicDecode.subst(iop)
3794661Sksewell@umich.edu    exec_output = HiLoRdSelExecute.subst(iop)
3804661Sksewell@umich.edu}};
3814661Sksewell@umich.edu
3822686Sksewell@umich.edudef format HiLoOp(code, *opt_flags) {{
3833951Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'HiLoOp', code, opt_flags)
3842686Sksewell@umich.edu    header_output = BasicDeclare.subst(iop)
3852686Sksewell@umich.edu    decoder_output = BasicConstructor.subst(iop)
3862750Sksewell@umich.edu    decode_block = BasicDecode.subst(iop)
3872686Sksewell@umich.edu    exec_output = HiLoExecute.subst(iop)
3882686Sksewell@umich.edu}};
389