fp.isa revision 9554
15647Sgblack@eecs.umich.edu// -*- mode:c++ -*-
29544Sandreas.hansson@arm.com
38922Swilliam.wang@arm.com// Copyright (c) 2007 MIPS Technologies, Inc.
48922Swilliam.wang@arm.com// All rights reserved.
58922Swilliam.wang@arm.com//
68922Swilliam.wang@arm.com// Redistribution and use in source and binary forms, with or without
78922Swilliam.wang@arm.com// modification, are permitted provided that the following conditions are
88922Swilliam.wang@arm.com// met: redistributions of source code must retain the above copyright
98922Swilliam.wang@arm.com// notice, this list of conditions and the following disclaimer;
108922Swilliam.wang@arm.com// redistributions in binary form must reproduce the above copyright
118922Swilliam.wang@arm.com// notice, this list of conditions and the following disclaimer in the
128922Swilliam.wang@arm.com// documentation and/or other materials provided with the distribution;
138922Swilliam.wang@arm.com// neither the name of the copyright holders nor the names of its
145647Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
155647Sgblack@eecs.umich.edu// this software without specific prior written permission.
165647Sgblack@eecs.umich.edu//
177087Snate@binkert.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
187087Snate@binkert.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
197087Snate@binkert.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
207087Snate@binkert.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
217087Snate@binkert.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
227087Snate@binkert.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
237087Snate@binkert.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
247087Snate@binkert.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
255647Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
267087Snate@binkert.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
277087Snate@binkert.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
287087Snate@binkert.org//
297087Snate@binkert.org// Authors: Korey Sewell
307087Snate@binkert.org
317087Snate@binkert.org////////////////////////////////////////////////////////////////////
327087Snate@binkert.org//
337087Snate@binkert.org// Floating Point operate instructions
345647Sgblack@eecs.umich.edu//
357087Snate@binkert.org
365647Sgblack@eecs.umich.eduoutput header {{
375647Sgblack@eecs.umich.edu        /**
385647Sgblack@eecs.umich.edu         * Base class for FP operations.
395647Sgblack@eecs.umich.edu         */
405647Sgblack@eecs.umich.edu        class FPOp : public MipsStaticInst
415647Sgblack@eecs.umich.edu        {
425647Sgblack@eecs.umich.edu                protected:
435647Sgblack@eecs.umich.edu
445647Sgblack@eecs.umich.edu                /// Constructor
455647Sgblack@eecs.umich.edu                FPOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
465647Sgblack@eecs.umich.edu                {
475647Sgblack@eecs.umich.edu                }
485647Sgblack@eecs.umich.edu
495647Sgblack@eecs.umich.edu            //std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
505647Sgblack@eecs.umich.edu
515647Sgblack@eecs.umich.edu                //needs function to check for fpEnable or not
528229Snate@binkert.org        };
535647Sgblack@eecs.umich.edu
545654Sgblack@eecs.umich.edu        class FPCompareOp : public FPOp
555647Sgblack@eecs.umich.edu        {
568232Snate@binkert.org          protected:
576137Sgblack@eecs.umich.edu            FPCompareOp(const char *mnem, MachInst _machInst, OpClass __opClass) : FPOp(mnem, _machInst, __opClass)
586137Sgblack@eecs.umich.edu                {
596137Sgblack@eecs.umich.edu                }
605654Sgblack@eecs.umich.edu
616046Sgblack@eecs.umich.edu            std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
628781Sgblack@eecs.umich.edu
635647Sgblack@eecs.umich.edu        };
645648Sgblack@eecs.umich.edu}};
655648Sgblack@eecs.umich.edu
665647Sgblack@eecs.umich.eduoutput decoder {{
675647Sgblack@eecs.umich.edu        std::string FPCompareOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
685647Sgblack@eecs.umich.edu        {
695647Sgblack@eecs.umich.edu            std::stringstream ss;
705647Sgblack@eecs.umich.edu
715647Sgblack@eecs.umich.edu            ccprintf(ss, "%-10s ", mnemonic);
725647Sgblack@eecs.umich.edu
735647Sgblack@eecs.umich.edu            ccprintf(ss,"%d",CC);
745647Sgblack@eecs.umich.edu
755648Sgblack@eecs.umich.edu            if(_numSrcRegs > 0) {
765647Sgblack@eecs.umich.edu                ss << ", ";
775648Sgblack@eecs.umich.edu                printReg(ss, _srcRegIdx[0]);
785648Sgblack@eecs.umich.edu            }
795648Sgblack@eecs.umich.edu
805648Sgblack@eecs.umich.edu            if(_numSrcRegs > 1) {
815648Sgblack@eecs.umich.edu                ss << ", ";
825648Sgblack@eecs.umich.edu                printReg(ss, _srcRegIdx[1]);
835648Sgblack@eecs.umich.edu            }
845648Sgblack@eecs.umich.edu
855648Sgblack@eecs.umich.edu            return ss.str();
865648Sgblack@eecs.umich.edu        }
875648Sgblack@eecs.umich.edu}};
885648Sgblack@eecs.umich.edu
895648Sgblack@eecs.umich.eduoutput header {{
905648Sgblack@eecs.umich.edu        void fpResetCauseBits(%(CPU_exec_context)s *cpu);
915648Sgblack@eecs.umich.edu
925648Sgblack@eecs.umich.edu}};
935648Sgblack@eecs.umich.edu
945648Sgblack@eecs.umich.eduoutput exec {{
955648Sgblack@eecs.umich.edu        inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
965648Sgblack@eecs.umich.edu        {
975648Sgblack@eecs.umich.edu            //@TODO: Implement correct CP0 checks to see if the CP1
985648Sgblack@eecs.umich.edu            // unit is enable or not
995648Sgblack@eecs.umich.edu          if (!isCoprocessorEnabled(xc, 1))
1005648Sgblack@eecs.umich.edu             return new CoprocessorUnusableFault(1);
1015648Sgblack@eecs.umich.edu
1025648Sgblack@eecs.umich.edu          return NoFault;
1035648Sgblack@eecs.umich.edu        }
1045648Sgblack@eecs.umich.edu
1055648Sgblack@eecs.umich.edu        //If any operand is Nan return the appropriate QNaN
1065648Sgblack@eecs.umich.edu        template <class T>
1075648Sgblack@eecs.umich.edu        bool
1085648Sgblack@eecs.umich.edu        fpNanOperands(FPOp *inst, %(CPU_exec_context)s *xc, const T &src_type,
1095648Sgblack@eecs.umich.edu                      Trace::InstRecord *traceData)
1105648Sgblack@eecs.umich.edu        {
1115648Sgblack@eecs.umich.edu            uint64_t mips_nan = 0;
1125648Sgblack@eecs.umich.edu            assert(sizeof(T) == 4);
1135648Sgblack@eecs.umich.edu
1145648Sgblack@eecs.umich.edu            for (int i = 0; i < inst->numSrcRegs(); i++) {
1155648Sgblack@eecs.umich.edu                uint64_t src_bits = xc->readFloatRegOperandBits(inst, 0);
1165648Sgblack@eecs.umich.edu
1175648Sgblack@eecs.umich.edu                if (isNan(&src_bits, 32) ) {
1185648Sgblack@eecs.umich.edu                    mips_nan = MIPS32_QNAN;
1195648Sgblack@eecs.umich.edu                    xc->setFloatRegOperandBits(inst, 0, mips_nan);
1205648Sgblack@eecs.umich.edu                    if (traceData) { traceData->setData(mips_nan); }
1215648Sgblack@eecs.umich.edu                    return true;
1225648Sgblack@eecs.umich.edu                }
1235648Sgblack@eecs.umich.edu            }
1245648Sgblack@eecs.umich.edu            return false;
1255648Sgblack@eecs.umich.edu        }
1265648Sgblack@eecs.umich.edu
1275648Sgblack@eecs.umich.edu        template <class T>
1285648Sgblack@eecs.umich.edu        bool
1295648Sgblack@eecs.umich.edu        fpInvalidOp(FPOp *inst, %(CPU_exec_context)s *cpu, const T dest_val,
1305648Sgblack@eecs.umich.edu                    Trace::InstRecord *traceData)
1315648Sgblack@eecs.umich.edu        {
1325648Sgblack@eecs.umich.edu            uint64_t mips_nan = 0;
1335648Sgblack@eecs.umich.edu            T src_op = dest_val;
1345648Sgblack@eecs.umich.edu            assert(sizeof(T) == 4);
1355648Sgblack@eecs.umich.edu
1365648Sgblack@eecs.umich.edu            if (isNan(&src_op, 32)) {
1375648Sgblack@eecs.umich.edu                mips_nan = MIPS32_QNAN;
1385648Sgblack@eecs.umich.edu
1395648Sgblack@eecs.umich.edu                //Set value to QNAN
1405648Sgblack@eecs.umich.edu                cpu->setFloatRegOperandBits(inst, 0, mips_nan);
1415648Sgblack@eecs.umich.edu
1425648Sgblack@eecs.umich.edu                //Read FCSR from FloatRegFile
1435648Sgblack@eecs.umich.edu                uint32_t fcsr_bits =
1445648Sgblack@eecs.umich.edu                    cpu->tcBase()->readFloatRegBits(FLOATREG_FCSR);
1455648Sgblack@eecs.umich.edu
1465648Sgblack@eecs.umich.edu                uint32_t new_fcsr = genInvalidVector(fcsr_bits);
1475648Sgblack@eecs.umich.edu
1485648Sgblack@eecs.umich.edu                //Write FCSR from FloatRegFile
1495648Sgblack@eecs.umich.edu                cpu->tcBase()->setFloatRegBits(FLOATREG_FCSR, new_fcsr);
1505648Sgblack@eecs.umich.edu
1515648Sgblack@eecs.umich.edu                if (traceData) { traceData->setData(mips_nan); }
1525648Sgblack@eecs.umich.edu                return true;
1535648Sgblack@eecs.umich.edu            }
1545648Sgblack@eecs.umich.edu
1555648Sgblack@eecs.umich.edu            return false;
1565648Sgblack@eecs.umich.edu        }
1575648Sgblack@eecs.umich.edu
1585648Sgblack@eecs.umich.edu        void
1595648Sgblack@eecs.umich.edu        fpResetCauseBits(%(CPU_exec_context)s *cpu)
1605648Sgblack@eecs.umich.edu        {
1615648Sgblack@eecs.umich.edu            //Read FCSR from FloatRegFile
1625648Sgblack@eecs.umich.edu            uint32_t fcsr = cpu->tcBase()->readFloatRegBits(FLOATREG_FCSR);
1635648Sgblack@eecs.umich.edu
1645648Sgblack@eecs.umich.edu            // TODO: Use utility function here
1655648Sgblack@eecs.umich.edu            fcsr = bits(fcsr, 31, 18) << 18 | bits(fcsr, 11, 0);
1665648Sgblack@eecs.umich.edu
1675648Sgblack@eecs.umich.edu            //Write FCSR from FloatRegFile
1685648Sgblack@eecs.umich.edu            cpu->tcBase()->setFloatRegBits(FLOATREG_FCSR, fcsr);
1695648Sgblack@eecs.umich.edu        }
1705648Sgblack@eecs.umich.edu}};
1715648Sgblack@eecs.umich.edu
1725648Sgblack@eecs.umich.edudef template FloatingPointExecute {{
1735648Sgblack@eecs.umich.edu        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
1745648Sgblack@eecs.umich.edu        {
1755648Sgblack@eecs.umich.edu                Fault fault = NoFault;
1765648Sgblack@eecs.umich.edu
1775648Sgblack@eecs.umich.edu                %(fp_enable_check)s;
1785648Sgblack@eecs.umich.edu
1795648Sgblack@eecs.umich.edu
1805648Sgblack@eecs.umich.edu                //When is the right time to reset cause bits?
1815648Sgblack@eecs.umich.edu                //start of every instruction or every cycle?
1825648Sgblack@eecs.umich.edu                if (FullSystem)
1835648Sgblack@eecs.umich.edu                    fpResetCauseBits(xc);
1845648Sgblack@eecs.umich.edu                %(op_decl)s;
1855648Sgblack@eecs.umich.edu                %(op_rd)s;
1865648Sgblack@eecs.umich.edu
1875648Sgblack@eecs.umich.edu                //Check if any FP operand is a NaN value
1885648Sgblack@eecs.umich.edu                if (!fpNanOperands((FPOp*)this, xc, Fd, traceData)) {
1895648Sgblack@eecs.umich.edu                    %(code)s;
1905648Sgblack@eecs.umich.edu
1915648Sgblack@eecs.umich.edu                    //Change this code for Full-System/Sycall Emulation
1925648Sgblack@eecs.umich.edu                    //separation
1935648Sgblack@eecs.umich.edu                    //----
1945648Sgblack@eecs.umich.edu                    //Should Full System-Mode throw a fault here?
1955648Sgblack@eecs.umich.edu                    //----
1965648Sgblack@eecs.umich.edu                    //Check for IEEE 754 FP Exceptions
1975648Sgblack@eecs.umich.edu                    //fault = fpNanOperands((FPOp*)this, xc, Fd, traceData);
1985648Sgblack@eecs.umich.edu                    bool invalid_op = false;
1995648Sgblack@eecs.umich.edu                    if (FullSystem) {
2005648Sgblack@eecs.umich.edu                        invalid_op =
2015648Sgblack@eecs.umich.edu                            fpInvalidOp((FPOp*)this, xc, Fd, traceData);
2025648Sgblack@eecs.umich.edu                    }
2035648Sgblack@eecs.umich.edu                    if (!invalid_op && fault == NoFault) {
2045648Sgblack@eecs.umich.edu                        %(op_wb)s;
2055648Sgblack@eecs.umich.edu                    }
2065648Sgblack@eecs.umich.edu                }
2075648Sgblack@eecs.umich.edu
2085648Sgblack@eecs.umich.edu                return fault;
2095648Sgblack@eecs.umich.edu        }
2105648Sgblack@eecs.umich.edu}};
2115648Sgblack@eecs.umich.edu
2125648Sgblack@eecs.umich.edu// Primary format for float point operate instructions:
2135648Sgblack@eecs.umich.edudef format FloatOp(code, *flags) {{
2145648Sgblack@eecs.umich.edu        iop = InstObjParams(name, Name, 'FPOp', code, flags)
2155648Sgblack@eecs.umich.edu        header_output = BasicDeclare.subst(iop)
2165648Sgblack@eecs.umich.edu        decoder_output = BasicConstructor.subst(iop)
2175648Sgblack@eecs.umich.edu        decode_block = BasicDecode.subst(iop)
2185648Sgblack@eecs.umich.edu        exec_output = FloatingPointExecute.subst(iop)
2195648Sgblack@eecs.umich.edu}};
2205649Sgblack@eecs.umich.edu
2215649Sgblack@eecs.umich.edudef format FloatCompareOp(cond_code, *flags) {{
2225649Sgblack@eecs.umich.edu    import sys
2235648Sgblack@eecs.umich.edu
2245898Sgblack@eecs.umich.edu    code = 'bool cond;\n'
2259805Sstever@gmail.com    if '_sf' in cond_code or 'SinglePrecision' in flags:
2265648Sgblack@eecs.umich.edu        if 'QnanException' in flags:
2275648Sgblack@eecs.umich.edu            code += 'if (isQnan(&Fs_sf, 32) || isQnan(&Ft_sf, 32)) {\n'
2285648Sgblack@eecs.umich.edu            code += '\tFCSR = genInvalidVector(FCSR);\n'
2295648Sgblack@eecs.umich.edu            code += '\treturn NoFault;'
2305648Sgblack@eecs.umich.edu            code += '}\n else '
2315648Sgblack@eecs.umich.edu        code += 'if (isNan(&Fs_sf, 32) || isNan(&Ft_sf, 32)) {\n'
2325648Sgblack@eecs.umich.edu    elif '_df' in cond_code or 'DoublePrecision' in flags:
2335648Sgblack@eecs.umich.edu        if 'QnanException' in flags:
2345648Sgblack@eecs.umich.edu            code += 'if (isQnan(&Fs_df, 64) || isQnan(&Ft_df, 64)) {\n'
2355648Sgblack@eecs.umich.edu            code += '\tFCSR = genInvalidVector(FCSR);\n'
2365648Sgblack@eecs.umich.edu            code += '\treturn NoFault;'
2375648Sgblack@eecs.umich.edu            code += '}\n else '
2385649Sgblack@eecs.umich.edu        code += 'if (isNan(&Fs_df, 64) || isNan(&Ft_df, 64)) {\n'
2395649Sgblack@eecs.umich.edu    else:
2405649Sgblack@eecs.umich.edu       sys.exit('Decoder Failed: Can\'t Determine Operand Type\n')
2415648Sgblack@eecs.umich.edu
2425898Sgblack@eecs.umich.edu    if 'UnorderedTrue' in flags:
2439805Sstever@gmail.com       code += 'cond = 1;\n'
2445647Sgblack@eecs.umich.edu    elif 'UnorderedFalse' in flags:
2455691Sgblack@eecs.umich.edu       code += 'cond = 0;\n'
2465691Sgblack@eecs.umich.edu    else:
2475691Sgblack@eecs.umich.edu       sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
2485691Sgblack@eecs.umich.edu
2495691Sgblack@eecs.umich.edu    code += '} else {\n'
2505691Sgblack@eecs.umich.edu    code +=  cond_code + '}'
2515691Sgblack@eecs.umich.edu    code += 'FCSR = genCCVector(FCSR, CC, cond);\n'
2525691Sgblack@eecs.umich.edu
2535691Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'FPCompareOp', code)
2545691Sgblack@eecs.umich.edu    header_output = BasicDeclare.subst(iop)
2555691Sgblack@eecs.umich.edu    decoder_output = BasicConstructor.subst(iop)
2565691Sgblack@eecs.umich.edu    decode_block = BasicDecode.subst(iop)
2575691Sgblack@eecs.umich.edu    exec_output = BasicExecute.subst(iop)
2585691Sgblack@eecs.umich.edu}};
2595691Sgblack@eecs.umich.edu
2605691Sgblack@eecs.umich.edudef format FloatConvertOp(code, *flags) {{
2615691Sgblack@eecs.umich.edu    import sys
2625691Sgblack@eecs.umich.edu
2635691Sgblack@eecs.umich.edu    #Determine Source Type
2645691Sgblack@eecs.umich.edu    convert = 'fpConvert('
2655691Sgblack@eecs.umich.edu    if '_sf' in code:
2665691Sgblack@eecs.umich.edu        code = 'float ' + code + '\n'
2675691Sgblack@eecs.umich.edu        convert += 'SINGLE_TO_'
2685691Sgblack@eecs.umich.edu    elif '_df' in code:
2695691Sgblack@eecs.umich.edu        code = 'double ' + code + '\n'
2705691Sgblack@eecs.umich.edu        convert += 'DOUBLE_TO_'
2715691Sgblack@eecs.umich.edu    elif '_uw' in code:
2725691Sgblack@eecs.umich.edu        code = 'uint32_t ' + code + '\n'
2735691Sgblack@eecs.umich.edu        convert += 'WORD_TO_'
2745691Sgblack@eecs.umich.edu    elif '_ud' in code:
2755691Sgblack@eecs.umich.edu        code = 'uint64_t ' + code + '\n'
2765691Sgblack@eecs.umich.edu        convert += 'LONG_TO_'
2775691Sgblack@eecs.umich.edu    else:
2785691Sgblack@eecs.umich.edu        sys.exit("Error Determining Source Type for Conversion")
2795691Sgblack@eecs.umich.edu
2805691Sgblack@eecs.umich.edu    #Determine Destination Type
2815691Sgblack@eecs.umich.edu    if 'ToSingle' in flags:
2825691Sgblack@eecs.umich.edu        code += 'Fd_uw = ' + convert + 'SINGLE, '
2835691Sgblack@eecs.umich.edu    elif 'ToDouble' in flags:
2846066Sgblack@eecs.umich.edu        code += 'Fd_ud = ' + convert + 'DOUBLE, '
2856066Sgblack@eecs.umich.edu    elif 'ToWord' in flags:
2866050Sgblack@eecs.umich.edu        code += 'Fd_uw = ' + convert + 'WORD, '
2876050Sgblack@eecs.umich.edu    elif 'ToLong' in flags:
2885691Sgblack@eecs.umich.edu        code += 'Fd_ud = ' + convert + 'LONG, '
2898745Sgblack@eecs.umich.edu    else:
2908781Sgblack@eecs.umich.edu        sys.exit("Error Determining Destination Type for Conversion")
2918781Sgblack@eecs.umich.edu
2925691Sgblack@eecs.umich.edu    #Figure out how to round value
2935647Sgblack@eecs.umich.edu    if 'Ceil' in flags:
2946041Sgblack@eecs.umich.edu        code += 'ceil(val)); '
2956041Sgblack@eecs.umich.edu    elif 'Floor' in flags:
2966041Sgblack@eecs.umich.edu        code += 'floor(val)); '
2976041Sgblack@eecs.umich.edu    elif 'Round' in flags:
2986136Sgblack@eecs.umich.edu        code += 'roundFP(val, 0)); '
2996136Sgblack@eecs.umich.edu    elif 'Trunc' in flags:
3006136Sgblack@eecs.umich.edu        code += 'truncFP(val));'
3016136Sgblack@eecs.umich.edu    else:
3026136Sgblack@eecs.umich.edu        code += 'val); '
3036041Sgblack@eecs.umich.edu
3046136Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'FPOp', code)
3056136Sgblack@eecs.umich.edu    header_output = BasicDeclare.subst(iop)
3069090Sandreas.hansson@arm.com    decoder_output = BasicConstructor.subst(iop)
3076041Sgblack@eecs.umich.edu    decode_block = BasicDecode.subst(iop)
3086041Sgblack@eecs.umich.edu    exec_output = BasicExecute.subst(iop)
3096041Sgblack@eecs.umich.edu}};
3106137Sgblack@eecs.umich.edu
3116137Sgblack@eecs.umich.edudef format FloatAccOp(code, *flags) {{
3126137Sgblack@eecs.umich.edu        iop = InstObjParams(name, Name, 'FPOp', code, flags)
3137913SBrad.Beckmann@amd.com        header_output = BasicDeclare.subst(iop)
3147913SBrad.Beckmann@amd.com        decoder_output = BasicConstructor.subst(iop)
3157913SBrad.Beckmann@amd.com        decode_block = BasicDecode.subst(iop)
3167913SBrad.Beckmann@amd.com        exec_output = BasicExecute.subst(iop)
3177913SBrad.Beckmann@amd.com}};
3186137Sgblack@eecs.umich.edu
3197913SBrad.Beckmann@amd.com// Primary format for float64 operate instructions:
3208922Swilliam.wang@arm.comdef format Float64Op(code, *flags) {{
3218922Swilliam.wang@arm.com        iop = InstObjParams(name, Name, 'MipsStaticInst', code, flags)
3228922Swilliam.wang@arm.com        header_output = BasicDeclare.subst(iop)
3236137Sgblack@eecs.umich.edu        decoder_output = BasicConstructor.subst(iop)
3246137Sgblack@eecs.umich.edu        decode_block = BasicDecode.subst(iop)
3256137Sgblack@eecs.umich.edu        exec_output = BasicExecute.subst(iop)
3265651Sgblack@eecs.umich.edu}};
3275651Sgblack@eecs.umich.edu
3285651Sgblack@eecs.umich.edudef format FloatPSCompareOp(cond_code1, cond_code2, *flags) {{
3296136Sgblack@eecs.umich.edu    import sys
3305651Sgblack@eecs.umich.edu
3315651Sgblack@eecs.umich.edu    code = 'bool cond1, cond2;\n'
3325651Sgblack@eecs.umich.edu    code += 'bool code_block1, code_block2;\n'
3335651Sgblack@eecs.umich.edu    code += 'code_block1 = code_block2 = true;\n'
3345654Sgblack@eecs.umich.edu
3355654Sgblack@eecs.umich.edu    if 'QnanException' in flags:
3365654Sgblack@eecs.umich.edu        code += 'if (isQnan(&Fs1_sf, 32) || isQnan(&Ft1_sf, 32)) {\n'
3375654Sgblack@eecs.umich.edu        code += '\tFCSR = genInvalidVector(FCSR);\n'
3385697Snate@binkert.org        code += 'code_block1 = false;'
3395655Sgblack@eecs.umich.edu        code += '}\n'
3405691Sgblack@eecs.umich.edu        code += 'if (isQnan(&Fs2_sf, 32) || isQnan(&Ft2_sf, 32)) {\n'
3415691Sgblack@eecs.umich.edu        code += '\tFCSR = genInvalidVector(FCSR);\n'
3425654Sgblack@eecs.umich.edu        code += 'code_block2 = false;'
3435651Sgblack@eecs.umich.edu        code += '}\n'
3445651Sgblack@eecs.umich.edu
3455651Sgblack@eecs.umich.edu    code += 'if (code_block1) {'
3465651Sgblack@eecs.umich.edu    code += '\tif (isNan(&Fs1_sf, 32) || isNan(&Ft1_sf, 32)) {\n'
3475651Sgblack@eecs.umich.edu    if 'UnorderedTrue' in flags:
3485651Sgblack@eecs.umich.edu       code += 'cond1 = 1;\n'
3496064Sgblack@eecs.umich.edu    elif 'UnorderedFalse' in flags:
3509805Sstever@gmail.com       code += 'cond1 = 0;\n'
3515651Sgblack@eecs.umich.edu    else:
3525651Sgblack@eecs.umich.edu       sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
3535651Sgblack@eecs.umich.edu    code += '} else {\n'
3546065Sgblack@eecs.umich.edu    code +=  cond_code1
3556065Sgblack@eecs.umich.edu    code += 'FCSR = genCCVector(FCSR, CC, cond1);}\n}\n'
3566065Sgblack@eecs.umich.edu
3576065Sgblack@eecs.umich.edu    code += 'if (code_block2) {'
3586065Sgblack@eecs.umich.edu    code += '\tif (isNan(&Fs2_sf, 32) || isNan(&Ft2_sf, 32)) {\n'
3596069Sgblack@eecs.umich.edu    if 'UnorderedTrue' in flags:
3606069Sgblack@eecs.umich.edu       code += 'cond2 = 1;\n'
3616069Sgblack@eecs.umich.edu    elif 'UnorderedFalse' in flags:
3626069Sgblack@eecs.umich.edu       code += 'cond2 = 0;\n'
3636069Sgblack@eecs.umich.edu    else:
3646069Sgblack@eecs.umich.edu       sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
3656065Sgblack@eecs.umich.edu    code += '} else {\n'
3666065Sgblack@eecs.umich.edu    code +=  cond_code2
3676065Sgblack@eecs.umich.edu    code += 'FCSR = genCCVector(FCSR, CC, cond2);}\n}'
3686065Sgblack@eecs.umich.edu
3696065Sgblack@eecs.umich.edu    iop = InstObjParams(name, Name, 'FPCompareOp', code)
3708711Sandreas.hansson@arm.com    header_output = BasicDeclare.subst(iop)
3719090Sandreas.hansson@arm.com    decoder_output = BasicConstructor.subst(iop)
3726041Sgblack@eecs.umich.edu    decode_block = BasicDecode.subst(iop)
3738711Sandreas.hansson@arm.com    exec_output = BasicExecute.subst(iop)
3748711Sandreas.hansson@arm.com}};
3758711Sandreas.hansson@arm.com
3768711Sandreas.hansson@arm.com