pred.isa revision 6243
16019Shines@cs.fsu.edu// -*- mode:c++ -*-
26019Shines@cs.fsu.edu
36019Shines@cs.fsu.edu// Copyright (c) 2007-2008 The Florida State University
46019Shines@cs.fsu.edu// All rights reserved.
56019Shines@cs.fsu.edu//
66019Shines@cs.fsu.edu// Redistribution and use in source and binary forms, with or without
76019Shines@cs.fsu.edu// modification, are permitted provided that the following conditions are
86019Shines@cs.fsu.edu// met: redistributions of source code must retain the above copyright
96019Shines@cs.fsu.edu// notice, this list of conditions and the following disclaimer;
106019Shines@cs.fsu.edu// redistributions in binary form must reproduce the above copyright
116019Shines@cs.fsu.edu// notice, this list of conditions and the following disclaimer in the
126019Shines@cs.fsu.edu// documentation and/or other materials provided with the distribution;
136019Shines@cs.fsu.edu// neither the name of the copyright holders nor the names of its
146019Shines@cs.fsu.edu// contributors may be used to endorse or promote products derived from
156019Shines@cs.fsu.edu// this software without specific prior written permission.
166019Shines@cs.fsu.edu//
176019Shines@cs.fsu.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186019Shines@cs.fsu.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196019Shines@cs.fsu.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206019Shines@cs.fsu.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216019Shines@cs.fsu.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226019Shines@cs.fsu.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236019Shines@cs.fsu.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246019Shines@cs.fsu.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256019Shines@cs.fsu.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266019Shines@cs.fsu.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276019Shines@cs.fsu.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286019Shines@cs.fsu.edu//
296019Shines@cs.fsu.edu// Authors: Stephen Hines
306019Shines@cs.fsu.edu
316019Shines@cs.fsu.edu////////////////////////////////////////////////////////////////////
326019Shines@cs.fsu.edu//
336019Shines@cs.fsu.edu// Predicated Instruction Execution
346019Shines@cs.fsu.edu//
356019Shines@cs.fsu.edu
366019Shines@cs.fsu.eduoutput header {{
376019Shines@cs.fsu.edu#include <iostream>
386019Shines@cs.fsu.edu
396019Shines@cs.fsu.edu    inline uint32_t
406019Shines@cs.fsu.edu    rotate_imm(uint32_t immValue, uint32_t rotateValue)
416019Shines@cs.fsu.edu    {
426019Shines@cs.fsu.edu        return ((immValue >> (int)(rotateValue & 31)) |
436019Shines@cs.fsu.edu                (immValue << (32 - (int)(rotateValue & 31))));
446019Shines@cs.fsu.edu    }
456019Shines@cs.fsu.edu
466019Shines@cs.fsu.edu    /**
476019Shines@cs.fsu.edu     * Base class for predicated integer operations.
486019Shines@cs.fsu.edu     */
496019Shines@cs.fsu.edu    class PredOp : public ArmStaticInst
506019Shines@cs.fsu.edu    {
516242Sgblack@eecs.umich.edu      protected:
526019Shines@cs.fsu.edu
536242Sgblack@eecs.umich.edu        ArmISA::ConditionCode condCode;
546019Shines@cs.fsu.edu
556242Sgblack@eecs.umich.edu        /// Constructor
566242Sgblack@eecs.umich.edu        PredOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
576242Sgblack@eecs.umich.edu                        ArmStaticInst(mnem, _machInst, __opClass),
586242Sgblack@eecs.umich.edu                        condCode((ArmISA::ConditionCode)COND_CODE)
596242Sgblack@eecs.umich.edu        {
606242Sgblack@eecs.umich.edu        }
616019Shines@cs.fsu.edu
626242Sgblack@eecs.umich.edu        std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
636019Shines@cs.fsu.edu    };
646019Shines@cs.fsu.edu
656019Shines@cs.fsu.edu    /**
666019Shines@cs.fsu.edu     * Base class for predicated immediate operations.
676019Shines@cs.fsu.edu     */
686019Shines@cs.fsu.edu    class PredImmOp : public PredOp
696019Shines@cs.fsu.edu    {
706019Shines@cs.fsu.edu            protected:
716019Shines@cs.fsu.edu
726019Shines@cs.fsu.edu            uint32_t imm;
736019Shines@cs.fsu.edu            uint32_t rotate;
746019Shines@cs.fsu.edu            uint32_t rotated_imm;
756019Shines@cs.fsu.edu            uint32_t rotated_carry;
766019Shines@cs.fsu.edu
776019Shines@cs.fsu.edu            /// Constructor
786019Shines@cs.fsu.edu            PredImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
796019Shines@cs.fsu.edu                            PredOp(mnem, _machInst, __opClass),
806019Shines@cs.fsu.edu                            imm(IMM), rotate(ROTATE << 1), rotated_imm(0),
816019Shines@cs.fsu.edu                            rotated_carry(0)
826019Shines@cs.fsu.edu            {
836019Shines@cs.fsu.edu                rotated_imm = rotate_imm(imm, rotate);
846019Shines@cs.fsu.edu                if (rotate != 0)
856019Shines@cs.fsu.edu                    rotated_carry = (rotated_imm >> 31) & 1;
866019Shines@cs.fsu.edu            }
876019Shines@cs.fsu.edu
886019Shines@cs.fsu.edu            std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
896019Shines@cs.fsu.edu    };
906019Shines@cs.fsu.edu
916019Shines@cs.fsu.edu    /**
926019Shines@cs.fsu.edu     * Base class for predicated integer operations.
936019Shines@cs.fsu.edu     */
946019Shines@cs.fsu.edu    class PredIntOp : public PredOp
956019Shines@cs.fsu.edu    {
966019Shines@cs.fsu.edu            protected:
976019Shines@cs.fsu.edu
986019Shines@cs.fsu.edu            uint32_t shift_size;
996019Shines@cs.fsu.edu            uint32_t shift;
1006019Shines@cs.fsu.edu
1016019Shines@cs.fsu.edu            /// Constructor
1026019Shines@cs.fsu.edu            PredIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
1036019Shines@cs.fsu.edu                            PredOp(mnem, _machInst, __opClass),
1046019Shines@cs.fsu.edu                            shift_size(SHIFT_SIZE), shift(SHIFT)
1056019Shines@cs.fsu.edu            {
1066019Shines@cs.fsu.edu            }
1076019Shines@cs.fsu.edu
1086019Shines@cs.fsu.edu            std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1096019Shines@cs.fsu.edu    };
1106019Shines@cs.fsu.edu
1116019Shines@cs.fsu.edu    /**
1126019Shines@cs.fsu.edu     * Base class for predicated macro-operations.
1136019Shines@cs.fsu.edu     */
1146019Shines@cs.fsu.edu    class PredMacroOp : public PredOp
1156019Shines@cs.fsu.edu    {
1166019Shines@cs.fsu.edu            protected:
1176019Shines@cs.fsu.edu
1186019Shines@cs.fsu.edu            uint32_t numMicroops;
1196019Shines@cs.fsu.edu            StaticInstPtr * microOps;
1206019Shines@cs.fsu.edu
1216019Shines@cs.fsu.edu            /// Constructor
1226019Shines@cs.fsu.edu            PredMacroOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
1236019Shines@cs.fsu.edu                            PredOp(mnem, _machInst, __opClass),
1246019Shines@cs.fsu.edu                            numMicroops(0)
1256019Shines@cs.fsu.edu            {
1266019Shines@cs.fsu.edu                // We rely on the subclasses of this object to handle the
1276019Shines@cs.fsu.edu                // initialization of the micro-operations, since they are
1286019Shines@cs.fsu.edu                // all of variable length
1296019Shines@cs.fsu.edu                flags[IsMacroop] = true;
1306019Shines@cs.fsu.edu            }
1316019Shines@cs.fsu.edu
1326019Shines@cs.fsu.edu            ~PredMacroOp()
1336019Shines@cs.fsu.edu            {
1346019Shines@cs.fsu.edu                if (numMicroops)
1356019Shines@cs.fsu.edu                    delete [] microOps;
1366019Shines@cs.fsu.edu            }
1376019Shines@cs.fsu.edu
1386019Shines@cs.fsu.edu            StaticInstPtr fetchMicroop(MicroPC microPC)
1396019Shines@cs.fsu.edu            {
1406019Shines@cs.fsu.edu                assert(microPC < numMicroops);
1416019Shines@cs.fsu.edu                return microOps[microPC];
1426019Shines@cs.fsu.edu            }
1436019Shines@cs.fsu.edu
1446019Shines@cs.fsu.edu            %(BasicExecPanic)s
1456019Shines@cs.fsu.edu
1466019Shines@cs.fsu.edu            std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
1476019Shines@cs.fsu.edu    };
1486019Shines@cs.fsu.edu
1496019Shines@cs.fsu.edu    /**
1506019Shines@cs.fsu.edu     * Base class for predicated micro-operations.
1516019Shines@cs.fsu.edu     */
1526019Shines@cs.fsu.edu    class PredMicroop : public PredOp
1536019Shines@cs.fsu.edu    {
1546019Shines@cs.fsu.edu            /// Constructor
1556019Shines@cs.fsu.edu            PredMicroop(const char *mnem, MachInst _machInst, OpClass __opClass) :
1566019Shines@cs.fsu.edu                            PredOp(mnem, _machInst, __opClass)
1576019Shines@cs.fsu.edu            {
1586019Shines@cs.fsu.edu                flags[IsMicroop] = true;
1596019Shines@cs.fsu.edu            }
1606019Shines@cs.fsu.edu    };
1616019Shines@cs.fsu.edu
1626019Shines@cs.fsu.edu}};
1636019Shines@cs.fsu.edu
1646243Sgblack@eecs.umich.edulet {{
1656243Sgblack@eecs.umich.edu    predicateTest = 'testPredicate(Cpsr, condCode)'
1666243Sgblack@eecs.umich.edu}};
1676243Sgblack@eecs.umich.edu
1686019Shines@cs.fsu.edudef template PredOpExecute {{
1696019Shines@cs.fsu.edu    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
1706019Shines@cs.fsu.edu    {
1716019Shines@cs.fsu.edu        Fault fault = NoFault;
1726019Shines@cs.fsu.edu        %(op_decl)s;
1736019Shines@cs.fsu.edu        %(op_rd)s;
1746019Shines@cs.fsu.edu
1756243Sgblack@eecs.umich.edu        if (%(predicate_test)s)
1766019Shines@cs.fsu.edu        {
1776243Sgblack@eecs.umich.edu            %(fp_enable_check)s;
1786243Sgblack@eecs.umich.edu            %(code)s;
1796019Shines@cs.fsu.edu            if (fault == NoFault)
1806019Shines@cs.fsu.edu            {
1816019Shines@cs.fsu.edu                %(op_wb)s;
1826019Shines@cs.fsu.edu            }
1836019Shines@cs.fsu.edu        }
1846019Shines@cs.fsu.edu
1856019Shines@cs.fsu.edu        return fault;
1866019Shines@cs.fsu.edu    }
1876019Shines@cs.fsu.edu}};
1886019Shines@cs.fsu.edu
1896019Shines@cs.fsu.edu//Outputs to decoder.cc
1906019Shines@cs.fsu.eduoutput decoder {{
1916019Shines@cs.fsu.edu    std::string PredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1926019Shines@cs.fsu.edu    {
1936019Shines@cs.fsu.edu        std::stringstream ss;
1946019Shines@cs.fsu.edu
1956019Shines@cs.fsu.edu        ccprintf(ss, "%-10s ", mnemonic);
1966019Shines@cs.fsu.edu
1976019Shines@cs.fsu.edu        if (_numDestRegs > 0) {
1986019Shines@cs.fsu.edu            printReg(ss, _destRegIdx[0]);
1996019Shines@cs.fsu.edu        }
2006019Shines@cs.fsu.edu
2016019Shines@cs.fsu.edu        ss << ", ";
2026019Shines@cs.fsu.edu
2036019Shines@cs.fsu.edu        if (_numSrcRegs > 0) {
2046019Shines@cs.fsu.edu            printReg(ss, _srcRegIdx[0]);
2056019Shines@cs.fsu.edu            ss << ", ";
2066019Shines@cs.fsu.edu        }
2076019Shines@cs.fsu.edu
2086019Shines@cs.fsu.edu        return ss.str();
2096019Shines@cs.fsu.edu    }
2106019Shines@cs.fsu.edu
2116019Shines@cs.fsu.edu    std::string PredImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
2126019Shines@cs.fsu.edu    {
2136019Shines@cs.fsu.edu        std::stringstream ss;
2146019Shines@cs.fsu.edu
2156019Shines@cs.fsu.edu        ccprintf(ss, "%-10s ", mnemonic);
2166019Shines@cs.fsu.edu
2176019Shines@cs.fsu.edu        if (_numDestRegs > 0) {
2186019Shines@cs.fsu.edu            printReg(ss, _destRegIdx[0]);
2196019Shines@cs.fsu.edu        }
2206019Shines@cs.fsu.edu
2216019Shines@cs.fsu.edu        ss << ", ";
2226019Shines@cs.fsu.edu
2236019Shines@cs.fsu.edu        if (_numSrcRegs > 0) {
2246019Shines@cs.fsu.edu            printReg(ss, _srcRegIdx[0]);
2256019Shines@cs.fsu.edu            ss << ", ";
2266019Shines@cs.fsu.edu        }
2276019Shines@cs.fsu.edu
2286019Shines@cs.fsu.edu        return ss.str();
2296019Shines@cs.fsu.edu    }
2306019Shines@cs.fsu.edu
2316019Shines@cs.fsu.edu    std::string PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
2326019Shines@cs.fsu.edu    {
2336019Shines@cs.fsu.edu        std::stringstream ss;
2346019Shines@cs.fsu.edu
2356019Shines@cs.fsu.edu        ccprintf(ss, "%-10s ", mnemonic);
2366019Shines@cs.fsu.edu
2376019Shines@cs.fsu.edu        if (_numDestRegs > 0) {
2386019Shines@cs.fsu.edu            printReg(ss, _destRegIdx[0]);
2396019Shines@cs.fsu.edu        }
2406019Shines@cs.fsu.edu
2416019Shines@cs.fsu.edu        ss << ", ";
2426019Shines@cs.fsu.edu
2436019Shines@cs.fsu.edu        if (_numSrcRegs > 0) {
2446019Shines@cs.fsu.edu            printReg(ss, _srcRegIdx[0]);
2456019Shines@cs.fsu.edu            ss << ", ";
2466019Shines@cs.fsu.edu        }
2476019Shines@cs.fsu.edu
2486019Shines@cs.fsu.edu        return ss.str();
2496019Shines@cs.fsu.edu    }
2506019Shines@cs.fsu.edu
2516019Shines@cs.fsu.edu    std::string PredMacroOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
2526019Shines@cs.fsu.edu    {
2536019Shines@cs.fsu.edu        std::stringstream ss;
2546019Shines@cs.fsu.edu
2556019Shines@cs.fsu.edu        ccprintf(ss, "%-10s ", mnemonic);
2566019Shines@cs.fsu.edu
2576019Shines@cs.fsu.edu        return ss.str();
2586019Shines@cs.fsu.edu    }
2596019Shines@cs.fsu.edu
2606019Shines@cs.fsu.edu}};
2616019Shines@cs.fsu.edu
2626019Shines@cs.fsu.edulet {{
2636019Shines@cs.fsu.edu
2646019Shines@cs.fsu.edu    calcCcCode = '''
2656019Shines@cs.fsu.edu        uint16_t _ic, _iv, _iz, _in;
2666019Shines@cs.fsu.edu
2676019Shines@cs.fsu.edu        _in = (resTemp >> 31) & 1;
2686019Shines@cs.fsu.edu        _iz = (resTemp == 0);
2696019Shines@cs.fsu.edu        _iv = %(ivValue)s & 1;
2706019Shines@cs.fsu.edu        _ic = %(icValue)s & 1;
2716019Shines@cs.fsu.edu
2726019Shines@cs.fsu.edu        Cpsr =  _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
2736019Shines@cs.fsu.edu            (Cpsr & 0x0FFFFFFF);
2746019Shines@cs.fsu.edu
2756019Shines@cs.fsu.edu        DPRINTF(Arm, "in = %%d\\n", _in);
2766019Shines@cs.fsu.edu        DPRINTF(Arm, "iz = %%d\\n", _iz);
2776019Shines@cs.fsu.edu        DPRINTF(Arm, "ic = %%d\\n", _ic);
2786019Shines@cs.fsu.edu        DPRINTF(Arm, "iv = %%d\\n", _iv);
2796019Shines@cs.fsu.edu        '''
2806019Shines@cs.fsu.edu
2816019Shines@cs.fsu.edu}};
2826019Shines@cs.fsu.edu
2836019Shines@cs.fsu.edudef format PredOp(code, *opt_flags) {{
2846243Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'PredOp',
2856243Sgblack@eecs.umich.edu                        {"code": code,
2866243Sgblack@eecs.umich.edu                         "predicate_test": predicateTest},
2876243Sgblack@eecs.umich.edu                        opt_flags)
2886019Shines@cs.fsu.edu    header_output = BasicDeclare.subst(iop)
2896019Shines@cs.fsu.edu    decoder_output = BasicConstructor.subst(iop)
2906019Shines@cs.fsu.edu    decode_block = BasicDecode.subst(iop)
2916019Shines@cs.fsu.edu    exec_output = PredOpExecute.subst(iop)
2926019Shines@cs.fsu.edu}};
2936019Shines@cs.fsu.edu
2946019Shines@cs.fsu.edudef format PredImmOp(code, *opt_flags) {{
2956243Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'PredImmOp',
2966243Sgblack@eecs.umich.edu                        {"code": code,
2976243Sgblack@eecs.umich.edu                         "predicate_test": predicateTest},
2986243Sgblack@eecs.umich.edu                        opt_flags)
2996019Shines@cs.fsu.edu    header_output = BasicDeclare.subst(iop)
3006019Shines@cs.fsu.edu    decoder_output = BasicConstructor.subst(iop)
3016019Shines@cs.fsu.edu    decode_block = BasicDecode.subst(iop)
3026019Shines@cs.fsu.edu    exec_output = PredOpExecute.subst(iop)
3036019Shines@cs.fsu.edu}};
3046019Shines@cs.fsu.edu
3056019Shines@cs.fsu.edudef format PredImmOpCc(code, icValue, ivValue, *opt_flags) {{
3066019Shines@cs.fsu.edu    ccCode = calcCcCode % vars()
3076019Shines@cs.fsu.edu    code += ccCode;
3086019Shines@cs.fsu.edu    iop = InstObjParams(name, Name, 'PredImmOp',
3096243Sgblack@eecs.umich.edu                        {"code": code,
3106243Sgblack@eecs.umich.edu                         "cc_code": ccCode,
3116243Sgblack@eecs.umich.edu                         "predicate_test": predicateTest},
3126243Sgblack@eecs.umich.edu                        opt_flags)
3136019Shines@cs.fsu.edu    header_output = BasicDeclare.subst(iop)
3146019Shines@cs.fsu.edu    decoder_output = BasicConstructor.subst(iop)
3156019Shines@cs.fsu.edu    decode_block = BasicDecode.subst(iop)
3166019Shines@cs.fsu.edu    exec_output = PredOpExecute.subst(iop)
3176019Shines@cs.fsu.edu}};
3186019Shines@cs.fsu.edu
3196019Shines@cs.fsu.edudef format PredIntOp(code, *opt_flags) {{
3206019Shines@cs.fsu.edu    new_code = ArmGenericCodeSubs(code)
3216243Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'PredIntOp',
3226243Sgblack@eecs.umich.edu                        {"code": new_code,
3236243Sgblack@eecs.umich.edu                         "predicate_test": predicateTest},
3246243Sgblack@eecs.umich.edu                        opt_flags)
3256019Shines@cs.fsu.edu    header_output = BasicDeclare.subst(iop)
3266019Shines@cs.fsu.edu    decoder_output = BasicConstructor.subst(iop)
3276019Shines@cs.fsu.edu    decode_block = BasicDecode.subst(iop)
3286019Shines@cs.fsu.edu    exec_output = PredOpExecute.subst(iop)
3296019Shines@cs.fsu.edu}};
3306019Shines@cs.fsu.edu
3316019Shines@cs.fsu.edudef format PredIntOpCc(code, icValue, ivValue, *opt_flags) {{
3326019Shines@cs.fsu.edu    ccCode = calcCcCode % vars()
3336019Shines@cs.fsu.edu    code += ccCode;
3346019Shines@cs.fsu.edu    new_code = ArmGenericCodeSubs(code)
3356019Shines@cs.fsu.edu    iop = InstObjParams(name, Name, 'PredIntOp',
3366243Sgblack@eecs.umich.edu                        {"code": new_code,
3376243Sgblack@eecs.umich.edu                         "cc_code": ccCode,
3386243Sgblack@eecs.umich.edu                         "predicate_test": predicateTest},
3396243Sgblack@eecs.umich.edu                        opt_flags)
3406019Shines@cs.fsu.edu    header_output = BasicDeclare.subst(iop)
3416019Shines@cs.fsu.edu    decoder_output = BasicConstructor.subst(iop)
3426019Shines@cs.fsu.edu    decode_block = BasicDecode.subst(iop)
3436019Shines@cs.fsu.edu    exec_output = PredOpExecute.subst(iop)
3446019Shines@cs.fsu.edu}};
3456019Shines@cs.fsu.edu
346