12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2009 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
16a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
17166db04e259ca51838c311891598664deeed85adIan Rogers#ifndef ART_COMPILER_UTILS_ARM_CONSTANTS_ARM_H_
18166db04e259ca51838c311891598664deeed85adIan Rogers#define ART_COMPILER_UTILS_ARM_CONSTANTS_ARM_H_
19a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
20a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro#include <stdint.h>
2107ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes
22b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include <iosfwd>
2307ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes
24166db04e259ca51838c311891598664deeed85adIan Rogers#include "arch/arm/registers_arm.h"
251aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/casts.h"
2607ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h"
27578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "globals.h"
28a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
29a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapironamespace art {
302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace arm {
31a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
32a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// Defines constants and accessor classes to assemble, disassemble and
33a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// simulate ARM instructions.
34a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro//
354fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain// Section references in the code refer to the "ARM Architecture
364fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain// Reference Manual ARMv7-A and ARMv7-R edition", issue C.b (24 July
374fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain// 2012).
38a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro//
39a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// Constants for specific fields are defined in their respective named enums.
40a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// General constants are in an anonymous enum in class Instr.
41a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4219a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray// 4 bits option for the dmb instruction.
4319a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray// Order and values follows those of the ARM Architecture Reference Manual.
4419a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffrayenum DmbOptions {
4519a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray  SY = 0xf,
4619a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray  ST = 0xe,
4719a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray  ISH = 0xb,
4819a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray  ISHST = 0xa,
4919a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray  NSH = 0x7,
5019a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray  NSHST = 0x6
5119a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray};
52a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
53a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroenum ScaleFactor {
54a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  TIMES_1 = 0,
55a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  TIMES_2 = 1,
56a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  TIMES_4 = 2,
57a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  TIMES_8 = 3
58a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro};
59a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
60a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// Values for double-precision floating point registers.
616a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogersenum DRegister {  // private marker to avoid generate-operator-out.py from processing.
626a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  D0  = 0,
636a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  D1  = 1,
646a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  D2  = 2,
656a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  D3  = 3,
666a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  D4  = 4,
676a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  D5  = 5,
686a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  D6  = 6,
696a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  D7  = 7,
706a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  D8  = 8,
716a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  D9  = 9,
72a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D10 = 10,
73a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D11 = 11,
74a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D12 = 12,
75a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D13 = 13,
76a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D14 = 14,
77a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D15 = 15,
78a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D16 = 16,
79a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D17 = 17,
80a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D18 = 18,
81a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D19 = 19,
82a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D20 = 20,
83a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D21 = 21,
84a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D22 = 22,
85a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D23 = 23,
86a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D24 = 24,
87a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D25 = 25,
88a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D26 = 26,
89a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D27 = 27,
90a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D28 = 28,
91a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D29 = 29,
92a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D30 = 30,
93a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  D31 = 31,
94a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kNumberOfDRegisters = 32,
95a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kNumberOfOverlappingDRegisters = 16,
96a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kNoDRegister = -1,
97a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro};
981f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const DRegister& rhs);
99a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
100a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1014fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain// Values for the condition field as defined in Table A8-1 "Condition
1024fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain// codes" (refer to Section A8.3 "Conditional execution").
1036a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogersenum Condition {  // private marker to avoid generate-operator-out.py from processing.
104a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kNoCondition = -1,
1054fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  //           Meaning (integer)                      | Meaning (floating-point)
1064fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  //           ---------------------------------------+-----------------------------------------
1074fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  EQ = 0,   // Equal                                  | Equal
1084fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  NE = 1,   // Not equal                              | Not equal, or unordered
1094fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  CS = 2,   // Carry set                              | Greater than, equal, or unordered
1104fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  CC = 3,   // Carry clear                            | Less than
1114fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  MI = 4,   // Minus, negative                        | Less than
1124fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  PL = 5,   // Plus, positive or zero                 | Greater than, equal, or unordered
1134fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  VS = 6,   // Overflow                               | Unordered (i.e. at least one NaN operand)
1144fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  VC = 7,   // No overflow                            | Not unordered
1154fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  HI = 8,   // Unsigned higher                        | Greater than, or unordered
1164fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  LS = 9,   // Unsigned lower or same                 | Less than or equal
1174fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  GE = 10,  // Signed greater than or equal           | Greater than or equal
1184fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  LT = 11,  // Signed less than                       | Less than, or unordered
1194fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  GT = 12,  // Signed greater than                    | Greater than
1204fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  LE = 13,  // Signed less than or equal              | Less than, equal, or unordered
1214fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  AL = 14,  // Always (unconditional)                 | Always (unconditional)
1224fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  kSpecialCondition = 15,  // Special condition (refer to Section A8.3 "Conditional execution").
123a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kMaxCondition = 16,
1244fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain
1254fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  HS = CS,  // HS (unsigned higher or same) is a synonym for CS.
1264fa13f65ece3b68fe3d8722d679ebab8656bbf99Roland Levillain  LO = CC   // LO (unsigned lower) is a synonym for CC.
127a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro};
1281f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Condition& rhs);
129a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
130a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
131a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// Opcodes for Data-processing instructions (instructions with a type 0 and 1)
132a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// as defined in section A3.4
133a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroenum Opcode {
134a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kNoOperand = -1,
1356a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  AND = 0,   // Logical AND
1366a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  EOR = 1,   // Logical Exclusive OR
1376a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  SUB = 2,   // Subtract
1386a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  RSB = 3,   // Reverse Subtract
1396a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  ADD = 4,   // Add
1406a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  ADC = 5,   // Add with Carry
1416a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  SBC = 6,   // Subtract with Carry
1426a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  RSC = 7,   // Reverse Subtract with Carry
1436a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  TST = 8,   // Test
1446a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  TEQ = 9,   // Test Equivalence
145a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CMP = 10,  // Compare
146a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CMN = 11,  // Compare Negated
147a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  ORR = 12,  // Logical (inclusive) OR
148a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  MOV = 13,  // Move
149a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  BIC = 14,  // Bit Clear
150a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  MVN = 15,  // Move Not
151d2b4ca2d02c86b1ce1826fd2b35ce6c9c58c1ff1Vladimir Marko  ORN = 16,  // Logical OR NOT.
152d2b4ca2d02c86b1ce1826fd2b35ce6c9c58c1ff1Vladimir Marko  kMaxOperand = 17
153a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro};
1546a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogersstd::ostream& operator<<(std::ostream& os, const Opcode& rhs);
155a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
156a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// Shifter types for Data-processing operands as defined in section A5.1.2.
157a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroenum Shift {
158a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kNoShift = -1,
159a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  LSL = 0,  // Logical shift left
160a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  LSR = 1,  // Logical shift right
161a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  ASR = 2,  // Arithmetic shift right
162a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  ROR = 3,  // Rotate right
16365fcc2cf3c5cd97b84330c094908f3a6a7a8d4e7Dave Allison  RRX = 4,  // Rotate right with extend.
16465fcc2cf3c5cd97b84330c094908f3a6a7a8d4e7Dave Allison  kMaxShift
165a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro};
1666a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogersstd::ostream& operator<<(std::ostream& os, const Shift& rhs);
167a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
168a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// Constants used for the decoding or encoding of the individual fields of
169a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// instructions. Based on the "Figure 3-1 ARM instruction set summary".
1706a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogersenum InstructionFields {  // private marker to avoid generate-operator-out.py from processing.
171a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kConditionShift = 28,
172a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kConditionBits = 4,
173a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kTypeShift = 25,
174a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kTypeBits = 3,
175a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kLinkShift = 24,
176a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kLinkBits = 1,
177a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kUShift = 23,
178a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kUBits = 1,
179a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kOpcodeShift = 21,
180a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kOpcodeBits = 4,
181a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kSShift = 20,
182a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kSBits = 1,
183a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kRnShift = 16,
184a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kRnBits = 4,
185a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kRdShift = 12,
186a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kRdBits = 4,
187a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kRsShift = 8,
188a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kRsBits = 4,
189a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kRmShift = 0,
190a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kRmBits = 4,
191a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
192a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Immediate instruction fields encoding.
193a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kRotateShift = 8,
194a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kRotateBits = 4,
195a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kImmed8Shift = 0,
196a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kImmed8Bits = 8,
197a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
198a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Shift instruction register fields encodings.
199a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kShiftImmShift = 7,
200a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kShiftRegisterShift = 8,
201a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kShiftImmBits = 5,
202a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kShiftShift = 5,
203a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kShiftBits = 2,
204a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
205a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Load/store instruction offset field encoding.
206a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kOffset12Shift = 0,
207a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kOffset12Bits = 12,
208a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kOffset12Mask = 0x00000fff,
209a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
210a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Mul instruction register fields encodings.
211a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kMulRdShift = 16,
212a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kMulRdBits = 4,
213a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kMulRnShift = 12,
214a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kMulRnBits = 4,
215a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
216a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kBranchOffsetMask = 0x00ffffff
217a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro};
218a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
219a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// Size (in bytes) of registers.
220a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroconst int kRegisterSize = 4;
221a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
222a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// List of registers used in load/store multiple.
223a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirotypedef uint16_t RegList;
224a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
225a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// The class Instr enables access to individual fields defined in the ARM
226a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// architecture instruction set encoding as described in figure A3-1.
227a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro//
228a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// Example: Test whether the instruction at ptr does set the condition code
229a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// bits.
230a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro//
23113735955f39b3b304c37d2b2840663c131262c18Ian Rogers// bool InstructionSetsConditionCodes(uint8_t* ptr) {
232a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro//   Instr* instr = Instr::At(ptr);
233a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro//   int type = instr->TypeField();
234a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro//   return ((type == 0) || (type == 1)) && instr->HasS();
235a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// }
236a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro//
237a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroclass Instr {
238a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro public:
239a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  enum {
240a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    kInstrSize = 4,
241a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    kInstrSizeLog2 = 2,
242a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    kPCReadOffset = 8
243a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  };
244a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
245a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  bool IsBreakPoint() {
246a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return IsBkpt();
247a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
248a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
249a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Get the raw instruction bits.
250dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int32_t InstructionBits() const {
251a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return *reinterpret_cast<const int32_t*>(this);
252a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
253a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
254a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Set the raw instruction bits to value.
255dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  void SetInstructionBits(int32_t value) {
256a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    *reinterpret_cast<int32_t*>(this) = value;
257a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
258a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
259a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Read one particular bit out of the instruction bits.
260dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int Bit(int nr) const {
261a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return (InstructionBits() >> nr) & 1;
262a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
263a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
264a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Read a bit field out of the instruction bits.
265dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int Bits(int shift, int count) const {
266a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return (InstructionBits() >> shift) & ((1 << count) - 1);
267a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
268a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
269a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
270a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Accessors for the different named fields used in the ARM encoding.
271a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // The naming of these accessor corresponds to figure A3-1.
272a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Generally applicable fields
273dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Condition ConditionField() const {
274a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return static_cast<Condition>(Bits(kConditionShift, kConditionBits));
275a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
276dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int TypeField() const { return Bits(kTypeShift, kTypeBits); }
277a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
278dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Register RnField() const { return static_cast<Register>(
279a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                        Bits(kRnShift, kRnBits)); }
280dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Register RdField() const { return static_cast<Register>(
281a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                        Bits(kRdShift, kRdBits)); }
282a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
283a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Fields used in Data processing instructions
284dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Opcode OpcodeField() const {
285a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return static_cast<Opcode>(Bits(kOpcodeShift, kOpcodeBits));
286a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
287dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int SField() const { return Bits(kSShift, kSBits); }
288a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // with register
289dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Register RmField() const {
290a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return static_cast<Register>(Bits(kRmShift, kRmBits));
291a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
292dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Shift ShiftField() const { return static_cast<Shift>(
293a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                        Bits(kShiftShift, kShiftBits)); }
294dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int RegShiftField() const { return Bit(4); }
295dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  Register RsField() const {
296a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return static_cast<Register>(Bits(kRsShift, kRsBits));
297a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
298dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int ShiftAmountField() const { return Bits(kShiftImmShift,
299a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                                    kShiftImmBits); }
300a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // with immediate
301dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int RotateField() const { return Bits(kRotateShift, kRotateBits); }
302dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int Immed8Field() const { return Bits(kImmed8Shift, kImmed8Bits); }
303a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
304a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Fields used in Load/Store instructions
305dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int PUField() const { return Bits(23, 2); }
306dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int  BField() const { return Bit(22); }
307dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int  WField() const { return Bit(21); }
308dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int  LField() const { return Bit(20); }
309a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // with register uses same fields as Data processing instructions above
310a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // with immediate
311dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int Offset12Field() const { return Bits(kOffset12Shift,
312a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                                 kOffset12Bits); }
313a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // multiple
314dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int RlistField() const { return Bits(0, 16); }
315a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // extra loads and stores
316dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int SignField() const { return Bit(6); }
317dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int HField() const { return Bit(5); }
318dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int ImmedHField() const { return Bits(8, 4); }
319dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int ImmedLField() const { return Bits(0, 4); }
320a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
321a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Fields used in Branch instructions
322dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int LinkField() const { return Bits(kLinkShift, kLinkBits); }
323dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); }
324a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
325a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Fields used in Supervisor Call instructions
326dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint32_t SvcField() const { return Bits(0, 24); }
327a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
328a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Field used in Breakpoint instruction
329dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint16_t BkptField() const {
330a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return ((Bits(8, 12) << 4) | Bits(0, 4));
331a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
332a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
333a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Field used in 16-bit immediate move instructions
334dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  uint16_t MovwField() const {
335a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return ((Bits(16, 4) << 12) | Bits(0, 12));
336a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
337a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
338a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Field used in VFP float immediate move instruction
339dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  float ImmFloatField() const {
340a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    uint32_t imm32 = (Bit(19) << 31) | (((1 << 5) - Bit(18)) << 25) |
341a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (Bits(16, 2) << 23) | (Bits(0, 4) << 19);
342a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return bit_cast<float, uint32_t>(imm32);
343a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
344a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
345a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Field used in VFP double immediate move instruction
346dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  double ImmDoubleField() const {
347a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    uint64_t imm64 = (Bit(19)*(1LL << 63)) | (((1LL << 8) - Bit(18)) << 54) |
348a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (Bits(16, 2)*(1LL << 52)) | (Bits(0, 4)*(1LL << 48));
349a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return bit_cast<double, uint64_t>(imm64);
350a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
351a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
352a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Test for data processing instructions of type 0 or 1.
353a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // See "ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition",
354a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // section A5.1 "ARM instruction set encoding".
355dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool IsDataProcessing() const {
356b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_NE(ConditionField(), kSpecialCondition);
357b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_EQ(Bits(26, 2), 0);  // Type 0 or 1.
358a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return ((Bits(20, 5) & 0x19) != 0x10) &&
359a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      ((Bit(25) == 1) ||  // Data processing immediate.
360a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro       (Bit(4) == 0) ||  // Data processing register.
361a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro       (Bit(7) == 0));  // Data processing register-shifted register.
362a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
363a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
364a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Tests for special encodings of type 0 instructions (extra loads and stores,
365a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // as well as multiplications, synchronization primitives, and miscellaneous).
366a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Can only be called for a type 0 or 1 instruction.
367dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool IsMiscellaneous() const {
368b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_EQ(Bits(26, 2), 0);  // Type 0 or 1.
369a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return ((Bit(25) == 0) && ((Bits(20, 5) & 0x19) == 0x10) && (Bit(7) == 0));
370a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
371dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool IsMultiplyOrSyncPrimitive() const {
372b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_EQ(Bits(26, 2), 0);  // Type 0 or 1.
373a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return ((Bit(25) == 0) && (Bits(4, 4) == 9));
374a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
375a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
376a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Test for Supervisor Call instruction.
377dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool IsSvc() const {
378a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return ((InstructionBits() & 0xff000000) == 0xef000000);
379a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
380a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
381a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Test for Breakpoint instruction.
382dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool IsBkpt() const {
383a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return ((InstructionBits() & 0xfff000f0) == 0xe1200070);
384a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
385a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
386a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // VFP register fields.
387dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  SRegister SnField() const {
388a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return static_cast<SRegister>((Bits(kRnShift, kRnBits) << 1) + Bit(7));
389a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
390dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  SRegister SdField() const {
391a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return static_cast<SRegister>((Bits(kRdShift, kRdBits) << 1) + Bit(22));
392a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
393dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  SRegister SmField() const {
394a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return static_cast<SRegister>((Bits(kRmShift, kRmBits) << 1) + Bit(5));
395a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
396dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  DRegister DnField() const {
397a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return static_cast<DRegister>(Bits(kRnShift, kRnBits) + (Bit(7) << 4));
398a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
399dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  DRegister DdField() const {
400a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return static_cast<DRegister>(Bits(kRdShift, kRdBits) + (Bit(22) << 4));
401a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
402dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  DRegister DmField() const {
403a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return static_cast<DRegister>(Bits(kRmShift, kRmBits) + (Bit(5) << 4));
404a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
405a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
406a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Test for VFP data processing or single transfer instructions of type 7.
407dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool IsVFPDataProcessingOrSingleTransfer() const {
408b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_NE(ConditionField(), kSpecialCondition);
409b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_EQ(TypeField(), 7);
410a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return ((Bit(24) == 0) && (Bits(9, 3) == 5));
411a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    // Bit(4) == 0: Data Processing
412a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    // Bit(4) == 1: 8, 16, or 32-bit Transfer between ARM Core and VFP
413a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
414a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
415a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Test for VFP 64-bit transfer instructions of type 6.
416dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool IsVFPDoubleTransfer() const {
417b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_NE(ConditionField(), kSpecialCondition);
418b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_EQ(TypeField(), 6);
419a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return ((Bits(21, 4) == 2) && (Bits(9, 3) == 5) &&
420a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro            ((Bits(4, 4) & 0xd) == 1));
421a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
422a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
423a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Test for VFP load and store instructions of type 6.
424dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool IsVFPLoadStore() const {
425b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_NE(ConditionField(), kSpecialCondition);
426b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_EQ(TypeField(), 6);
427a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return ((Bits(20, 5) & 0x12) == 0x10) && (Bits(9, 3) == 5);
428a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
429a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
430a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Special accessors that test for existence of a value.
431dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool HasS() const { return SField() == 1; }
432dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool HasB() const { return BField() == 1; }
433dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool HasW() const { return WField() == 1; }
434dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool HasL() const { return LField() == 1; }
435dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool HasSign() const { return SignField() == 1; }
436dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool HasH() const { return HField() == 1; }
437dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers  bool HasLink() const { return LinkField() == 1; }
438a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
439a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Instructions are read out of a code stream. The only way to get a
440a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // reference to an instruction is to convert a pointer. There is no way
441a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // to allocate or create instances of class Instr.
442a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Use the At(pc) function to create references to Instr.
44313735955f39b3b304c37d2b2840663c131262c18Ian Rogers  static Instr* At(uintptr_t pc) { return reinterpret_cast<Instr*>(pc); }
444a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Instr* Next() { return this + kInstrSize; }
445a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
446a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro private:
447a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // We need to prevent the creation of instances of class Instr.
448a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
449a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro};
450a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4512c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers}  // namespace arm
452a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}  // namespace art
453a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
454166db04e259ca51838c311891598664deeed85adIan Rogers#endif  // ART_COMPILER_UTILS_ARM_CONSTANTS_ARM_H_
455