pred.isa (6251:1d794d81a4e6) pred.isa (6253:988a001820f8)
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
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
36let {{
37 predicateTest = 'testPredicate(Cpsr, condCode)'
38}};
39
40def template PredOpExecute {{
41 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
42 {
43 Fault fault = NoFault;
44 %(op_decl)s;
45 %(op_rd)s;
46
47 if (%(predicate_test)s)
48 {
49 %(code)s;
50 if (fault == NoFault)
51 {
52 %(op_wb)s;
53 }
54 }
55
56 return fault;
57 }
58}};
59
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
60let {{
61
62 calcCcCode = '''
63 uint16_t _ic, _iv, _iz, _in;
64
65 _in = (resTemp >> 31) & 1;
66 _iz = (resTemp == 0);
67 _iv = %(ivValue)s & 1;
68 _ic = %(icValue)s & 1;
69
70 Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
71 (Cpsr & 0x0FFFFFFF);
72
73 DPRINTF(Arm, "in = %%d\\n", _in);
74 DPRINTF(Arm, "iz = %%d\\n", _iz);
75 DPRINTF(Arm, "ic = %%d\\n", _ic);
76 DPRINTF(Arm, "iv = %%d\\n", _iv);
77 '''
78
79}};
80
81def format PredOp(code, *opt_flags) {{
82 iop = InstObjParams(name, Name, 'PredOp',
83 {"code": code,
84 "predicate_test": predicateTest},
85 opt_flags)
86 header_output = BasicDeclare.subst(iop)
87 decoder_output = BasicConstructor.subst(iop)
88 decode_block = BasicDecode.subst(iop)
89 exec_output = PredOpExecute.subst(iop)
90}};
91
92def format PredImmOp(code, *opt_flags) {{
93 iop = InstObjParams(name, Name, 'PredImmOp',
94 {"code": code,
95 "predicate_test": predicateTest},
96 opt_flags)
97 header_output = BasicDeclare.subst(iop)
98 decoder_output = BasicConstructor.subst(iop)
99 decode_block = BasicDecode.subst(iop)
100 exec_output = PredOpExecute.subst(iop)
101}};
102
103def format PredImmOpCc(code, icValue, ivValue, *opt_flags) {{
104 ccCode = calcCcCode % vars()
105 code += ccCode;
106 iop = InstObjParams(name, Name, 'PredImmOp',
107 {"code": code,
108 "cc_code": ccCode,
109 "predicate_test": predicateTest},
110 opt_flags)
111 header_output = BasicDeclare.subst(iop)
112 decoder_output = BasicConstructor.subst(iop)
113 decode_block = BasicDecode.subst(iop)
114 exec_output = PredOpExecute.subst(iop)
115}};
116
117def format PredIntOp(code, *opt_flags) {{
118 new_code = ArmGenericCodeSubs(code)
119 iop = InstObjParams(name, Name, 'PredIntOp',
120 {"code": new_code,
121 "predicate_test": predicateTest},
122 opt_flags)
123 header_output = BasicDeclare.subst(iop)
124 decoder_output = BasicConstructor.subst(iop)
125 decode_block = BasicDecode.subst(iop)
126 exec_output = PredOpExecute.subst(iop)
127}};
128
129def format PredIntOpCc(code, icValue, ivValue, *opt_flags) {{
130 ccCode = calcCcCode % vars()
131 code += ccCode;
132 new_code = ArmGenericCodeSubs(code)
133 iop = InstObjParams(name, Name, 'PredIntOp',
134 {"code": new_code,
135 "cc_code": ccCode,
136 "predicate_test": predicateTest},
137 opt_flags)
138 header_output = BasicDeclare.subst(iop)
139 decoder_output = BasicConstructor.subst(iop)
140 decode_block = BasicDecode.subst(iop)
141 exec_output = PredOpExecute.subst(iop)
142}};
143