blob: 702e03a2770c696d0517a9537d1a138442242ba4 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Carl Shapiroa2e18e12011-06-21 18:57:55 -070016
Ian Rogers166db042013-07-26 12:05:57 -070017#ifndef ART_COMPILER_UTILS_ARM_CONSTANTS_ARM_H_
18#define ART_COMPILER_UTILS_ARM_CONSTANTS_ARM_H_
Carl Shapiroa2e18e12011-06-21 18:57:55 -070019
20#include <stdint.h>
Elliott Hughes07ed66b2012-12-12 18:34:25 -080021
Ian Rogersb033c752011-07-20 12:22:35 -070022#include <iosfwd>
Elliott Hughes07ed66b2012-12-12 18:34:25 -080023
Ian Rogers166db042013-07-26 12:05:57 -070024#include "arch/arm/registers_arm.h"
Elliott Hughes1aa246d2012-12-13 09:29:36 -080025#include "base/casts.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080026#include "base/logging.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070027#include "globals.h"
Carl Shapiroa2e18e12011-06-21 18:57:55 -070028
29namespace art {
Ian Rogers2c8f6532011-09-02 17:16:34 -070030namespace arm {
Carl Shapiroa2e18e12011-06-21 18:57:55 -070031
32// Defines constants and accessor classes to assemble, disassemble and
33// simulate ARM instructions.
34//
35// Section references in the code refer to the "ARM Architecture Reference
36// Manual" from July 2005 (available at http://www.arm.com/miscPDFs/14128.pdf)
37//
38// Constants for specific fields are defined in their respective named enums.
39// General constants are in an anonymous enum in class Instr.
40
41
42// We support both VFPv3-D16 and VFPv3-D32 profiles, but currently only one at
43// a time, so that compile time optimizations can be applied.
44// Warning: VFPv3-D32 is untested.
45#define VFPv3_D16
46#if defined(VFPv3_D16) == defined(VFPv3_D32)
47#error "Exactly one of VFPv3_D16 or VFPv3_D32 can be defined at a time."
48#endif
49
Nicolas Geoffray19a19cf2014-10-22 16:07:05 +010050// 4 bits option for the dmb instruction.
51// Order and values follows those of the ARM Architecture Reference Manual.
52enum DmbOptions {
53 SY = 0xf,
54 ST = 0xe,
55 ISH = 0xb,
56 ISHST = 0xa,
57 NSH = 0x7,
58 NSHST = 0x6
59};
Carl Shapiroa2e18e12011-06-21 18:57:55 -070060
Carl Shapiroa2e18e12011-06-21 18:57:55 -070061enum ScaleFactor {
62 TIMES_1 = 0,
63 TIMES_2 = 1,
64 TIMES_4 = 2,
65 TIMES_8 = 3
66};
67
Carl Shapiroa2e18e12011-06-21 18:57:55 -070068// Values for double-precision floating point registers.
69enum DRegister {
70 D0 = 0,
71 D1 = 1,
72 D2 = 2,
73 D3 = 3,
74 D4 = 4,
75 D5 = 5,
76 D6 = 6,
77 D7 = 7,
78 D8 = 8,
79 D9 = 9,
80 D10 = 10,
81 D11 = 11,
82 D12 = 12,
83 D13 = 13,
84 D14 = 14,
85 D15 = 15,
86#ifdef VFPv3_D16
87 kNumberOfDRegisters = 16,
88#else
89 D16 = 16,
90 D17 = 17,
91 D18 = 18,
92 D19 = 19,
93 D20 = 20,
94 D21 = 21,
95 D22 = 22,
96 D23 = 23,
97 D24 = 24,
98 D25 = 25,
99 D26 = 26,
100 D27 = 27,
101 D28 = 28,
102 D29 = 29,
103 D30 = 30,
104 D31 = 31,
105 kNumberOfDRegisters = 32,
106#endif
107 kNumberOfOverlappingDRegisters = 16,
108 kNoDRegister = -1,
109};
Elliott Hughes1f359b02011-07-17 14:27:17 -0700110std::ostream& operator<<(std::ostream& os, const DRegister& rhs);
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700111
112
113// Values for the condition field as defined in section A3.2.
114enum Condition {
115 kNoCondition = -1,
116 EQ = 0, // equal
117 NE = 1, // not equal
118 CS = 2, // carry set/unsigned higher or same
119 CC = 3, // carry clear/unsigned lower
120 MI = 4, // minus/negative
121 PL = 5, // plus/positive or zero
122 VS = 6, // overflow
123 VC = 7, // no overflow
124 HI = 8, // unsigned higher
125 LS = 9, // unsigned lower or same
126 GE = 10, // signed greater than or equal
127 LT = 11, // signed less than
128 GT = 12, // signed greater than
129 LE = 13, // signed less than or equal
130 AL = 14, // always (unconditional)
131 kSpecialCondition = 15, // special condition (refer to section A3.2.1)
132 kMaxCondition = 16,
133};
Elliott Hughes1f359b02011-07-17 14:27:17 -0700134std::ostream& operator<<(std::ostream& os, const Condition& rhs);
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700135
136
137// Opcodes for Data-processing instructions (instructions with a type 0 and 1)
138// as defined in section A3.4
139enum Opcode {
140 kNoOperand = -1,
141 AND = 0, // Logical AND
142 EOR = 1, // Logical Exclusive OR
143 SUB = 2, // Subtract
144 RSB = 3, // Reverse Subtract
145 ADD = 4, // Add
146 ADC = 5, // Add with Carry
147 SBC = 6, // Subtract with Carry
148 RSC = 7, // Reverse Subtract with Carry
149 TST = 8, // Test
150 TEQ = 9, // Test Equivalence
151 CMP = 10, // Compare
152 CMN = 11, // Compare Negated
153 ORR = 12, // Logical (inclusive) OR
154 MOV = 13, // Move
155 BIC = 14, // Bit Clear
156 MVN = 15, // Move Not
157 kMaxOperand = 16
158};
159
160
161// Shifter types for Data-processing operands as defined in section A5.1.2.
162enum Shift {
163 kNoShift = -1,
164 LSL = 0, // Logical shift left
165 LSR = 1, // Logical shift right
166 ASR = 2, // Arithmetic shift right
167 ROR = 3, // Rotate right
Dave Allison65fcc2c2014-04-28 13:45:27 -0700168 RRX = 4, // Rotate right with extend.
169 kMaxShift
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700170};
171
172
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700173// Constants used for the decoding or encoding of the individual fields of
174// instructions. Based on the "Figure 3-1 ARM instruction set summary".
175enum InstructionFields {
176 kConditionShift = 28,
177 kConditionBits = 4,
178 kTypeShift = 25,
179 kTypeBits = 3,
180 kLinkShift = 24,
181 kLinkBits = 1,
182 kUShift = 23,
183 kUBits = 1,
184 kOpcodeShift = 21,
185 kOpcodeBits = 4,
186 kSShift = 20,
187 kSBits = 1,
188 kRnShift = 16,
189 kRnBits = 4,
190 kRdShift = 12,
191 kRdBits = 4,
192 kRsShift = 8,
193 kRsBits = 4,
194 kRmShift = 0,
195 kRmBits = 4,
196
197 // Immediate instruction fields encoding.
198 kRotateShift = 8,
199 kRotateBits = 4,
200 kImmed8Shift = 0,
201 kImmed8Bits = 8,
202
203 // Shift instruction register fields encodings.
204 kShiftImmShift = 7,
205 kShiftRegisterShift = 8,
206 kShiftImmBits = 5,
207 kShiftShift = 5,
208 kShiftBits = 2,
209
210 // Load/store instruction offset field encoding.
211 kOffset12Shift = 0,
212 kOffset12Bits = 12,
213 kOffset12Mask = 0x00000fff,
214
215 // Mul instruction register fields encodings.
216 kMulRdShift = 16,
217 kMulRdBits = 4,
218 kMulRnShift = 12,
219 kMulRnBits = 4,
220
221 kBranchOffsetMask = 0x00ffffff
222};
223
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700224// Size (in bytes) of registers.
225const int kRegisterSize = 4;
226
227// List of registers used in load/store multiple.
228typedef uint16_t RegList;
229
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700230// The class Instr enables access to individual fields defined in the ARM
231// architecture instruction set encoding as described in figure A3-1.
232//
233// Example: Test whether the instruction at ptr does set the condition code
234// bits.
235//
Ian Rogers13735952014-10-08 12:43:28 -0700236// bool InstructionSetsConditionCodes(uint8_t* ptr) {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700237// Instr* instr = Instr::At(ptr);
238// int type = instr->TypeField();
239// return ((type == 0) || (type == 1)) && instr->HasS();
240// }
241//
242class Instr {
243 public:
244 enum {
245 kInstrSize = 4,
246 kInstrSizeLog2 = 2,
247 kPCReadOffset = 8
248 };
249
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700250 bool IsBreakPoint() {
251 return IsBkpt();
252 }
253
254 // Get the raw instruction bits.
Ian Rogersdd7624d2014-03-14 17:43:00 -0700255 int32_t InstructionBits() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700256 return *reinterpret_cast<const int32_t*>(this);
257 }
258
259 // Set the raw instruction bits to value.
Ian Rogersdd7624d2014-03-14 17:43:00 -0700260 void SetInstructionBits(int32_t value) {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700261 *reinterpret_cast<int32_t*>(this) = value;
262 }
263
264 // Read one particular bit out of the instruction bits.
Ian Rogersdd7624d2014-03-14 17:43:00 -0700265 int Bit(int nr) const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700266 return (InstructionBits() >> nr) & 1;
267 }
268
269 // Read a bit field out of the instruction bits.
Ian Rogersdd7624d2014-03-14 17:43:00 -0700270 int Bits(int shift, int count) const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700271 return (InstructionBits() >> shift) & ((1 << count) - 1);
272 }
273
274
275 // Accessors for the different named fields used in the ARM encoding.
276 // The naming of these accessor corresponds to figure A3-1.
277 // Generally applicable fields
Ian Rogersdd7624d2014-03-14 17:43:00 -0700278 Condition ConditionField() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700279 return static_cast<Condition>(Bits(kConditionShift, kConditionBits));
280 }
Ian Rogersdd7624d2014-03-14 17:43:00 -0700281 int TypeField() const { return Bits(kTypeShift, kTypeBits); }
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700282
Ian Rogersdd7624d2014-03-14 17:43:00 -0700283 Register RnField() const { return static_cast<Register>(
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700284 Bits(kRnShift, kRnBits)); }
Ian Rogersdd7624d2014-03-14 17:43:00 -0700285 Register RdField() const { return static_cast<Register>(
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700286 Bits(kRdShift, kRdBits)); }
287
288 // Fields used in Data processing instructions
Ian Rogersdd7624d2014-03-14 17:43:00 -0700289 Opcode OpcodeField() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700290 return static_cast<Opcode>(Bits(kOpcodeShift, kOpcodeBits));
291 }
Ian Rogersdd7624d2014-03-14 17:43:00 -0700292 int SField() const { return Bits(kSShift, kSBits); }
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700293 // with register
Ian Rogersdd7624d2014-03-14 17:43:00 -0700294 Register RmField() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700295 return static_cast<Register>(Bits(kRmShift, kRmBits));
296 }
Ian Rogersdd7624d2014-03-14 17:43:00 -0700297 Shift ShiftField() const { return static_cast<Shift>(
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700298 Bits(kShiftShift, kShiftBits)); }
Ian Rogersdd7624d2014-03-14 17:43:00 -0700299 int RegShiftField() const { return Bit(4); }
300 Register RsField() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700301 return static_cast<Register>(Bits(kRsShift, kRsBits));
302 }
Ian Rogersdd7624d2014-03-14 17:43:00 -0700303 int ShiftAmountField() const { return Bits(kShiftImmShift,
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700304 kShiftImmBits); }
305 // with immediate
Ian Rogersdd7624d2014-03-14 17:43:00 -0700306 int RotateField() const { return Bits(kRotateShift, kRotateBits); }
307 int Immed8Field() const { return Bits(kImmed8Shift, kImmed8Bits); }
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700308
309 // Fields used in Load/Store instructions
Ian Rogersdd7624d2014-03-14 17:43:00 -0700310 int PUField() const { return Bits(23, 2); }
311 int BField() const { return Bit(22); }
312 int WField() const { return Bit(21); }
313 int LField() const { return Bit(20); }
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700314 // with register uses same fields as Data processing instructions above
315 // with immediate
Ian Rogersdd7624d2014-03-14 17:43:00 -0700316 int Offset12Field() const { return Bits(kOffset12Shift,
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700317 kOffset12Bits); }
318 // multiple
Ian Rogersdd7624d2014-03-14 17:43:00 -0700319 int RlistField() const { return Bits(0, 16); }
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700320 // extra loads and stores
Ian Rogersdd7624d2014-03-14 17:43:00 -0700321 int SignField() const { return Bit(6); }
322 int HField() const { return Bit(5); }
323 int ImmedHField() const { return Bits(8, 4); }
324 int ImmedLField() const { return Bits(0, 4); }
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700325
326 // Fields used in Branch instructions
Ian Rogersdd7624d2014-03-14 17:43:00 -0700327 int LinkField() const { return Bits(kLinkShift, kLinkBits); }
328 int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); }
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700329
330 // Fields used in Supervisor Call instructions
Ian Rogersdd7624d2014-03-14 17:43:00 -0700331 uint32_t SvcField() const { return Bits(0, 24); }
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700332
333 // Field used in Breakpoint instruction
Ian Rogersdd7624d2014-03-14 17:43:00 -0700334 uint16_t BkptField() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700335 return ((Bits(8, 12) << 4) | Bits(0, 4));
336 }
337
338 // Field used in 16-bit immediate move instructions
Ian Rogersdd7624d2014-03-14 17:43:00 -0700339 uint16_t MovwField() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700340 return ((Bits(16, 4) << 12) | Bits(0, 12));
341 }
342
343 // Field used in VFP float immediate move instruction
Ian Rogersdd7624d2014-03-14 17:43:00 -0700344 float ImmFloatField() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700345 uint32_t imm32 = (Bit(19) << 31) | (((1 << 5) - Bit(18)) << 25) |
346 (Bits(16, 2) << 23) | (Bits(0, 4) << 19);
347 return bit_cast<float, uint32_t>(imm32);
348 }
349
350 // Field used in VFP double immediate move instruction
Ian Rogersdd7624d2014-03-14 17:43:00 -0700351 double ImmDoubleField() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700352 uint64_t imm64 = (Bit(19)*(1LL << 63)) | (((1LL << 8) - Bit(18)) << 54) |
353 (Bits(16, 2)*(1LL << 52)) | (Bits(0, 4)*(1LL << 48));
354 return bit_cast<double, uint64_t>(imm64);
355 }
356
357 // Test for data processing instructions of type 0 or 1.
358 // See "ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition",
359 // section A5.1 "ARM instruction set encoding".
Ian Rogersdd7624d2014-03-14 17:43:00 -0700360 bool IsDataProcessing() const {
Ian Rogersb033c752011-07-20 12:22:35 -0700361 CHECK_NE(ConditionField(), kSpecialCondition);
362 CHECK_EQ(Bits(26, 2), 0); // Type 0 or 1.
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700363 return ((Bits(20, 5) & 0x19) != 0x10) &&
364 ((Bit(25) == 1) || // Data processing immediate.
365 (Bit(4) == 0) || // Data processing register.
366 (Bit(7) == 0)); // Data processing register-shifted register.
367 }
368
369 // Tests for special encodings of type 0 instructions (extra loads and stores,
370 // as well as multiplications, synchronization primitives, and miscellaneous).
371 // Can only be called for a type 0 or 1 instruction.
Ian Rogersdd7624d2014-03-14 17:43:00 -0700372 bool IsMiscellaneous() const {
Ian Rogersb033c752011-07-20 12:22:35 -0700373 CHECK_EQ(Bits(26, 2), 0); // Type 0 or 1.
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700374 return ((Bit(25) == 0) && ((Bits(20, 5) & 0x19) == 0x10) && (Bit(7) == 0));
375 }
Ian Rogersdd7624d2014-03-14 17:43:00 -0700376 bool IsMultiplyOrSyncPrimitive() const {
Ian Rogersb033c752011-07-20 12:22:35 -0700377 CHECK_EQ(Bits(26, 2), 0); // Type 0 or 1.
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700378 return ((Bit(25) == 0) && (Bits(4, 4) == 9));
379 }
380
381 // Test for Supervisor Call instruction.
Ian Rogersdd7624d2014-03-14 17:43:00 -0700382 bool IsSvc() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700383 return ((InstructionBits() & 0xff000000) == 0xef000000);
384 }
385
386 // Test for Breakpoint instruction.
Ian Rogersdd7624d2014-03-14 17:43:00 -0700387 bool IsBkpt() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700388 return ((InstructionBits() & 0xfff000f0) == 0xe1200070);
389 }
390
391 // VFP register fields.
Ian Rogersdd7624d2014-03-14 17:43:00 -0700392 SRegister SnField() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700393 return static_cast<SRegister>((Bits(kRnShift, kRnBits) << 1) + Bit(7));
394 }
Ian Rogersdd7624d2014-03-14 17:43:00 -0700395 SRegister SdField() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700396 return static_cast<SRegister>((Bits(kRdShift, kRdBits) << 1) + Bit(22));
397 }
Ian Rogersdd7624d2014-03-14 17:43:00 -0700398 SRegister SmField() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700399 return static_cast<SRegister>((Bits(kRmShift, kRmBits) << 1) + Bit(5));
400 }
Ian Rogersdd7624d2014-03-14 17:43:00 -0700401 DRegister DnField() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700402 return static_cast<DRegister>(Bits(kRnShift, kRnBits) + (Bit(7) << 4));
403 }
Ian Rogersdd7624d2014-03-14 17:43:00 -0700404 DRegister DdField() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700405 return static_cast<DRegister>(Bits(kRdShift, kRdBits) + (Bit(22) << 4));
406 }
Ian Rogersdd7624d2014-03-14 17:43:00 -0700407 DRegister DmField() const {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700408 return static_cast<DRegister>(Bits(kRmShift, kRmBits) + (Bit(5) << 4));
409 }
410
411 // Test for VFP data processing or single transfer instructions of type 7.
Ian Rogersdd7624d2014-03-14 17:43:00 -0700412 bool IsVFPDataProcessingOrSingleTransfer() const {
Ian Rogersb033c752011-07-20 12:22:35 -0700413 CHECK_NE(ConditionField(), kSpecialCondition);
414 CHECK_EQ(TypeField(), 7);
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700415 return ((Bit(24) == 0) && (Bits(9, 3) == 5));
416 // Bit(4) == 0: Data Processing
417 // Bit(4) == 1: 8, 16, or 32-bit Transfer between ARM Core and VFP
418 }
419
420 // Test for VFP 64-bit transfer instructions of type 6.
Ian Rogersdd7624d2014-03-14 17:43:00 -0700421 bool IsVFPDoubleTransfer() const {
Ian Rogersb033c752011-07-20 12:22:35 -0700422 CHECK_NE(ConditionField(), kSpecialCondition);
423 CHECK_EQ(TypeField(), 6);
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700424 return ((Bits(21, 4) == 2) && (Bits(9, 3) == 5) &&
425 ((Bits(4, 4) & 0xd) == 1));
426 }
427
428 // Test for VFP load and store instructions of type 6.
Ian Rogersdd7624d2014-03-14 17:43:00 -0700429 bool IsVFPLoadStore() const {
Ian Rogersb033c752011-07-20 12:22:35 -0700430 CHECK_NE(ConditionField(), kSpecialCondition);
431 CHECK_EQ(TypeField(), 6);
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700432 return ((Bits(20, 5) & 0x12) == 0x10) && (Bits(9, 3) == 5);
433 }
434
435 // Special accessors that test for existence of a value.
Ian Rogersdd7624d2014-03-14 17:43:00 -0700436 bool HasS() const { return SField() == 1; }
437 bool HasB() const { return BField() == 1; }
438 bool HasW() const { return WField() == 1; }
439 bool HasL() const { return LField() == 1; }
440 bool HasSign() const { return SignField() == 1; }
441 bool HasH() const { return HField() == 1; }
442 bool HasLink() const { return LinkField() == 1; }
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700443
444 // Instructions are read out of a code stream. The only way to get a
445 // reference to an instruction is to convert a pointer. There is no way
446 // to allocate or create instances of class Instr.
447 // Use the At(pc) function to create references to Instr.
Ian Rogers13735952014-10-08 12:43:28 -0700448 static Instr* At(uintptr_t pc) { return reinterpret_cast<Instr*>(pc); }
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700449 Instr* Next() { return this + kInstrSize; }
450
451 private:
452 // We need to prevent the creation of instances of class Instr.
453 DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
454};
455
Ian Rogers2c8f6532011-09-02 17:16:34 -0700456} // namespace arm
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700457} // namespace art
458
Ian Rogers166db042013-07-26 12:05:57 -0700459#endif // ART_COMPILER_UTILS_ARM_CONSTANTS_ARM_H_