branch.isa revision 2516
18981Sandreas.hansson@arm.com////////////////////////////////////////////////////////////////////
210744SGeoffrey.Blake@arm.com//
311804Srjthakur@google.com// Branch instructions
411804Srjthakur@google.com//
58981Sandreas.hansson@arm.com
68981Sandreas.hansson@arm.comoutput header {{
78981Sandreas.hansson@arm.com        /**
88981Sandreas.hansson@arm.com         * Base class for branch operations.
98981Sandreas.hansson@arm.com         */
108981Sandreas.hansson@arm.com        class Branch : public SparcStaticInst
118981Sandreas.hansson@arm.com        {
128981Sandreas.hansson@arm.com          protected:
138981Sandreas.hansson@arm.com            // Constructor
148981Sandreas.hansson@arm.com            Branch(const char *mnem, MachInst _machInst, OpClass __opClass) :
158981Sandreas.hansson@arm.com                SparcStaticInst(mnem, _machInst, __opClass)
168981Sandreas.hansson@arm.com            {
178981Sandreas.hansson@arm.com            }
188981Sandreas.hansson@arm.com
198981Sandreas.hansson@arm.com            std::string generateDisassembly(Addr pc,
208981Sandreas.hansson@arm.com                    const SymbolTable *symtab) const;
218981Sandreas.hansson@arm.com        };
228981Sandreas.hansson@arm.com
238981Sandreas.hansson@arm.com        /**
248981Sandreas.hansson@arm.com         * Base class for branch operations with an immediate displacement.
258981Sandreas.hansson@arm.com         */
268981Sandreas.hansson@arm.com        class BranchDisp : public Branch
278981Sandreas.hansson@arm.com        {
288981Sandreas.hansson@arm.com          protected:
298981Sandreas.hansson@arm.com            // Constructor
308981Sandreas.hansson@arm.com            BranchDisp(const char *mnem, MachInst _machInst,
318981Sandreas.hansson@arm.com                    OpClass __opClass) :
328981Sandreas.hansson@arm.com                Branch(mnem, _machInst, __opClass)
338981Sandreas.hansson@arm.com            {
348981Sandreas.hansson@arm.com            }
358981Sandreas.hansson@arm.com
368981Sandreas.hansson@arm.com            std::string generateDisassembly(Addr pc,
378981Sandreas.hansson@arm.com                    const SymbolTable *symtab) const;
388981Sandreas.hansson@arm.com
398981Sandreas.hansson@arm.com            int32_t disp;
4011804Srjthakur@google.com        };
418981Sandreas.hansson@arm.com
428981Sandreas.hansson@arm.com        /**
4311793Sbrandon.potter@amd.com         * Base class for branches with 19 bit displacements.
4411793Sbrandon.potter@amd.com         */
459356Snilay@cs.wisc.edu        class Branch19 : public BranchDisp
468981Sandreas.hansson@arm.com        {
478981Sandreas.hansson@arm.com          protected:
488981Sandreas.hansson@arm.com            // Constructor
498981Sandreas.hansson@arm.com            Branch19(const char *mnem, MachInst _machInst,
508981Sandreas.hansson@arm.com                    OpClass __opClass) :
518981Sandreas.hansson@arm.com                BranchDisp(mnem, _machInst, __opClass)
528981Sandreas.hansson@arm.com            {
538981Sandreas.hansson@arm.com                disp = sign_ext(DISP19 << 2, 21);
548981Sandreas.hansson@arm.com            }
5510902Sandreas.sandberg@arm.com        };
5610902Sandreas.sandberg@arm.com
578981Sandreas.hansson@arm.com        /**
588981Sandreas.hansson@arm.com         * Base class for branches with 22 bit displacements.
5910064Sandreas.hansson@arm.com         */
6010902Sandreas.sandberg@arm.com        class Branch22 : public BranchDisp
618981Sandreas.hansson@arm.com        {
628981Sandreas.hansson@arm.com          protected:
638981Sandreas.hansson@arm.com            // Constructor
648981Sandreas.hansson@arm.com            Branch22(const char *mnem, MachInst _machInst,
658981Sandreas.hansson@arm.com                    OpClass __opClass) :
668981Sandreas.hansson@arm.com                BranchDisp(mnem, _machInst, __opClass)
678981Sandreas.hansson@arm.com            {
688981Sandreas.hansson@arm.com                disp = sign_ext(DISP22 << 2, 24);
698981Sandreas.hansson@arm.com            }
708981Sandreas.hansson@arm.com        };
718981Sandreas.hansson@arm.com
728981Sandreas.hansson@arm.com        /**
738981Sandreas.hansson@arm.com         * Base class for branches with 30 bit displacements.
748981Sandreas.hansson@arm.com         */
758981Sandreas.hansson@arm.com        class Branch30 : public BranchDisp
768981Sandreas.hansson@arm.com        {
7710994Sandreas.sandberg@arm.com          protected:
7810994Sandreas.sandberg@arm.com            // Constructor
7910994Sandreas.sandberg@arm.com            Branch30(const char *mnem, MachInst _machInst,
8010994Sandreas.sandberg@arm.com                    OpClass __opClass) :
8110994Sandreas.sandberg@arm.com                BranchDisp(mnem, _machInst, __opClass)
8210994Sandreas.sandberg@arm.com            {
8310994Sandreas.sandberg@arm.com                disp = sign_ext(DISP30 << 2, 32);
849294Sandreas.hansson@arm.com            }
859294Sandreas.hansson@arm.com        };
868981Sandreas.hansson@arm.com
878981Sandreas.hansson@arm.com        /**
888981Sandreas.hansson@arm.com         * Base class for 16bit split displacements.
898981Sandreas.hansson@arm.com         */
908981Sandreas.hansson@arm.com        class BranchSplit : public BranchDisp
918981Sandreas.hansson@arm.com        {
928981Sandreas.hansson@arm.com          protected:
938981Sandreas.hansson@arm.com            // Constructor
949294Sandreas.hansson@arm.com            BranchSplit(const char *mnem, MachInst _machInst,
959294Sandreas.hansson@arm.com                    OpClass __opClass) :
968981Sandreas.hansson@arm.com                BranchDisp(mnem, _machInst, __opClass)
978981Sandreas.hansson@arm.com            {
988981Sandreas.hansson@arm.com                disp = sign_ext((D16HI << 16) | (D16LO << 2), 18);
998981Sandreas.hansson@arm.com            }
1008981Sandreas.hansson@arm.com        };
1018981Sandreas.hansson@arm.com
1028981Sandreas.hansson@arm.com        /**
1038981Sandreas.hansson@arm.com         * Base class for branches that use an immediate and a register to
1048981Sandreas.hansson@arm.com         * compute their displacements.
1058981Sandreas.hansson@arm.com         */
1068981Sandreas.hansson@arm.com        class BranchImm13 : public Branch
1078981Sandreas.hansson@arm.com        {
1088981Sandreas.hansson@arm.com          protected:
1098981Sandreas.hansson@arm.com            // Constructor
1108981Sandreas.hansson@arm.com            BranchImm13(const char *mnem, MachInst _machInst, OpClass __opClass) :
1118981Sandreas.hansson@arm.com                Branch(mnem, _machInst, __opClass), imm(sign_ext(SIMM13, 13))
1128981Sandreas.hansson@arm.com            {
1138981Sandreas.hansson@arm.com            }
1148981Sandreas.hansson@arm.com
1158981Sandreas.hansson@arm.com            std::string generateDisassembly(Addr pc,
11611804Srjthakur@google.com                    const SymbolTable *symtab) const;
11711804Srjthakur@google.com
11811804Srjthakur@google.com            int32_t imm;
11911804Srjthakur@google.com        };
12011804Srjthakur@google.com}};
12111804Srjthakur@google.com
12211804Srjthakur@google.comoutput decoder {{
12311804Srjthakur@google.com        std::string Branch::generateDisassembly(Addr pc,
12411804Srjthakur@google.com                const SymbolTable *symtab) const
12511804Srjthakur@google.com        {
12611804Srjthakur@google.com            std::stringstream response;
12711804Srjthakur@google.com
12811804Srjthakur@google.com            printMnemonic(response, mnemonic);
12911804Srjthakur@google.com
13011804Srjthakur@google.com            if (_numSrcRegs > 0)
13111804Srjthakur@google.com            {
13211804Srjthakur@google.com                printReg(response, _srcRegIdx[0]);
13311804Srjthakur@google.com                for(int x = 1; x < _numSrcRegs; x++)
13411804Srjthakur@google.com                {
13511804Srjthakur@google.com                    response << ", ";
13611804Srjthakur@google.com                    printReg(response, _srcRegIdx[x]);
13711804Srjthakur@google.com                }
13811804Srjthakur@google.com            }
13911804Srjthakur@google.com
14011804Srjthakur@google.com            if (_numDestRegs > 0)
14111804Srjthakur@google.com            {
14211804Srjthakur@google.com                if(_numSrcRegs > 0)
14311804Srjthakur@google.com                    response << ", ";
14411804Srjthakur@google.com                printReg(response, _destRegIdx[0]);
14511804Srjthakur@google.com            }
14611804Srjthakur@google.com
14711804Srjthakur@google.com            return response.str();
14811804Srjthakur@google.com        }
14911804Srjthakur@google.com
15011804Srjthakur@google.com        std::string BranchImm13::generateDisassembly(Addr pc,
15111804Srjthakur@google.com                const SymbolTable *symtab) const
15211804Srjthakur@google.com        {
15311804Srjthakur@google.com            std::stringstream response;
15411804Srjthakur@google.com
15511804Srjthakur@google.com            printMnemonic(response, mnemonic);
15611804Srjthakur@google.com
15711804Srjthakur@google.com            if (_numSrcRegs > 0)
15811804Srjthakur@google.com            {
15911804Srjthakur@google.com                printReg(response, _srcRegIdx[0]);
16011804Srjthakur@google.com                for(int x = 1; x < _numSrcRegs; x++)
16111804Srjthakur@google.com                {
16211804Srjthakur@google.com                    response << ", ";
16311804Srjthakur@google.com                    printReg(response, _srcRegIdx[x]);
16411804Srjthakur@google.com                }
16511804Srjthakur@google.com            }
16611804Srjthakur@google.com
16711804Srjthakur@google.com            if(_numSrcRegs > 0)
16811804Srjthakur@google.com                response << ", ";
16911804Srjthakur@google.com
17011804Srjthakur@google.com            ccprintf(response, "0x%x", imm);
17111804Srjthakur@google.com
17211804Srjthakur@google.com            if (_numDestRegs > 0)
17311804Srjthakur@google.com            {
17411804Srjthakur@google.com                response << ", ";
17511804Srjthakur@google.com                printReg(response, _destRegIdx[0]);
17611804Srjthakur@google.com            }
17711804Srjthakur@google.com
17811804Srjthakur@google.com            return response.str();
17911804Srjthakur@google.com        }
18011804Srjthakur@google.com
18111804Srjthakur@google.com        std::string BranchDisp::generateDisassembly(Addr pc,
18211804Srjthakur@google.com                const SymbolTable *symtab) const
18311804Srjthakur@google.com        {
18411804Srjthakur@google.com            std::stringstream response;
18511804Srjthakur@google.com            std::string symbol;
18611804Srjthakur@google.com            Addr symbolAddr;
18711804Srjthakur@google.com
18811804Srjthakur@google.com            Addr target = disp + pc;
18911804Srjthakur@google.com
19011804Srjthakur@google.com            printMnemonic(response, mnemonic);
19111804Srjthakur@google.com            ccprintf(response, "0x%x", target);
19211804Srjthakur@google.com
19311804Srjthakur@google.com            if(symtab->findNearestSymbol(target, symbol, symbolAddr))
19411804Srjthakur@google.com            {
19511804Srjthakur@google.com                ccprintf(response, " <%s", symbol);
19611804Srjthakur@google.com                if(symbolAddr != target)
19711804Srjthakur@google.com                    ccprintf(response, "+0x%x>", target - symbolAddr);
19811804Srjthakur@google.com                else
19911804Srjthakur@google.com                    ccprintf(response, ">");
20011804Srjthakur@google.com            }
20111804Srjthakur@google.com
20211804Srjthakur@google.com            return response.str();
20311804Srjthakur@google.com        }
20411804Srjthakur@google.com}};
20511804Srjthakur@google.com
20611804Srjthakur@google.comdef template BranchExecute {{
20711804Srjthakur@google.com        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
20811804Srjthakur@google.com                Trace::InstRecord *traceData) const
20911804Srjthakur@google.com        {
21011804Srjthakur@google.com            //Attempt to execute the instruction
21111804Srjthakur@google.com            Fault fault = NoFault;
21211804Srjthakur@google.com
21311804Srjthakur@google.com            %(op_decl)s;
21411804Srjthakur@google.com            %(op_rd)s;
2158981Sandreas.hansson@arm.com
2168981Sandreas.hansson@arm.com            NNPC = xc->readNextNPC();
2178981Sandreas.hansson@arm.com            %(code)s;
21811804Srjthakur@google.com
21911804Srjthakur@google.com            if(fault == NoFault)
22011139Sandreas.hansson@arm.com            {
22111139Sandreas.hansson@arm.com                //Write the resulting state to the execution context
22210994Sandreas.sandberg@arm.com                %(op_wb)s;
22310994Sandreas.sandberg@arm.com            }
22411804Srjthakur@google.com
22511804Srjthakur@google.com            return fault;
22611804Srjthakur@google.com        }
22711804Srjthakur@google.com}};
22811804Srjthakur@google.com
22910994Sandreas.sandberg@arm.com// Primary format for branch instructions:
23011139Sandreas.hansson@arm.comdef format Branch(code, *opt_flags) {{
23111139Sandreas.hansson@arm.com        (usesImm, code, immCode,
23210994Sandreas.sandberg@arm.com         rString, iString) = splitOutImm(code)
2338981Sandreas.hansson@arm.com        codeBlk = CodeBlock(code)
2348981Sandreas.hansson@arm.com        iop = InstObjParams(name, Name, 'Branch', codeBlk, opt_flags)
2358981Sandreas.hansson@arm.com        header_output = BasicDeclare.subst(iop)
2368981Sandreas.hansson@arm.com        decoder_output = BasicConstructor.subst(iop)
2378981Sandreas.hansson@arm.com        exec_output = BranchExecute.subst(iop)
2388981Sandreas.hansson@arm.com        if usesImm:
2398981Sandreas.hansson@arm.com            imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString,
2408981Sandreas.hansson@arm.com                    codeBlk, opt_flags)
2418981Sandreas.hansson@arm.com            header_output += BasicDeclare.subst(imm_iop)
2428981Sandreas.hansson@arm.com            decoder_output += BasicConstructor.subst(imm_iop)
2438981Sandreas.hansson@arm.com            exec_output += BranchExecute.subst(imm_iop)
2448981Sandreas.hansson@arm.com            decode_block = ROrImmDecode.subst(iop)
2458981Sandreas.hansson@arm.com        else:
2468981Sandreas.hansson@arm.com            decode_block = BasicDecode.subst(iop)
2478981Sandreas.hansson@arm.com}};
2488981Sandreas.hansson@arm.com
24911139Sandreas.hansson@arm.com// Primary format for branch instructions:
25011139Sandreas.hansson@arm.comdef format Branch19(code, *opt_flags) {{
25111804Srjthakur@google.com        codeBlk = CodeBlock(code)
25211804Srjthakur@google.com        iop = InstObjParams(name, Name, 'Branch19', codeBlk, opt_flags)
2538981Sandreas.hansson@arm.com        header_output = BasicDeclare.subst(iop)
2548981Sandreas.hansson@arm.com        decoder_output = BasicConstructor.subst(iop)
2558981Sandreas.hansson@arm.com        exec_output = BranchExecute.subst(iop)
25611284Sandreas.hansson@arm.com        decode_block = BasicDecode.subst(iop)
25711284Sandreas.hansson@arm.com}};
2589785Sandreas.hansson@arm.com
2599542Sandreas.hansson@arm.com// Primary format for branch instructions:
2608981Sandreas.hansson@arm.comdef format Branch22(code, *opt_flags) {{
2618981Sandreas.hansson@arm.com        codeBlk = CodeBlock(code)
26211284Sandreas.hansson@arm.com        iop = InstObjParams(name, Name, 'Branch22', codeBlk, opt_flags)
2638981Sandreas.hansson@arm.com        header_output = BasicDeclare.subst(iop)
2648981Sandreas.hansson@arm.com        decoder_output = BasicConstructor.subst(iop)
2658981Sandreas.hansson@arm.com        exec_output = BranchExecute.subst(iop)
2669785Sandreas.hansson@arm.com        decode_block = BasicDecode.subst(iop)
2679542Sandreas.hansson@arm.com}};
2688981Sandreas.hansson@arm.com
2698981Sandreas.hansson@arm.com// Primary format for branch instructions:
27010994Sandreas.sandberg@arm.comdef format Branch30(code, *opt_flags) {{
27111139Sandreas.hansson@arm.com        codeBlk = CodeBlock(code)
27210994Sandreas.sandberg@arm.com        iop = InstObjParams(name, Name, 'Branch30', codeBlk, opt_flags)
27310994Sandreas.sandberg@arm.com        header_output = BasicDeclare.subst(iop)
27411804Srjthakur@google.com        decoder_output = BasicConstructor.subst(iop)
27511847Spierre-yves.peneau@lirmm.fr        exec_output = BranchExecute.subst(iop)
27611847Spierre-yves.peneau@lirmm.fr        decode_block = BasicDecode.subst(iop)
27711804Srjthakur@google.com}};
2788981Sandreas.hansson@arm.com
2798981Sandreas.hansson@arm.com// Primary format for branch instructions:
2808981Sandreas.hansson@arm.comdef format BranchSplit(code, *opt_flags) {{
2818981Sandreas.hansson@arm.com        codeBlk = CodeBlock(code)
2828981Sandreas.hansson@arm.com        iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags)
2838981Sandreas.hansson@arm.com        header_output = BasicDeclare.subst(iop)
2848981Sandreas.hansson@arm.com        decoder_output = BasicConstructor.subst(iop)
2858981Sandreas.hansson@arm.com        exec_output = BranchExecute.subst(iop)
2868981Sandreas.hansson@arm.com        decode_block = BasicDecode.subst(iop)
2878981Sandreas.hansson@arm.com}};
2888981Sandreas.hansson@arm.com
2898981Sandreas.hansson@arm.com