pred.isa revision 9077:e236675714a4
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder.  You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42
43////////////////////////////////////////////////////////////////////
44//
45// Predicated Instruction Execution
46//
47
48let {{
49    predicateTest = 'testPredicate(OptCondCodesNZ, OptCondCodesC, OptCondCodesV, condCode)'
50    condPredicateTest = 'testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)'
51}};
52
53def template DataImmDeclare {{
54class %(class_name)s : public %(base_class)s
55{
56    public:
57        // Constructor
58        %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
59                IntRegIndex _op1, uint32_t _imm, bool _rotC=true);
60        %(BasicExecDeclare)s
61};
62}};
63
64def template DataImmConstructor {{
65    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
66                                          IntRegIndex _dest,
67                                          IntRegIndex _op1,
68                                          uint32_t _imm,
69                                          bool _rotC)
70        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
71                         _dest, _op1, _imm, _rotC)
72    {
73        %(constructor)s;
74        if (!(condCode == COND_AL || condCode == COND_UC)) {
75            for (int x = 0; x < _numDestRegs; x++) {
76                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
77            }
78        }
79    }
80}};
81
82def template DataRegDeclare {{
83class %(class_name)s : public %(base_class)s
84{
85    public:
86        // Constructor
87        %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
88                IntRegIndex _op1, IntRegIndex _op2,
89                int32_t _shiftAmt, ArmShiftType _shiftType);
90        %(BasicExecDeclare)s
91};
92}};
93
94def template DataRegConstructor {{
95    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
96                                          IntRegIndex _dest,
97                                          IntRegIndex _op1,
98                                          IntRegIndex _op2,
99                                          int32_t _shiftAmt,
100                                          ArmShiftType _shiftType)
101        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
102                         _dest, _op1, _op2, _shiftAmt, _shiftType)
103    {
104        %(constructor)s;
105        if (!(condCode == COND_AL || condCode == COND_UC)) {
106            for (int x = 0; x < _numDestRegs; x++) {
107                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
108            }
109        }
110
111        if (%(is_branch)s){
112            flags[IsControl] = true;
113            flags[IsIndirectControl] = true;
114            if (condCode == COND_AL || condCode == COND_UC)
115                flags[IsUncondControl] = true;
116            else
117                flags[IsCondControl] = true;
118
119            if (%(is_ras_pop)s) {
120                flags[IsReturn] = true;
121            }
122        }
123
124    }
125}};
126
127def template DataRegRegDeclare {{
128class %(class_name)s : public %(base_class)s
129{
130    public:
131        // Constructor
132        %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
133                IntRegIndex _op1, IntRegIndex _op2, IntRegIndex _shift,
134                ArmShiftType _shiftType);
135        %(BasicExecDeclare)s
136};
137}};
138
139def template DataRegRegConstructor {{
140    inline %(class_name)s::%(class_name)s(ExtMachInst machInst,
141                                          IntRegIndex _dest,
142                                          IntRegIndex _op1,
143                                          IntRegIndex _op2,
144                                          IntRegIndex _shift,
145                                          ArmShiftType _shiftType)
146        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
147                         _dest, _op1, _op2, _shift, _shiftType)
148    {
149        %(constructor)s;
150        if (!(condCode == COND_AL || condCode == COND_UC)) {
151            for (int x = 0; x < _numDestRegs; x++) {
152                _srcRegIdx[_numSrcRegs++] = _destRegIdx[x];
153            }
154        }
155    }
156}};
157
158def template PredOpExecute {{
159    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
160    {
161        Fault fault = NoFault;
162        uint64_t resTemp = 0;
163        resTemp = resTemp;
164        %(op_decl)s;
165        %(op_rd)s;
166
167        if (%(predicate_test)s)
168        {
169            %(code)s;
170            if (fault == NoFault)
171            {
172                %(op_wb)s;
173            }
174        } else {
175            xc->setPredicate(false);
176        }
177
178        return fault;
179    }
180}};
181
182def template QuiescePredOpExecute {{
183    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
184    {
185        Fault fault = NoFault;
186        uint64_t resTemp = 0;
187        resTemp = resTemp;
188        %(op_decl)s;
189        %(op_rd)s;
190
191        if (%(predicate_test)s)
192        {
193            %(code)s;
194            if (fault == NoFault)
195            {
196                %(op_wb)s;
197            }
198        } else {
199            xc->setPredicate(false);
200            PseudoInst::quiesceSkip(xc->tcBase());
201        }
202
203        return fault;
204    }
205}};
206
207def template QuiescePredOpExecuteWithFixup {{
208    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
209    {
210        Fault fault = NoFault;
211        uint64_t resTemp = 0;
212        resTemp = resTemp;
213        %(op_decl)s;
214        %(op_rd)s;
215
216        if (%(predicate_test)s)
217        {
218            %(code)s;
219            if (fault == NoFault)
220            {
221                %(op_wb)s;
222            }
223        } else {
224            xc->setPredicate(false);
225            %(pred_fixup)s;
226            PseudoInst::quiesceSkip(xc->tcBase());
227        }
228
229        return fault;
230    }
231}};
232
233def template DataDecode {{
234    if (machInst.opcode4 == 0) {
235        if (machInst.sField == 0)
236            return new %(class_name)sImm(machInst);
237        else
238            return new %(class_name)sImmCc(machInst);
239    } else {
240        if (machInst.sField == 0)
241            return new %(class_name)s(machInst);
242        else
243            return new %(class_name)sCc(machInst);
244    }
245}};
246
247def template DataImmDecode {{
248    if (machInst.sField == 0)
249        return new %(class_name)s(machInst);
250    else
251        return new %(class_name)sCc(machInst);
252}};
253