branch.isa revision 12236:126ac9da6050
12440SN/A// -*- mode:c++ -*-
22440SN/A
32440SN/A// Copyright (c) 2010, 2014 ARM Limited
42440SN/A// All rights reserved
52440SN/A//
62440SN/A// The license below extends only to copyright in the software and shall
72440SN/A// not be construed as granting a license to any other intellectual
82440SN/A// property including but not limited to intellectual property relating
92440SN/A// to a hardware implementation of the functionality of the software
102440SN/A// licensed hereunder.  You may use the software subject to the license
112440SN/A// terms below provided that you ensure that this notice is replicated
122440SN/A// unmodified and in its entirety in all distributions of the software,
132440SN/A// modified or unmodified, in source code or in binary form.
142440SN/A//
152440SN/A// Redistribution and use in source and binary forms, with or without
162440SN/A// modification, are permitted provided that the following conditions are
172440SN/A// met: redistributions of source code must retain the above copyright
182440SN/A// notice, this list of conditions and the following disclaimer;
192440SN/A// redistributions in binary form must reproduce the above copyright
202440SN/A// notice, this list of conditions and the following disclaimer in the
212440SN/A// documentation and/or other materials provided with the distribution;
222440SN/A// neither the name of the copyright holders nor the names of its
232440SN/A// contributors may be used to endorse or promote products derived from
242440SN/A// this software without specific prior written permission.
252440SN/A//
262440SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
272665Ssaidi@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
282665Ssaidi@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
292665Ssaidi@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
302440SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
312440SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
322440SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
332440SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
342440SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
352440SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
362440SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
372972Sgblack@eecs.umich.edu//
382460SN/A// Authors: Gabe Black
392440SN/A
403120Sgblack@eecs.umich.edudef template BranchImmDeclare {{
412440SN/Aclass %(class_name)s : public %(base_class)s
422440SN/A{
432440SN/A    public:
442440SN/A        // Constructor
454826Ssaidi@eecs.umich.edu        %(class_name)s(ExtMachInst machInst, int32_t _imm);
464826Ssaidi@eecs.umich.edu        Fault execute(ExecContext *, Trace::InstRecord *) const;
473577Sgblack@eecs.umich.edu};
483577Sgblack@eecs.umich.edu}};
493577Sgblack@eecs.umich.edu
504172Ssaidi@eecs.umich.edudef template BranchImmConstructor {{
513577Sgblack@eecs.umich.edu    %(class_name)s::%(class_name)s(ExtMachInst machInst,
523577Sgblack@eecs.umich.edu                                          int32_t _imm)
532467SN/A        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _imm)
542440SN/A    {
552440SN/A        %(constructor)s;
562440SN/A        if (!(condCode == COND_AL || condCode == COND_UC)) {
572440SN/A            for (int x = 0; x < _numDestRegs; x++) {
582467SN/A                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
592440SN/A            }
602440SN/A            flags[IsCondControl] = true;
612440SN/A        } else {
622440SN/A            flags[IsUncondControl] = true;
632467SN/A        }
642440SN/A
652440SN/A    }
662440SN/A}};
672440SN/A
682467SN/Adef template BranchImmCondDeclare {{
692440SN/Aclass %(class_name)s : public %(base_class)s
702440SN/A{
712440SN/A    public:
722440SN/A        // Constructor
732467SN/A        %(class_name)s(ExtMachInst machInst, int32_t _imm,
742440SN/A                       ConditionCode _condCode);
752440SN/A        Fault execute(ExecContext *, Trace::InstRecord *) const;
762440SN/A        ArmISA::PCState branchTarget(const ArmISA::PCState &branchPC) const;
772440SN/A
782440SN/A        /// Explicitly import the otherwise hidden branchTarget
792467SN/A        using StaticInst::branchTarget;
802440SN/A};
812440SN/A}};
822440SN/A
832467SN/Adef template BranchImmCondConstructor {{
842440SN/A    %(class_name)s::%(class_name)s(ExtMachInst machInst,
852440SN/A                                          int32_t _imm,
862440SN/A                                          ConditionCode _condCode)
872440SN/A        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
882440SN/A                         _imm, _condCode)
892467SN/A    {
902440SN/A        %(constructor)s;
912440SN/A        if (!(condCode == COND_AL || condCode == COND_UC)) {
922440SN/A            for (int x = 0; x < _numDestRegs; x++) {
932467SN/A                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
942440SN/A            }
952440SN/A            flags[IsCondControl] = true;
962440SN/A        } else {
972440SN/A            flags[IsUncondControl] = true;
982440SN/A        }
992440SN/A    }
1002440SN/A}};
1012440SN/A
1022440SN/Adef template BranchRegDeclare {{
1032440SN/Aclass %(class_name)s : public %(base_class)s
1042440SN/A{
1052440SN/A    public:
1062440SN/A        // Constructor
1072440SN/A        %(class_name)s(ExtMachInst machInst, IntRegIndex _op1);
1082680Sktlim@umich.edu        Fault execute(ExecContext *, Trace::InstRecord *) const;
1092440SN/A};
1102680Sktlim@umich.edu}};
1112680Sktlim@umich.edu
1122440SN/Adef template BranchRegConstructor {{
1133961Sgblack@eecs.umich.edu    %(class_name)s::%(class_name)s(ExtMachInst machInst,
1143961Sgblack@eecs.umich.edu                                          IntRegIndex _op1)
1154194Ssaidi@eecs.umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _op1)
1164194Ssaidi@eecs.umich.edu    {
1174194Ssaidi@eecs.umich.edu        %(constructor)s;
1182440SN/A        if (!(condCode == COND_AL || condCode == COND_UC)) {
1192440SN/A            for (int x = 0; x < _numDestRegs; x++) {
1202440SN/A                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1212440SN/A            }
1222440SN/A            flags[IsCondControl] = true;
1232440SN/A        } else {
1242440SN/A            flags[IsUncondControl] = true;
1252467SN/A        }
1262440SN/A        if (%(is_ras_pop)s)
1272440SN/A            flags[IsReturn] = true;
1282467SN/A    }
1292440SN/A}};
1302440SN/A
1312467SN/Adef template BranchRegCondDeclare {{
1322467SN/Aclass %(class_name)s : public %(base_class)s
1332440SN/A{
1342440SN/A    public:
1352467SN/A        // Constructor
1362440SN/A        %(class_name)s(ExtMachInst machInst, IntRegIndex _op1,
1372467SN/A                       ConditionCode _condCode);
1382440SN/A        Fault execute(ExecContext *, Trace::InstRecord *) const;
1392440SN/A};
1402440SN/A}};
1412467SN/A
1422440SN/Adef template BranchRegCondConstructor {{
1432440SN/A    %(class_name)s::%(class_name)s(ExtMachInst machInst,
1442440SN/A                                          IntRegIndex _op1,
1452680Sktlim@umich.edu                                          ConditionCode _condCode)
1462680Sktlim@umich.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
1472440SN/A                         _op1, _condCode)
1482440SN/A    {
1492440SN/A        %(constructor)s;
1502680Sktlim@umich.edu        if (!(condCode == COND_AL || condCode == COND_UC)) {
1512440SN/A            for (int x = 0; x < _numDestRegs; x++) {
1522680Sktlim@umich.edu                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
1532680Sktlim@umich.edu            }
1542440SN/A            flags[IsCondControl] = true;
1552440SN/A        } else {
1562440SN/A            flags[IsUncondControl] = true;
1572440SN/A        }
1582440SN/A        if (%(is_ras_pop)s)
159            flags[IsReturn] = true;
160    }
161}};
162
163def template BranchRegRegDeclare {{
164class %(class_name)s : public %(base_class)s
165{
166    public:
167        // Constructor
168        %(class_name)s(ExtMachInst machInst,
169                       IntRegIndex _op1, IntRegIndex _op2);
170        Fault execute(ExecContext *, Trace::InstRecord *) const;
171};
172}};
173
174def template BranchTableDeclare {{
175class %(class_name)s : public %(base_class)s
176{
177    public:
178        // Constructor
179        %(class_name)s(ExtMachInst machInst,
180                       IntRegIndex _op1, IntRegIndex _op2);
181        Fault execute(ExecContext *, Trace::InstRecord *) const;
182        Fault initiateAcc(ExecContext *, Trace::InstRecord *) const;
183        Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const;
184};
185}};
186
187def template BranchRegRegConstructor {{
188    %(class_name)s::%(class_name)s(ExtMachInst machInst,
189                                          IntRegIndex _op1,
190                                          IntRegIndex _op2)
191        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _op1, _op2)
192    {
193        %(constructor)s;
194        if (!(condCode == COND_AL || condCode == COND_UC)) {
195            for (int x = 0; x < _numDestRegs; x++) {
196                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
197            }
198            flags[IsCondControl] = true;
199        } else {
200            flags[IsUncondControl] = true;
201        }
202    }
203}};
204
205def template BranchImmRegDeclare {{
206class %(class_name)s : public %(base_class)s
207{
208    public:
209        // Constructor
210        %(class_name)s(ExtMachInst machInst,
211                       int32_t imm, IntRegIndex _op1);
212        Fault execute(ExecContext *, Trace::InstRecord *) const;
213        ArmISA::PCState branchTarget(const ArmISA::PCState &branchPC) const;
214
215        /// Explicitly import the otherwise hidden branchTarget
216        using StaticInst::branchTarget;
217};
218}};
219
220// Only used by CBNZ, CBZ which is conditional based on
221// a register value even though the instruction is always unconditional.
222def template BranchImmRegConstructor {{
223    %(class_name)s::%(class_name)s(ExtMachInst machInst,
224                                          int32_t _imm,
225                                          IntRegIndex _op1)
226        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _imm, _op1)
227    {
228        %(constructor)s;
229        flags[IsCondControl] = true;
230    }
231}};
232
233def template BranchTarget {{
234
235    ArmISA::PCState
236    %(class_name)s::branchTarget(const ArmISA::PCState &branchPC) const
237    {
238        %(op_decl)s;
239        %(op_rd)s;
240
241        ArmISA::PCState pcs = branchPC;
242        %(brTgtCode)s
243        pcs.advance();
244        return pcs;
245    }
246}};
247
248
249