pred.isa revision 6244:113424c3f621
1// -*- mode:c++ -*-
2
3// Copyright (c) 2007-2008 The Florida State University
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Stephen Hines
30
31////////////////////////////////////////////////////////////////////
32//
33// Predicated Instruction Execution
34//
35
36output header {{
37#include <iostream>
38
39    inline uint32_t
40    rotate_imm(uint32_t immValue, int rotateValue)
41    {
42        return ((immValue >> (rotateValue & 31)) |
43                (immValue << (32 - (rotateValue & 31))));
44    }
45
46    /**
47     * Base class for predicated integer operations.
48     */
49    class PredOp : public ArmStaticInst
50    {
51      protected:
52
53        ArmISA::ConditionCode condCode;
54
55        /// Constructor
56        PredOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
57                        ArmStaticInst(mnem, _machInst, __opClass),
58                        condCode((ArmISA::ConditionCode)COND_CODE)
59        {
60        }
61
62        std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
63    };
64
65    /**
66     * Base class for predicated immediate operations.
67     */
68    class PredImmOp : public PredOp
69    {
70            protected:
71
72            uint32_t imm;
73            uint32_t rotate;
74            uint32_t rotated_imm;
75            uint32_t rotated_carry;
76
77            /// Constructor
78            PredImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
79                            PredOp(mnem, _machInst, __opClass),
80                            imm(IMM), rotate(ROTATE << 1), rotated_imm(0),
81                            rotated_carry(0)
82            {
83                rotated_imm = rotate_imm(imm, rotate);
84                if (rotate != 0)
85                    rotated_carry = (rotated_imm >> 31) & 1;
86            }
87
88            std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
89    };
90
91    /**
92     * Base class for predicated integer operations.
93     */
94    class PredIntOp : public PredOp
95    {
96            protected:
97
98            uint32_t shift_size;
99            uint32_t shift;
100
101            /// Constructor
102            PredIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
103                            PredOp(mnem, _machInst, __opClass),
104                            shift_size(SHIFT_SIZE), shift(SHIFT)
105            {
106            }
107
108            std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
109    };
110
111    /**
112     * Base class for predicated macro-operations.
113     */
114    class PredMacroOp : public PredOp
115    {
116            protected:
117
118            uint32_t numMicroops;
119            StaticInstPtr * microOps;
120
121            /// Constructor
122            PredMacroOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
123                            PredOp(mnem, _machInst, __opClass),
124                            numMicroops(0)
125            {
126                // We rely on the subclasses of this object to handle the
127                // initialization of the micro-operations, since they are
128                // all of variable length
129                flags[IsMacroop] = true;
130            }
131
132            ~PredMacroOp()
133            {
134                if (numMicroops)
135                    delete [] microOps;
136            }
137
138            StaticInstPtr fetchMicroop(MicroPC microPC)
139            {
140                assert(microPC < numMicroops);
141                return microOps[microPC];
142            }
143
144            %(BasicExecPanic)s
145
146            std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
147    };
148
149    /**
150     * Base class for predicated micro-operations.
151     */
152    class PredMicroop : public PredOp
153    {
154            /// Constructor
155            PredMicroop(const char *mnem, MachInst _machInst, OpClass __opClass) :
156                            PredOp(mnem, _machInst, __opClass)
157            {
158                flags[IsMicroop] = true;
159            }
160    };
161
162}};
163
164let {{
165    predicateTest = 'testPredicate(Cpsr, condCode)'
166}};
167
168def template PredOpExecute {{
169    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
170    {
171        Fault fault = NoFault;
172        %(op_decl)s;
173        %(op_rd)s;
174
175        if (%(predicate_test)s)
176        {
177            %(fp_enable_check)s;
178            %(code)s;
179            if (fault == NoFault)
180            {
181                %(op_wb)s;
182            }
183        }
184
185        return fault;
186    }
187}};
188
189//Outputs to decoder.cc
190output decoder {{
191    std::string PredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
192    {
193        std::stringstream ss;
194
195        ccprintf(ss, "%-10s ", mnemonic);
196
197        if (_numDestRegs > 0) {
198            printReg(ss, _destRegIdx[0]);
199        }
200
201        ss << ", ";
202
203        if (_numSrcRegs > 0) {
204            printReg(ss, _srcRegIdx[0]);
205            ss << ", ";
206        }
207
208        return ss.str();
209    }
210
211    std::string PredImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
212    {
213        std::stringstream ss;
214
215        ccprintf(ss, "%-10s ", mnemonic);
216
217        if (_numDestRegs > 0) {
218            printReg(ss, _destRegIdx[0]);
219        }
220
221        ss << ", ";
222
223        if (_numSrcRegs > 0) {
224            printReg(ss, _srcRegIdx[0]);
225            ss << ", ";
226        }
227
228        return ss.str();
229    }
230
231    std::string PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
232    {
233        std::stringstream ss;
234
235        ccprintf(ss, "%-10s ", mnemonic);
236
237        if (_numDestRegs > 0) {
238            printReg(ss, _destRegIdx[0]);
239        }
240
241        ss << ", ";
242
243        if (_numSrcRegs > 0) {
244            printReg(ss, _srcRegIdx[0]);
245            ss << ", ";
246        }
247
248        return ss.str();
249    }
250
251    std::string PredMacroOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
252    {
253        std::stringstream ss;
254
255        ccprintf(ss, "%-10s ", mnemonic);
256
257        return ss.str();
258    }
259
260}};
261
262let {{
263
264    calcCcCode = '''
265        uint16_t _ic, _iv, _iz, _in;
266
267        _in = (resTemp >> 31) & 1;
268        _iz = (resTemp == 0);
269        _iv = %(ivValue)s & 1;
270        _ic = %(icValue)s & 1;
271
272        Cpsr =  _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
273            (Cpsr & 0x0FFFFFFF);
274
275        DPRINTF(Arm, "in = %%d\\n", _in);
276        DPRINTF(Arm, "iz = %%d\\n", _iz);
277        DPRINTF(Arm, "ic = %%d\\n", _ic);
278        DPRINTF(Arm, "iv = %%d\\n", _iv);
279        '''
280
281}};
282
283def format PredOp(code, *opt_flags) {{
284    iop = InstObjParams(name, Name, 'PredOp',
285                        {"code": code,
286                         "predicate_test": predicateTest},
287                        opt_flags)
288    header_output = BasicDeclare.subst(iop)
289    decoder_output = BasicConstructor.subst(iop)
290    decode_block = BasicDecode.subst(iop)
291    exec_output = PredOpExecute.subst(iop)
292}};
293
294def format PredImmOp(code, *opt_flags) {{
295    iop = InstObjParams(name, Name, 'PredImmOp',
296                        {"code": code,
297                         "predicate_test": predicateTest},
298                        opt_flags)
299    header_output = BasicDeclare.subst(iop)
300    decoder_output = BasicConstructor.subst(iop)
301    decode_block = BasicDecode.subst(iop)
302    exec_output = PredOpExecute.subst(iop)
303}};
304
305def format PredImmOpCc(code, icValue, ivValue, *opt_flags) {{
306    ccCode = calcCcCode % vars()
307    code += ccCode;
308    iop = InstObjParams(name, Name, 'PredImmOp',
309                        {"code": code,
310                         "cc_code": ccCode,
311                         "predicate_test": predicateTest},
312                        opt_flags)
313    header_output = BasicDeclare.subst(iop)
314    decoder_output = BasicConstructor.subst(iop)
315    decode_block = BasicDecode.subst(iop)
316    exec_output = PredOpExecute.subst(iop)
317}};
318
319def format PredIntOp(code, *opt_flags) {{
320    new_code = ArmGenericCodeSubs(code)
321    iop = InstObjParams(name, Name, 'PredIntOp',
322                        {"code": new_code,
323                         "predicate_test": predicateTest},
324                        opt_flags)
325    header_output = BasicDeclare.subst(iop)
326    decoder_output = BasicConstructor.subst(iop)
327    decode_block = BasicDecode.subst(iop)
328    exec_output = PredOpExecute.subst(iop)
329}};
330
331def format PredIntOpCc(code, icValue, ivValue, *opt_flags) {{
332    ccCode = calcCcCode % vars()
333    code += ccCode;
334    new_code = ArmGenericCodeSubs(code)
335    iop = InstObjParams(name, Name, 'PredIntOp',
336                        {"code": new_code,
337                         "cc_code": ccCode,
338                         "predicate_test": predicateTest},
339                        opt_flags)
340    header_output = BasicDeclare.subst(iop)
341    decoder_output = BasicConstructor.subst(iop)
342    decode_block = BasicDecode.subst(iop)
343    exec_output = PredOpExecute.subst(iop)
344}};
345
346