Deleted Added
sdiff udiff text old ( 7422:feddb9077def ) new ( 7639:8c09b7ff5b57 )
full compact
1/*
2 * Copyright (c) 2010 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2007-2008 The Florida State University
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Stephen Hines
41 */
42#ifndef __ARCH_ARM_INSTS_PREDINST_HH__
43#define __ARCH_ARM_INSTS_PREDINST_HH__
44
45#include "arch/arm/insts/static_inst.hh"
46#include "base/trace.hh"
47
48namespace ArmISA
49{
50static inline uint32_t
51rotate_imm(uint32_t immValue, int rotateValue)
52{
53 return ((immValue >> (rotateValue & 31)) |
54 (immValue << (32 - (rotateValue & 31))));
55}
56
57static inline uint32_t
58modified_imm(uint8_t ctrlImm, uint8_t dataImm)
59{
60 uint32_t bigData = dataImm;
61 uint32_t bigCtrl = ctrlImm;
62 if (bigCtrl < 4) {
63 switch (bigCtrl) {
64 case 0:
65 return bigData;
66 case 1:
67 return bigData | (bigData << 16);
68 case 2:
69 return (bigData << 8) | (bigData << 24);
70 case 3:
71 return (bigData << 0) | (bigData << 8) |
72 (bigData << 16) | (bigData << 24);
73 }
74 }
75 bigCtrl = (bigCtrl << 1) | ((bigData >> 7) & 0x1);
76 bigData |= (1 << 7);
77 return bigData << (32 - bigCtrl);
78}
79
80static inline uint64_t
81simd_modified_imm(bool op, uint8_t cmode, uint8_t data)
82{
83 uint64_t bigData = data;
84 switch (cmode) {
85 case 0x0:
86 case 0x1:
87 bigData = (bigData << 0) | (bigData << 32);
88 break;
89 case 0x2:
90 case 0x3:
91 bigData = (bigData << 8) | (bigData << 40);
92 break;
93 case 0x4:
94 case 0x5:
95 bigData = (bigData << 16) | (bigData << 48);
96 break;
97 case 0x6:
98 case 0x7:
99 bigData = (bigData << 24) | (bigData << 56);
100 break;
101 case 0x8:
102 case 0x9:
103 bigData = (bigData << 0) | (bigData << 16) |
104 (bigData << 32) | (bigData << 48);
105 break;
106 case 0xa:
107 case 0xb:
108 bigData = (bigData << 8) | (bigData << 24) |
109 (bigData << 40) | (bigData << 56);
110 break;
111 case 0xc:
112 bigData = (0xffULL << 0) | (bigData << 8) |
113 (0xffULL << 32) | (bigData << 40);
114 break;
115 case 0xd:
116 bigData = (0xffffULL << 0) | (bigData << 16) |
117 (0xffffULL << 32) | (bigData << 48);
118 break;
119 case 0xe:
120 if (op) {
121 bigData = (bigData << 0) | (bigData << 8) |
122 (bigData << 16) | (bigData << 24) |
123 (bigData << 32) | (bigData << 40) |
124 (bigData << 48) | (bigData << 56);
125 } else {
126 bigData = 0;
127 for (int i = 7; i >= 0; i--) {
128 if (bits(data, i)) {
129 bigData |= (0xFF << (i * 8));
130 }
131 }
132 }
133 case 0xf:
134 if (!op) {
135 uint64_t bVal = bits(bigData, 6) ? (0x1F) : (0x20);
136 bigData = (bits(bigData, 5, 0) << 19) |
137 (bVal << 25) | (bits(bigData, 7) << 31);
138 bigData |= (bigData << 32);
139 }
140 // Fall through
141 default:
142 panic("Illegal modified SIMD immediate parameters.\n");
143 }
144 return bigData;
145}
146
147static inline uint64_t
148vfp_modified_imm(uint8_t data, bool wide)
149{
150 uint64_t bigData = data;
151 uint64_t repData;
152 if (wide) {
153 repData = bits(data, 6) ? 0xFF : 0;
154 bigData = (bits(bigData, 5, 0) << 48) |
155 (repData << 54) | (bits(~bigData, 6) << 62) |
156 (bits(bigData, 7) << 63);
157 } else {
158 repData = bits(data, 6) ? 0x1F : 0;
159 bigData = (bits(bigData, 5, 0) << 19) |
160 (repData << 25) | (bits(~bigData, 6) << 30) |
161 (bits(bigData, 7) << 31);
162 }
163 return bigData;
164}
165
166
167/**
168 * Base class for predicated integer operations.
169 */
170class PredOp : public ArmStaticInst
171{
172 protected:
173
174 ConditionCode condCode;
175
176 /// Constructor
177 PredOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
178 ArmStaticInst(mnem, _machInst, __opClass),
179 condCode(machInst.itstateMask ?
180 (ConditionCode)(uint8_t)machInst.itstateCond :
181 (ConditionCode)(unsigned)machInst.condCode)
182 {
183 }
184};
185
186/**
187 * Base class for predicated immediate operations.
188 */
189class PredImmOp : public PredOp
190{
191 protected:
192
193 uint32_t imm;
194 uint32_t rotated_imm;
195 uint32_t rotated_carry;
196 uint32_t rotate;
197
198 /// Constructor
199 PredImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
200 PredOp(mnem, _machInst, __opClass),
201 imm(machInst.imm), rotated_imm(0), rotated_carry(0),
202 rotate(machInst.rotate << 1)
203 {
204 rotated_imm = rotate_imm(imm, rotate);
205 if (rotate != 0)
206 rotated_carry = bits(rotated_imm, 31);
207 }
208
209 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
210};
211
212/**
213 * Base class for predicated integer operations.
214 */
215class PredIntOp : public PredOp
216{
217 protected:
218
219 uint32_t shift_size;
220 uint32_t shift;
221
222 /// Constructor
223 PredIntOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
224 PredOp(mnem, _machInst, __opClass),
225 shift_size(machInst.shiftSize), shift(machInst.shift)
226 {
227 }
228
229 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
230};
231
232class DataImmOp : public PredOp
233{
234 protected:
235 IntRegIndex dest, op1;
236 uint32_t imm;
237 // Whether the carry flag should be modified if that's an option for
238 // this instruction.
239 bool rotC;
240
241 DataImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
242 IntRegIndex _dest, IntRegIndex _op1, uint32_t _imm, bool _rotC) :
243 PredOp(mnem, _machInst, __opClass),
244 dest(_dest), op1(_op1), imm(_imm), rotC(_rotC)
245 {}
246
247 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
248};
249
250class DataRegOp : public PredOp
251{
252 protected:
253 IntRegIndex dest, op1, op2;
254 int32_t shiftAmt;
255 ArmShiftType shiftType;
256
257 DataRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
258 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
259 int32_t _shiftAmt, ArmShiftType _shiftType) :
260 PredOp(mnem, _machInst, __opClass),
261 dest(_dest), op1(_op1), op2(_op2),
262 shiftAmt(_shiftAmt), shiftType(_shiftType)
263 {}
264
265 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
266};
267
268class DataRegRegOp : public PredOp
269{
270 protected:
271 IntRegIndex dest, op1, op2, shift;
272 ArmShiftType shiftType;
273
274 DataRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
275 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
276 IntRegIndex _shift, ArmShiftType _shiftType) :
277 PredOp(mnem, _machInst, __opClass),
278 dest(_dest), op1(_op1), op2(_op2), shift(_shift),
279 shiftType(_shiftType)
280 {}
281
282 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
283};
284
285/**
286 * Base class for predicated macro-operations.
287 */
288class PredMacroOp : public PredOp
289{
290 protected:
291
292 uint32_t numMicroops;
293 StaticInstPtr * microOps;
294
295 /// Constructor
296 PredMacroOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
297 PredOp(mnem, _machInst, __opClass),
298 numMicroops(0)
299 {
300 // We rely on the subclasses of this object to handle the
301 // initialization of the micro-operations, since they are
302 // all of variable length
303 flags[IsMacroop] = true;
304 }
305
306 ~PredMacroOp()
307 {
308 if (numMicroops)
309 delete [] microOps;
310 }
311
312 StaticInstPtr
313 fetchMicroop(MicroPC microPC)
314 {
315 assert(microPC < numMicroops);
316 return microOps[microPC];
317 }
318
319 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
320};
321
322/**
323 * Base class for predicated micro-operations.
324 */
325class PredMicroop : public PredOp
326{
327 /// Constructor
328 PredMicroop(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
329 PredOp(mnem, _machInst, __opClass)
330 {
331 flags[IsMicroop] = true;
332 }
333};
334}
335
336#endif //__ARCH_ARM_INSTS_PREDINST_HH__