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