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 = 0;
122 for (int i = 7; i >= 0; i--) {
123 if (bits(data, i)) {
124 bigData |= (ULL(0xFF) << (i * 8));
125 }
126 }
127 } else {
128 bigData = (bigData << 0) | (bigData << 8) |
129 (bigData << 16) | (bigData << 24) |
130 (bigData << 32) | (bigData << 40) |
131 (bigData << 48) | (bigData << 56);
132 }
133 break;
134 case 0xf:
135 if (!op) {
136 uint64_t bVal = bits(bigData, 6) ? (0x1F) : (0x20);
137 bigData = (bits(bigData, 5, 0) << 19) |
138 (bVal << 25) | (bits(bigData, 7) << 31);
139 bigData |= (bigData << 32);
140 break;
141 }
142 // Fall through
143 default:
144 panic("Illegal modified SIMD immediate parameters.\n");
145 }
146 return bigData;
147}
148
149static inline uint64_t
150vfp_modified_imm(uint8_t data, bool wide)
151{
152 uint64_t bigData = data;
153 uint64_t repData;
154 if (wide) {
155 repData = bits(data, 6) ? 0xFF : 0;
156 bigData = (bits(bigData, 5, 0) << 48) |
157 (repData << 54) | (bits(~bigData, 6) << 62) |
158 (bits(bigData, 7) << 63);
159 } else {
160 repData = bits(data, 6) ? 0x1F : 0;
161 bigData = (bits(bigData, 5, 0) << 19) |
162 (repData << 25) | (bits(~bigData, 6) << 30) |
163 (bits(bigData, 7) << 31);
164 }
165 return bigData;
166}
167
168
169/**
170 * Base class for predicated integer operations.
171 */
172class PredOp : public ArmStaticInst
173{
174 protected:
175
176 ConditionCode condCode;
177
178 /// Constructor
179 PredOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
180 ArmStaticInst(mnem, _machInst, __opClass),
181 condCode(machInst.itstateMask ?
182 (ConditionCode)(uint8_t)machInst.itstateCond :
183 (ConditionCode)(unsigned)machInst.condCode)
184 {
185 }
186};
187
188/**
189 * Base class for predicated immediate operations.
190 */
191class PredImmOp : public PredOp
192{
193 protected:
194
195 uint32_t imm;
196 uint32_t rotated_imm;
197 uint32_t rotated_carry;
198 uint32_t rotate;
199
200 /// Constructor
201 PredImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
202 PredOp(mnem, _machInst, __opClass),
203 imm(machInst.imm), rotated_imm(0), rotated_carry(0),
204 rotate(machInst.rotate << 1)
205 {
206 rotated_imm = rotate_imm(imm, rotate);
207 if (rotate != 0)
208 rotated_carry = bits(rotated_imm, 31);
209 }
210
211 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
212};
213
214/**
215 * Base class for predicated integer operations.
216 */
217class PredIntOp : public PredOp
218{
219 protected:
220
221 uint32_t shift_size;
222 uint32_t shift;
223
224 /// Constructor
225 PredIntOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
226 PredOp(mnem, _machInst, __opClass),
227 shift_size(machInst.shiftSize), shift(machInst.shift)
228 {
229 }
230
231 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
232};
233
234class DataImmOp : public PredOp
235{
236 protected:
237 IntRegIndex dest, op1;
238 uint32_t imm;
239 // Whether the carry flag should be modified if that's an option for
240 // this instruction.
241 bool rotC;
242
243 DataImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
244 IntRegIndex _dest, IntRegIndex _op1, uint32_t _imm, bool _rotC) :
245 PredOp(mnem, _machInst, __opClass),
246 dest(_dest), op1(_op1), imm(_imm), rotC(_rotC)
247 {}
248
249 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
250};
251
252class DataRegOp : public PredOp
253{
254 protected:
255 IntRegIndex dest, op1, op2;
256 int32_t shiftAmt;
257 ArmShiftType shiftType;
258
259 DataRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
260 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
261 int32_t _shiftAmt, ArmShiftType _shiftType) :
262 PredOp(mnem, _machInst, __opClass),
263 dest(_dest), op1(_op1), op2(_op2),
264 shiftAmt(_shiftAmt), shiftType(_shiftType)
265 {}
266
267 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
268};
269
270class DataRegRegOp : public PredOp
271{
272 protected:
273 IntRegIndex dest, op1, op2, shift;
274 ArmShiftType shiftType;
275
276 DataRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
277 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
278 IntRegIndex _shift, ArmShiftType _shiftType) :
279 PredOp(mnem, _machInst, __opClass),
280 dest(_dest), op1(_op1), op2(_op2), shift(_shift),
281 shiftType(_shiftType)
282 {}
283
284 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
285};
286
287/**
288 * Base class for predicated macro-operations.
289 */
290class PredMacroOp : public PredOp
291{
292 protected:
293
294 uint32_t numMicroops;
295 StaticInstPtr * microOps;
296
297 /// Constructor
298 PredMacroOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
299 PredOp(mnem, _machInst, __opClass),
300 numMicroops(0)
301 {
302 // We rely on the subclasses of this object to handle the
303 // initialization of the micro-operations, since they are
304 // all of variable length
305 flags[IsMacroop] = true;
306 }
307
308 ~PredMacroOp()
309 {
310 if (numMicroops)
311 delete [] microOps;
312 }
313
314 StaticInstPtr
315 fetchMicroop(MicroPC microPC)
316 {
317 assert(microPC < numMicroops);
318 return microOps[microPC];
319 }
320
321 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
322};
323
324/**
325 * Base class for predicated micro-operations.
326 */
327class PredMicroop : public PredOp
328{
329 /// Constructor
330 PredMicroop(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
331 PredOp(mnem, _machInst, __opClass)
332 {
333 flags[IsMicroop] = true;
334 }
335};
336}
337
338#endif //__ARCH_ARM_INSTS_PREDINST_HH__