3 // Copyright (c) 2007-2008 The Florida State University
4 // All rights reserved.
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.
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.
29 // Authors: Stephen Hines
31 ////////////////////////////////////////////////////////////////////
33 // Predicated Instruction Execution
39 enum ArmPredicateBits {
59 rotate_imm(uint32_t immValue, uint32_t rotateValue)
61 return ((immValue >> (int)(rotateValue & 31)) |
62 (immValue << (32 - (int)(rotateValue & 31))));
65 inline uint32_t nSet(uint32_t cpsr) { return cpsr & (1<<31); }
66 inline uint32_t zSet(uint32_t cpsr) { return cpsr & (1<<30); }
67 inline uint32_t cSet(uint32_t cpsr) { return cpsr & (1<<29); }
68 inline uint32_t vSet(uint32_t cpsr) { return cpsr & (1<<28); }
70 inline bool arm_predicate(uint32_t cpsr, uint32_t predBits)
73 enum ArmPredicateBits armPredBits = (enum ArmPredicateBits) predBits;
78 result = zSet(cpsr); break;
80 result = !zSet(cpsr); break;
82 result = cSet(cpsr); break;
84 result = !cSet(cpsr); break;
86 result = nSet(cpsr); break;
88 result = !nSet(cpsr); break;
90 result = vSet(cpsr); break;
92 result = !vSet(cpsr); break;
94 result = cSet(cpsr) && !zSet(cpsr); break;
96 result = !cSet(cpsr) || zSet(cpsr); break;
98 result = (!nSet(cpsr) && !vSet(cpsr)) || (nSet(cpsr) && vSet(cpsr)); break;
100 result = (nSet(cpsr) && !vSet(cpsr)) || (!nSet(cpsr) && vSet(cpsr)); break;
102 result = (!nSet(cpsr) && !vSet(cpsr) && !zSet(cpsr)) || (nSet(cpsr) && vSet(cpsr) && !zSet(cpsr)); break;
104 result = (nSet(cpsr) && !vSet(cpsr)) || (!nSet(cpsr) && vSet(cpsr)) || zSet(cpsr); break;
105 case COND_AL: result = 1; break;
106 case COND_NV: result = 0; break;
108 fprintf(stderr, "Unhandled predicate condition: %d\n", armPredBits);
119 * Base class for predicated integer operations.
121 class PredOp : public ArmStaticInst
128 PredOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
129 ArmStaticInst(mnem, _machInst, __opClass),
134 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
138 * Base class for predicated immediate operations.
140 class PredImmOp : public PredOp
146 uint32_t rotated_imm;
147 uint32_t rotated_carry;
150 PredImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
151 PredOp(mnem, _machInst, __opClass),
152 imm(IMM), rotate(ROTATE << 1), rotated_imm(0),
155 rotated_imm = rotate_imm(imm, rotate);
157 rotated_carry = (rotated_imm >> 31) & 1;
160 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
164 * Base class for predicated integer operations.
166 class PredIntOp : public PredOp
174 PredIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
175 PredOp(mnem, _machInst, __opClass),
176 shift_size(SHIFT_SIZE), shift(SHIFT)
180 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
184 * Base class for predicated macro-operations.
186 class PredMacroOp : public PredOp
190 uint32_t numMicroops;
191 StaticInstPtr * microOps;
194 PredMacroOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
195 PredOp(mnem, _machInst, __opClass),
198 // We rely on the subclasses of this object to handle the
199 // initialization of the micro-operations, since they are
200 // all of variable length
201 flags[IsMacroop] = true;
210 StaticInstPtr fetchMicroop(MicroPC microPC)
212 assert(microPC < numMicroops);
213 return microOps[microPC];
218 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
222 * Base class for predicated micro-operations.
224 class PredMicroop : public PredOp
227 PredMicroop(const char *mnem, MachInst _machInst, OpClass __opClass) :
228 PredOp(mnem, _machInst, __opClass)
230 flags[IsMicroop] = true;
236 def template PredOpExecute {{
237 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
239 Fault fault = NoFault;
246 if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
248 if (fault == NoFault)
255 // Predicated false instructions should not return faults
261 //Outputs to decoder.cc
263 std::string PredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
265 std::stringstream ss;
267 ccprintf(ss, "%-10s ", mnemonic);
269 if (_numDestRegs > 0) {
270 printReg(ss, _destRegIdx[0]);
275 if (_numSrcRegs > 0) {
276 printReg(ss, _srcRegIdx[0]);
283 std::string PredImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
285 std::stringstream ss;
287 ccprintf(ss, "%-10s ", mnemonic);
289 if (_numDestRegs > 0) {
290 printReg(ss, _destRegIdx[0]);
295 if (_numSrcRegs > 0) {
296 printReg(ss, _srcRegIdx[0]);
303 std::string PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
305 std::stringstream ss;
307 ccprintf(ss, "%-10s ", mnemonic);
309 if (_numDestRegs > 0) {
310 printReg(ss, _destRegIdx[0]);
315 if (_numSrcRegs > 0) {
316 printReg(ss, _srcRegIdx[0]);
323 std::string PredMacroOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
325 std::stringstream ss;
327 ccprintf(ss, "%-10s ", mnemonic);
337 uint16_t _ic, _iv, _iz, _in;
339 _in = (resTemp >> 31) & 1;
340 _iz = (resTemp == 0);
341 _iv = %(ivValue)s & 1;
342 _ic = %(icValue)s & 1;
344 Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 |
347 DPRINTF(Arm, "in = %%d\\n", _in);
348 DPRINTF(Arm, "iz = %%d\\n", _iz);
349 DPRINTF(Arm, "ic = %%d\\n", _ic);
350 DPRINTF(Arm, "iv = %%d\\n", _iv);
355 def format PredOp(code, *opt_flags) {{
356 iop = InstObjParams(name, Name, 'PredOp', code, opt_flags)
357 header_output = BasicDeclare.subst(iop)
358 decoder_output = BasicConstructor.subst(iop)
359 decode_block = BasicDecode.subst(iop)
360 exec_output = PredOpExecute.subst(iop)
363 def format PredImmOp(code, *opt_flags) {{
364 iop = InstObjParams(name, Name, 'PredImmOp', code, opt_flags)
365 header_output = BasicDeclare.subst(iop)
366 decoder_output = BasicConstructor.subst(iop)
367 decode_block = BasicDecode.subst(iop)
368 exec_output = PredOpExecute.subst(iop)
371 def format PredImmOpCc(code, icValue, ivValue, *opt_flags) {{
372 ccCode = calcCcCode % vars()
374 iop = InstObjParams(name, Name, 'PredImmOp',
375 {"code": code, "cc_code": ccCode}, opt_flags)
376 header_output = BasicDeclare.subst(iop)
377 decoder_output = BasicConstructor.subst(iop)
378 decode_block = BasicDecode.subst(iop)
379 exec_output = PredOpExecute.subst(iop)
382 def format PredIntOp(code, *opt_flags) {{
383 new_code = ArmGenericCodeSubs(code)
384 iop = InstObjParams(name, Name, 'PredIntOp', new_code, opt_flags)
385 header_output = BasicDeclare.subst(iop)
386 decoder_output = BasicConstructor.subst(iop)
387 decode_block = BasicDecode.subst(iop)
388 exec_output = PredOpExecute.subst(iop)
391 def format PredIntOpCc(code, icValue, ivValue, *opt_flags) {{
392 ccCode = calcCcCode % vars()
394 new_code = ArmGenericCodeSubs(code)
395 iop = InstObjParams(name, Name, 'PredIntOp',
396 {"code": new_code, "cc_code": ccCode }, opt_flags)
397 header_output = BasicDeclare.subst(iop)
398 decoder_output = BasicConstructor.subst(iop)
399 decode_block = BasicDecode.subst(iop)
400 exec_output = PredOpExecute.subst(iop)