integerop.isa revision 7799:5d0f62927d75
12SN/A// Copyright (c) 2006-2007 The Regents of The University of Michigan
21762SN/A// All rights reserved.
32SN/A//
42SN/A// Redistribution and use in source and binary forms, with or without
52SN/A// modification, are permitted provided that the following conditions are
62SN/A// met: redistributions of source code must retain the above copyright
72SN/A// notice, this list of conditions and the following disclaimer;
82SN/A// redistributions in binary form must reproduce the above copyright
92SN/A// notice, this list of conditions and the following disclaimer in the
102SN/A// documentation and/or other materials provided with the distribution;
112SN/A// neither the name of the copyright holders nor the names of its
122SN/A// contributors may be used to endorse or promote products derived from
132SN/A// this software without specific prior written permission.
142SN/A//
152SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
162SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
172SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
182SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
192SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
202SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
212SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
222SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
232SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
242SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
252SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
262SN/A//
272665Ssaidi@eecs.umich.edu// Authors: Ali Saidi
282665Ssaidi@eecs.umich.edu//          Gabe Black
292665Ssaidi@eecs.umich.edu//          Steve Reinhardt
302SN/A
312SN/A////////////////////////////////////////////////////////////////////
324997Sgblack@eecs.umich.edu//
331110SN/A// Integer operate instructions
344997Sgblack@eecs.umich.edu//
358229Snate@binkert.org
368229Snate@binkert.orgoutput header {{
372680Sktlim@umich.edu        /**
388229Snate@binkert.org         * Base class for integer operations.
392800Ssaidi@eecs.umich.edu         */
408780Sgblack@eecs.umich.edu        class IntOp : public SparcStaticInst
412SN/A        {
425569Snate@binkert.org          protected:
432167SN/A            // Constructor
442203SN/A            IntOp(const char *mnem, ExtMachInst _machInst,
452203SN/A                    OpClass __opClass) :
462222SN/A                SparcStaticInst(mnem, _machInst, __opClass)
472166SN/A            {
482203SN/A            }
492203SN/A
502222SN/A            std::string generateDisassembly(Addr pc,
512166SN/A                const SymbolTable *symtab) const;
522147SN/A
532147SN/A            virtual bool printPseudoOps(std::ostream &os, Addr pc,
542222SN/A                    const SymbolTable *symtab) const;
552147SN/A        };
562147SN/A
572147SN/A        /**
582222SN/A         * Base class for immediate integer operations.
592147SN/A         */
602147SN/A        class IntOpImm : public IntOp
612147SN/A        {
622222SN/A          protected:
632147SN/A            // Constructor
642147SN/A            IntOpImm(const char *mnem, ExtMachInst _machInst,
652147SN/A                    OpClass __opClass) :
662222SN/A                IntOp(mnem, _machInst, __opClass)
672147SN/A            {
682147SN/A            }
692147SN/A
702222SN/A            int64_t imm;
712147SN/A
728405Sksewell@umich.edu            std::string generateDisassembly(Addr pc,
732147SN/A                const SymbolTable *symtab) const;
742222SN/A
752147SN/A            virtual bool printPseudoOps(std::ostream &os, Addr pc,
768405Sksewell@umich.edu                    const SymbolTable *symtab) const;
772147SN/A        };
782222SN/A
792147SN/A        /**
802289SN/A         * Base class for 10 bit immediate integer operations.
812289SN/A         */
822289SN/A        class IntOpImm10 : public IntOpImm
832289SN/A        {
842147SN/A          protected:
852147SN/A            // Constructor
862222SN/A            IntOpImm10(const char *mnem, ExtMachInst _machInst,
872147SN/A                    OpClass __opClass) :
882147SN/A                IntOpImm(mnem, _machInst, __opClass)
892147SN/A            {
902222SN/A                imm = sext<10>(SIMM10);
912147SN/A            }
922147SN/A        };
932147SN/A
942222SN/A        /**
952147SN/A         * Base class for 11 bit immediate integer operations.
962147SN/A         */
972147SN/A        class IntOpImm11 : public IntOpImm
982222SN/A        {
992147SN/A          protected:
1002147SN/A            // Constructor
1012147SN/A            IntOpImm11(const char *mnem, ExtMachInst _machInst,
1022222SN/A                    OpClass __opClass) :
1032147SN/A                IntOpImm(mnem, _machInst, __opClass)
1042147SN/A            {
1052147SN/A                imm = sext<11>(SIMM11);
1062222SN/A            }
1072147SN/A        };
1085569Snate@binkert.org
10910417Sandreas.hansson@arm.com        /**
1102174SN/A         * Base class for 13 bit immediate integer operations.
1112680Sktlim@umich.edu         */
1128780Sgblack@eecs.umich.edu        class IntOpImm13 : public IntOpImm
1138780Sgblack@eecs.umich.edu        {
1142222SN/A          protected:
1152174SN/A            // Constructor
1167720Sgblack@eecs.umich.edu            IntOpImm13(const char *mnem, ExtMachInst _machInst,
1177720Sgblack@eecs.umich.edu                    OpClass __opClass) :
1182196SN/A                IntOpImm(mnem, _machInst, __opClass)
1197720Sgblack@eecs.umich.edu            {
1207720Sgblack@eecs.umich.edu                imm = sext<13>(SIMM13);
1212196SN/A            }
1222201SN/A        };
1232196SN/A
1245568Snate@binkert.org        /**
1255568Snate@binkert.org         * Base class for sethi.
1262196SN/A         */
1272196SN/A        class SetHi : public IntOpImm
1287720Sgblack@eecs.umich.edu        {
1297720Sgblack@eecs.umich.edu          protected:
1302174SN/A            // Constructor
1312174SN/A            SetHi(const char *mnem, ExtMachInst _machInst,
1325569Snate@binkert.org                    OpClass __opClass) :
13310417Sandreas.hansson@arm.com                IntOpImm(mnem, _machInst, __opClass)
1342201SN/A            {
1352680Sktlim@umich.edu                imm = (IMM22 & 0x3FFFFF) << 10;
1368780Sgblack@eecs.umich.edu            }
1378780Sgblack@eecs.umich.edu
1382201SN/A            std::string generateDisassembly(Addr pc,
1392201SN/A                const SymbolTable *symtab) const;
1402201SN/A        };
1415569Snate@binkert.org}};
14210417Sandreas.hansson@arm.com
1432289SN/Adef template SetHiDecode {{
1448780Sgblack@eecs.umich.edu    {
1458780Sgblack@eecs.umich.edu        if (RD == 0 && IMM22 == 0)
1468780Sgblack@eecs.umich.edu            return (SparcStaticInst *)(new Nop("nop", machInst, No_OpClass));
1478780Sgblack@eecs.umich.edu        else
1488780Sgblack@eecs.umich.edu            return (SparcStaticInst *)(new %(class_name)s(machInst));
1498780Sgblack@eecs.umich.edu    }
15010664SAli.Saidi@ARM.com}};
1518780Sgblack@eecs.umich.edu
1528780Sgblack@eecs.umich.eduoutput decoder {{
1532289SN/A
1548780Sgblack@eecs.umich.edu        bool
1558780Sgblack@eecs.umich.edu        IntOp::printPseudoOps(std::ostream &os, Addr pc,
1568780Sgblack@eecs.umich.edu                const SymbolTable *symbab) const
1578780Sgblack@eecs.umich.edu        {
1588780Sgblack@eecs.umich.edu            if (!std::strcmp(mnemonic, "or") && _srcRegIdx[0] == 0) {
1598780Sgblack@eecs.umich.edu                printMnemonic(os, "mov");
1602289SN/A                printSrcReg(os, 1);
1618780Sgblack@eecs.umich.edu                ccprintf(os, ", ");
1628780Sgblack@eecs.umich.edu                printDestReg(os, 0);
1638780Sgblack@eecs.umich.edu                return true;
1648780Sgblack@eecs.umich.edu            }
1652289SN/A            return false;
1662289SN/A        }
1672680Sktlim@umich.edu
1682289SN/A        bool
1692289SN/A        IntOpImm::printPseudoOps(std::ostream &os, Addr pc,
1705569Snate@binkert.org                const SymbolTable *symbab) const
17110417Sandreas.hansson@arm.com        {
1722289SN/A            if (!std::strcmp(mnemonic, "or")) {
1738780Sgblack@eecs.umich.edu                if (_numSrcRegs > 0 && _srcRegIdx[0] == 0) {
17410664SAli.Saidi@ARM.com                    if (imm == 0) {
17510664SAli.Saidi@ARM.com                        printMnemonic(os, "clr");
17610664SAli.Saidi@ARM.com                    } else {
1772289SN/A                        printMnemonic(os, "mov");
1782289SN/A                        ccprintf(os, " 0x%x, ", imm);
1792680Sktlim@umich.edu                    }
1802289SN/A                    printDestReg(os, 0);
1812289SN/A                    return true;
1825569Snate@binkert.org                } else if (imm == 0) {
18310417Sandreas.hansson@arm.com                    printMnemonic(os, "mov");
1844997Sgblack@eecs.umich.edu                    printSrcReg(os, 0);
1858780Sgblack@eecs.umich.edu                    ccprintf(os, ", ");
1868780Sgblack@eecs.umich.edu                    printDestReg(os, 0);
1878806Sgblack@eecs.umich.edu                    return true;
1888806Sgblack@eecs.umich.edu                }
1898806Sgblack@eecs.umich.edu            }
1908806Sgblack@eecs.umich.edu            return false;
1918806Sgblack@eecs.umich.edu        }
1928806Sgblack@eecs.umich.edu
1938806Sgblack@eecs.umich.edu        std::string
1948806Sgblack@eecs.umich.edu        IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
1954997Sgblack@eecs.umich.edu        {
1968806Sgblack@eecs.umich.edu            std::stringstream response;
1978806Sgblack@eecs.umich.edu
1984997Sgblack@eecs.umich.edu            if (printPseudoOps(response, pc, symtab))
1994997Sgblack@eecs.umich.edu                return response.str();
2004997Sgblack@eecs.umich.edu            printMnemonic(response, mnemonic);
2015569Snate@binkert.org            printRegArray(response, _srcRegIdx, _numSrcRegs);
20210417Sandreas.hansson@arm.com            if (_numDestRegs && _numSrcRegs)
2034997Sgblack@eecs.umich.edu                response << ", ";
2048780Sgblack@eecs.umich.edu            printDestReg(response, 0);
2058780Sgblack@eecs.umich.edu            return response.str();
2068806Sgblack@eecs.umich.edu        }
2078806Sgblack@eecs.umich.edu
2088806Sgblack@eecs.umich.edu        std::string
2098806Sgblack@eecs.umich.edu        IntOpImm::generateDisassembly(Addr pc,
2108806Sgblack@eecs.umich.edu                const SymbolTable *symtab) const
2118806Sgblack@eecs.umich.edu        {
2128806Sgblack@eecs.umich.edu            std::stringstream response;
2138806Sgblack@eecs.umich.edu
2148806Sgblack@eecs.umich.edu            if (printPseudoOps(response, pc, symtab))
2158806Sgblack@eecs.umich.edu                return response.str();
2168806Sgblack@eecs.umich.edu            printMnemonic(response, mnemonic);
2178806Sgblack@eecs.umich.edu            printRegArray(response, _srcRegIdx, _numSrcRegs);
2184997Sgblack@eecs.umich.edu            if (_numSrcRegs > 0)
2198806Sgblack@eecs.umich.edu                response << ", ";
2204997Sgblack@eecs.umich.edu            ccprintf(response, "0x%x", imm);
2214997Sgblack@eecs.umich.edu            if (_numDestRegs > 0)
2224997Sgblack@eecs.umich.edu                response << ", ";
2232167SN/A            printDestReg(response, 0);
2242167SN/A            return response.str();
225        }
226
227        std::string
228        SetHi::generateDisassembly(Addr pc, const SymbolTable *symtab) const
229        {
230            std::stringstream response;
231
232            printMnemonic(response, mnemonic);
233            ccprintf(response, "%%hi(0x%x), ", imm);
234            printDestReg(response, 0);
235            return response.str();
236        }
237}};
238
239def template IntOpExecute {{
240        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
241                Trace::InstRecord *traceData) const
242        {
243            Fault fault = NoFault;
244
245            %(op_decl)s;
246            %(op_rd)s;
247            %(code)s;
248
249            // Write the resulting state to the execution context
250            if (fault == NoFault) {
251                %(cc_code)s;
252                %(op_wb)s;
253            }
254            return fault;
255        }
256}};
257
258let {{
259    def doIntFormat(code, ccCode, name, Name, opt_flags):
260        (usesImm, code, immCode,
261         rString, iString) = splitOutImm(code)
262        iop = InstObjParams(name, Name, 'IntOp',
263                {"code": code, "cc_code": ccCode},
264                opt_flags)
265        header_output = BasicDeclare.subst(iop)
266        decoder_output = BasicConstructor.subst(iop)
267        exec_output = IntOpExecute.subst(iop)
268        if usesImm:
269            imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString,
270                    {"code": immCode, "cc_code": ccCode}, opt_flags)
271            header_output += BasicDeclare.subst(imm_iop)
272            decoder_output += BasicConstructor.subst(imm_iop)
273            exec_output += IntOpExecute.subst(imm_iop)
274            decode_block = ROrImmDecode.subst(iop)
275        else:
276            decode_block = BasicDecode.subst(iop)
277        return (header_output, decoder_output, exec_output, decode_block)
278
279    calcCcCode = '''
280        uint16_t _ic, _iv, _iz, _in, _xc, _xv, _xz, _xn;
281
282        _in = (Rd >> 31) & 1;
283        _iz = ((Rd & 0xFFFFFFFF) == 0);
284        _xn = (Rd >> 63) & 1;
285        _xz = (Rd == 0);
286        _iv = %(iv)s & 1;
287        _ic = %(ic)s & 1;
288        _xv = %(xv)s & 1;
289        _xc = %(xc)s & 1;
290
291        Ccr =  _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 |
292               _xc << 4 | _xv << 5 | _xz << 6 | _xn << 7;
293
294
295        DPRINTF(Sparc, "in = %%d\\n", _in);
296        DPRINTF(Sparc, "iz = %%d\\n", _iz);
297        DPRINTF(Sparc, "xn = %%d\\n", _xn);
298        DPRINTF(Sparc, "xz = %%d\\n", _xz);
299        DPRINTF(Sparc, "iv = %%d\\n", _iv);
300        DPRINTF(Sparc, "ic = %%d\\n", _ic);
301        DPRINTF(Sparc, "xv = %%d\\n", _xv);
302        DPRINTF(Sparc, "xc = %%d\\n", _xc);
303        '''
304
305    default_ic = "findCarry(32, res, op1, op2)"
306    default_iv = "findOverflow(32, res, op1, op2)"
307    default_xc = "findCarry(64, res, op1, op2)"
308    default_xv = "findOverflow(64, res, op1, op2)"
309    default_sub_ic = "!findCarry(32, res, op1, ~op2)"
310    default_sub_iv = "findOverflow(32, res, op1, ~op2)"
311    default_sub_xc = "!findCarry(64, res, op1, ~op2)"
312    default_sub_xv = "findOverflow(64, res, op1, ~op2)"
313}};
314
315// Primary format for integer operate instructions:
316def format IntOp(code, *opt_flags) {{
317    ccCode = ''
318    (header_output,
319     decoder_output,
320     exec_output,
321     decode_block) = doIntFormat(code, ccCode,
322                                 name, Name, opt_flags)
323}};
324
325// Primary format for integer operate instructions:
326def format IntOpCc(code, ic=default_ic, iv=default_iv,
327                         xc=default_xc, xv=default_xv,
328                         sub=False, *opt_flags) {{
329
330    if sub == "False":
331        (def_ic, def_iv, def_xc, def_xv) = \
332            (default_ic, default_iv, default_xc, default_xv)
333    else:
334        (def_ic, def_iv, def_xc, def_xv) = \
335            (default_sub_ic, default_sub_iv, default_sub_xc, default_sub_xv)
336    if ic == "default_ic":
337        ic = def_ic
338    if iv == "default_iv":
339        iv = def_iv
340    if xc == "default_xc":
341        xc = def_xc
342    if xv == "default_xv":
343        xv = def_xv
344    ccCode = calcCcCode % vars()
345    (header_output,
346     decoder_output,
347     exec_output,
348     decode_block) = doIntFormat(code, ccCode,
349                                 name, Name, opt_flags)
350}};
351
352// Primary format for integer operate instructions:
353def format IntOpCcRes(code, ic=0, iv=0, xc=0, xv=0, *opt_flags) {{
354    ccCode = calcCcCode % {"ic" : ic, "iv" : iv, "xc" : xc, "xv" : xv}
355    (header_output,
356     decoder_output,
357     exec_output,
358     decode_block) = doIntFormat(code, ccCode,
359                                 name, Name, opt_flags)
360}};
361
362def format SetHi(code, *opt_flags) {{
363    iop = InstObjParams(name, Name, 'SetHi',
364            {"code": code, "cc_code": ''}, opt_flags)
365    header_output = BasicDeclare.subst(iop)
366    decoder_output = BasicConstructor.subst(iop)
367    exec_output = IntOpExecute.subst(iop)
368    decode_block = SetHiDecode.subst(iop)
369}};
370
371