pred.isa revision 6251:1d794d81a4e6
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)(unsigned)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            %(code)s;
178            if (fault == NoFault)
179            {
180                %(op_wb)s;
181            }
182        }
183
184        return fault;
185    }
186}};
187
188//Outputs to decoder.cc
189output decoder {{
190    std::string PredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
191    {
192        std::stringstream ss;
193
194        ccprintf(ss, "%-10s ", mnemonic);
195
196        if (_numDestRegs > 0) {
197            printReg(ss, _destRegIdx[0]);
198        }
199
200        ss << ", ";
201
202        if (_numSrcRegs > 0) {
203            printReg(ss, _srcRegIdx[0]);
204            ss << ", ";
205        }
206
207        return ss.str();
208    }
209
210    std::string PredImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
211    {
212        std::stringstream ss;
213
214        ccprintf(ss, "%-10s ", mnemonic);
215
216        if (_numDestRegs > 0) {
217            printReg(ss, _destRegIdx[0]);
218        }
219
220        ss << ", ";
221
222        if (_numSrcRegs > 0) {
223            printReg(ss, _srcRegIdx[0]);
224            ss << ", ";
225        }
226
227        return ss.str();
228    }
229
230    std::string PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
231    {
232        std::stringstream ss;
233
234        ccprintf(ss, "%-10s ", mnemonic);
235
236        if (_numDestRegs > 0) {
237            printReg(ss, _destRegIdx[0]);
238        }
239
240        ss << ", ";
241
242        if (_numSrcRegs > 0) {
243            printReg(ss, _srcRegIdx[0]);
244            ss << ", ";
245        }
246
247        return ss.str();
248    }
249
250    std::string PredMacroOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
251    {
252        std::stringstream ss;
253
254        ccprintf(ss, "%-10s ", mnemonic);
255
256        return ss.str();
257    }
258
259}};
260
261let {{
262
263    calcCcCode = '''
264        uint16_t _ic, _iv, _iz, _in;
265
266        _in = (resTemp >> 31) & 1;
267        _iz = (resTemp == 0);
268        _iv = %(ivValue)s & 1;
269        _ic = %(icValue)s & 1;
270
271        Cpsr =  _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
272            (Cpsr & 0x0FFFFFFF);
273
274        DPRINTF(Arm, "in = %%d\\n", _in);
275        DPRINTF(Arm, "iz = %%d\\n", _iz);
276        DPRINTF(Arm, "ic = %%d\\n", _ic);
277        DPRINTF(Arm, "iv = %%d\\n", _iv);
278        '''
279
280}};
281
282def format PredOp(code, *opt_flags) {{
283    iop = InstObjParams(name, Name, 'PredOp',
284                        {"code": code,
285                         "predicate_test": predicateTest},
286                        opt_flags)
287    header_output = BasicDeclare.subst(iop)
288    decoder_output = BasicConstructor.subst(iop)
289    decode_block = BasicDecode.subst(iop)
290    exec_output = PredOpExecute.subst(iop)
291}};
292
293def format PredImmOp(code, *opt_flags) {{
294    iop = InstObjParams(name, Name, 'PredImmOp',
295                        {"code": code,
296                         "predicate_test": predicateTest},
297                        opt_flags)
298    header_output = BasicDeclare.subst(iop)
299    decoder_output = BasicConstructor.subst(iop)
300    decode_block = BasicDecode.subst(iop)
301    exec_output = PredOpExecute.subst(iop)
302}};
303
304def format PredImmOpCc(code, icValue, ivValue, *opt_flags) {{
305    ccCode = calcCcCode % vars()
306    code += ccCode;
307    iop = InstObjParams(name, Name, 'PredImmOp',
308                        {"code": code,
309                         "cc_code": ccCode,
310                         "predicate_test": predicateTest},
311                        opt_flags)
312    header_output = BasicDeclare.subst(iop)
313    decoder_output = BasicConstructor.subst(iop)
314    decode_block = BasicDecode.subst(iop)
315    exec_output = PredOpExecute.subst(iop)
316}};
317
318def format PredIntOp(code, *opt_flags) {{
319    new_code = ArmGenericCodeSubs(code)
320    iop = InstObjParams(name, Name, 'PredIntOp',
321                        {"code": new_code,
322                         "predicate_test": predicateTest},
323                        opt_flags)
324    header_output = BasicDeclare.subst(iop)
325    decoder_output = BasicConstructor.subst(iop)
326    decode_block = BasicDecode.subst(iop)
327    exec_output = PredOpExecute.subst(iop)
328}};
329
330def format PredIntOpCc(code, icValue, ivValue, *opt_flags) {{
331    ccCode = calcCcCode % vars()
332    code += ccCode;
333    new_code = ArmGenericCodeSubs(code)
334    iop = InstObjParams(name, Name, 'PredIntOp',
335                        {"code": new_code,
336                         "cc_code": ccCode,
337                         "predicate_test": predicateTest},
338                        opt_flags)
339    header_output = BasicDeclare.subst(iop)
340    decoder_output = BasicConstructor.subst(iop)
341    decode_block = BasicDecode.subst(iop)
342    exec_output = PredOpExecute.subst(iop)
343}};
344
345