pred.isa revision 6242:1cee707c1228
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, uint32_t rotateValue)
41    {
42        return ((immValue >> (int)(rotateValue & 31)) |
43                (immValue << (32 - (int)(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
164def template PredOpExecute {{
165    Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
166    {
167        Fault fault = NoFault;
168
169        %(fp_enable_check)s;
170        %(op_decl)s;
171        %(op_rd)s;
172        %(code)s;
173
174        if (testPredicate(xc->readMiscReg(ArmISA::MISCREG_CPSR), condCode))
175        {
176            if (fault == NoFault)
177            {
178                %(op_wb)s;
179            }
180        }
181        else
182            return NoFault;
183            // Predicated false instructions should not return faults
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', code, opt_flags)
285    header_output = BasicDeclare.subst(iop)
286    decoder_output = BasicConstructor.subst(iop)
287    decode_block = BasicDecode.subst(iop)
288    exec_output = PredOpExecute.subst(iop)
289}};
290
291def format PredImmOp(code, *opt_flags) {{
292    iop = InstObjParams(name, Name, 'PredImmOp', code, opt_flags)
293    header_output = BasicDeclare.subst(iop)
294    decoder_output = BasicConstructor.subst(iop)
295    decode_block = BasicDecode.subst(iop)
296    exec_output = PredOpExecute.subst(iop)
297}};
298
299def format PredImmOpCc(code, icValue, ivValue, *opt_flags) {{
300    ccCode = calcCcCode % vars()
301    code += ccCode;
302    iop = InstObjParams(name, Name, 'PredImmOp',
303        {"code": code, "cc_code": ccCode}, opt_flags)
304    header_output = BasicDeclare.subst(iop)
305    decoder_output = BasicConstructor.subst(iop)
306    decode_block = BasicDecode.subst(iop)
307    exec_output = PredOpExecute.subst(iop)
308}};
309
310def format PredIntOp(code, *opt_flags) {{
311    new_code = ArmGenericCodeSubs(code)
312    iop = InstObjParams(name, Name, 'PredIntOp', new_code, 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 PredIntOpCc(code, icValue, ivValue, *opt_flags) {{
320    ccCode = calcCcCode % vars()
321    code += ccCode;
322    new_code = ArmGenericCodeSubs(code)
323    iop = InstObjParams(name, Name, 'PredIntOp',
324        {"code": new_code, "cc_code": ccCode }, 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
331