assembler_arm.cc revision b033c75ebda80ac75f936366fe78d1edf5cec937
1a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro// Copyright 2011 Google Inc. All Rights Reserved.
2a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
3a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro#include "src/assembler.h"
4a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro#include "src/logging.h"
5b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include "src/utils.h"
6a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
76b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapironamespace art {
8a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
9a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// Instruction encoding bits.
10a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroenum {
11a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  H   = 1 << 5,   // halfword (or byte)
12a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  L   = 1 << 20,  // load (or store)
13a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  S   = 1 << 20,  // set condition code (or leave unchanged)
14a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  W   = 1 << 21,  // writeback base register (or leave unchanged)
15a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  A   = 1 << 21,  // accumulate in multiply instruction (or not)
16a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B   = 1 << 22,  // unsigned byte (or word)
17a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  N   = 1 << 22,  // long (or short)
18a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  U   = 1 << 23,  // positive (or negative) offset/index
19a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  P   = 1 << 24,  // offset/pre-indexed addressing (or post-indexed addressing)
20a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  I   = 1 << 25,  // immediate shifter operand (or not)
21a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
22a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B0 = 1,
23a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B1 = 1 << 1,
24a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B2 = 1 << 2,
25a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B3 = 1 << 3,
26a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B4 = 1 << 4,
27a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B5 = 1 << 5,
28a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B6 = 1 << 6,
29a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B7 = 1 << 7,
30a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B8 = 1 << 8,
31a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B9 = 1 << 9,
32a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B10 = 1 << 10,
33a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B11 = 1 << 11,
34a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B12 = 1 << 12,
35a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B16 = 1 << 16,
36a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B17 = 1 << 17,
37a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B18 = 1 << 18,
38a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B19 = 1 << 19,
39a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B20 = 1 << 20,
40a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B21 = 1 << 21,
41a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B22 = 1 << 22,
42a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B23 = 1 << 23,
43a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B24 = 1 << 24,
44a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B25 = 1 << 25,
45a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B26 = 1 << 26,
46a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B27 = 1 << 27,
47a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
48a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Instruction bit masks.
49a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  RdMask = 15 << 12,  // in str instruction
50a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CondMask = 15 << 28,
51a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CoprocessorMask = 15 << 8,
52a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  OpCodeMask = 15 << 21,  // in data-processing instructions
53a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Imm24Mask = (1 << 24) - 1,
54a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Off12Mask = (1 << 12) - 1,
55a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
56a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // ldrex/strex register field encodings.
57a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kLdExRnShift = 16,
58a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kLdExRtShift = 12,
59a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kStrExRnShift = 16,
60a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kStrExRdShift = 12,
61a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kStrExRtShift = 0,
62a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro};
63a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
64a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
651f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstatic const char* kRegisterNames[] = {
661f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
671f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  "fp", "ip", "sp", "lr", "pc"
681f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes};
691f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Register& rhs) {
701f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  if (rhs >= R0 && rhs <= PC) {
711f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes    os << kRegisterNames[rhs];
721f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  } else {
73b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "Register[" << static_cast<int>(rhs) << "]";
741f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  }
751f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  return os;
761f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}
771f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
781f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
791f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const SRegister& rhs) {
801f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  if (rhs >= S0 && rhs < kNumberOfSRegisters) {
81b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "s" << static_cast<int>(rhs);
821f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  } else {
83b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "SRegister[" << static_cast<int>(rhs) << "]";
841f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  }
851f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  return os;
861f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}
871f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
881f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
891f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const DRegister& rhs) {
901f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  if (rhs >= D0 && rhs < kNumberOfDRegisters) {
91b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "d" << static_cast<int>(rhs);
921f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  } else {
93b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "DRegister[" << static_cast<int>(rhs) << "]";
941f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  }
951f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  return os;
961f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}
971f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
981f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
991f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstatic const char* kConditionNames[] = {
100b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT",
101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  "LE", "AL",
1021f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes};
1031f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Condition& rhs) {
1041f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  if (rhs >= EQ && rhs <= AL) {
1051f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes    os << kConditionNames[rhs];
1061f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  } else {
107b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "Condition[" << static_cast<int>(rhs) << "]";
1081f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  }
1091f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  return os;
1101f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}
1111f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
1121f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
113a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::Emit(int32_t value) {
114a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
115a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  buffer_.Emit<int32_t>(value);
116a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
117a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
118a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
119a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitType01(Condition cond,
120a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                           int type,
121a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                           Opcode opcode,
122a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                           int set_cc,
123a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                           Register rn,
124a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                           Register rd,
125a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                           ShifterOperand so) {
126a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
127a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
128a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
129a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     type << kTypeShift |
130a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(opcode) << kOpcodeShift |
131a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     set_cc << kSShift |
132a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rn) << kRnShift |
133a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rd) << kRdShift |
134a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     so.encoding();
135a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
136a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
137a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
138a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
139a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitType5(Condition cond, int offset, bool link) {
140a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
141a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
142a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     5 << kTypeShift |
143a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (link ? 1 : 0) << kLinkShift;
144a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(Assembler::EncodeBranchOffset(offset, encoding));
145a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
146a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
147a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
148a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitMemOp(Condition cond,
149a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                          bool load,
150a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                          bool byte,
151a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                          Register rd,
152a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                          Address ad) {
153a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
154a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
155a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
156a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B26 |
157a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (load ? L : 0) |
158a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (byte ? B : 0) |
159a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rd) << kRdShift) |
160a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ad.encoding();
161a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
162a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
163a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
164a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
165a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitMemOpAddressMode3(Condition cond,
166a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                      int32_t mode,
167a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                      Register rd,
168a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                      Address ad) {
169a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
170a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
171a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
172a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B22  |
173a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     mode |
174a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rd) << kRdShift) |
175a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ad.encoding3();
176a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
177a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
178a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
179a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
180a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitMultiMemOp(Condition cond,
181a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                               BlockAddressMode am,
182a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                               bool load,
183a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                               Register base,
184a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                               RegList regs) {
185a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(base, kNoRegister);
186a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
187a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
188a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 |
189a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     am |
190a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (load ? L : 0) |
191a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(base) << kRnShift) |
192a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     regs;
193a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
194a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
195a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
196a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
197a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitShiftImmediate(Condition cond,
198a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                   Shift opcode,
199a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                   Register rd,
200a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                   Register rm,
201a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                   ShifterOperand so) {
202a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
2031f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  CHECK_EQ(so.type(), 1U);
204a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
205a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(MOV) << kOpcodeShift |
206a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rd) << kRdShift |
207a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     so.encoding() << kShiftImmShift |
208a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(opcode) << kShiftShift |
209a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rm);
210a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
211a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
212a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
213a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
214a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitShiftRegister(Condition cond,
215a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                  Shift opcode,
216a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                  Register rd,
217a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                  Register rm,
218a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                                  ShifterOperand so) {
219a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
2201f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  CHECK_EQ(so.type(), 0U);
221a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
222a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(MOV) << kOpcodeShift |
223a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rd) << kRdShift |
224a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     so.encoding() << kShiftRegisterShift |
225a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(opcode) << kShiftShift |
226a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B4 |
227a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rm);
228a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
229a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
230a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
231a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
232a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitBranch(Condition cond, Label* label, bool link) {
233a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  if (label->IsBound()) {
234a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    EmitType5(cond, label->Position() - buffer_.Size(), link);
235a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  } else {
236a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    int position = buffer_.Size();
237a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    // Use the offset field of the branch instruction for linking the sites.
238a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    EmitType5(cond, label->position_, link);
239a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    label->LinkTo(position);
240a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
241a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
242a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
243a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
244a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::and_(Register rd, Register rn, ShifterOperand so,
245a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     Condition cond) {
246a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), AND, 0, rn, rd, so);
247a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
248a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
249a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
250a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::eor(Register rd, Register rn, ShifterOperand so,
251a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Condition cond) {
252a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), EOR, 0, rn, rd, so);
253a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
254a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
255a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
256a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::sub(Register rd, Register rn, ShifterOperand so,
257a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Condition cond) {
258a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), SUB, 0, rn, rd, so);
259a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
260a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
261a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::rsb(Register rd, Register rn, ShifterOperand so,
262a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Condition cond) {
263a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), RSB, 0, rn, rd, so);
264a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
265a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
266a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::rsbs(Register rd, Register rn, ShifterOperand so,
267a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     Condition cond) {
268a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), RSB, 1, rn, rd, so);
269a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
270a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
271a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
272a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::add(Register rd, Register rn, ShifterOperand so,
273a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Condition cond) {
274a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ADD, 0, rn, rd, so);
275a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
276a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
277a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
278a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::adds(Register rd, Register rn, ShifterOperand so,
279a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     Condition cond) {
280a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ADD, 1, rn, rd, so);
281a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
282a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
283a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
284a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::subs(Register rd, Register rn, ShifterOperand so,
285a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     Condition cond) {
286a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), SUB, 1, rn, rd, so);
287a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
288a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
289a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
290a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::adc(Register rd, Register rn, ShifterOperand so,
291a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Condition cond) {
292a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ADC, 0, rn, rd, so);
293a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
294a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
295a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
296a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::sbc(Register rd, Register rn, ShifterOperand so,
297a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Condition cond) {
298a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), SBC, 0, rn, rd, so);
299a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
300a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
301a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
302a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::rsc(Register rd, Register rn, ShifterOperand so,
303a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Condition cond) {
304a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), RSC, 0, rn, rd, so);
305a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
306a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
307a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
308a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::tst(Register rn, ShifterOperand so, Condition cond) {
309a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, PC);  // Reserve tst pc instruction for exception handler marker.
310a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), TST, 1, rn, R0, so);
311a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
312a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
313a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
314a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::teq(Register rn, ShifterOperand so, Condition cond) {
315a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, PC);  // Reserve teq pc instruction for exception handler marker.
316a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), TEQ, 1, rn, R0, so);
317a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
318a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
319a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
320a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::cmp(Register rn, ShifterOperand so, Condition cond) {
321a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), CMP, 1, rn, R0, so);
322a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
323a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
324a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
325a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::cmn(Register rn, ShifterOperand so, Condition cond) {
326a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), CMN, 1, rn, R0, so);
327a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
328a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
329a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
330a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::orr(Register rd, Register rn,
331a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    ShifterOperand so, Condition cond) {
332a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ORR, 0, rn, rd, so);
333a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
334a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
335a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
336a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::orrs(Register rd, Register rn,
337a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ShifterOperand so, Condition cond) {
338a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ORR, 1, rn, rd, so);
339a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
340a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
341a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
342a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mov(Register rd, ShifterOperand so, Condition cond) {
343a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), MOV, 0, R0, rd, so);
344a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
345a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
346a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
347a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::movs(Register rd, ShifterOperand so, Condition cond) {
348a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), MOV, 1, R0, rd, so);
349a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
350a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
351a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
352a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::bic(Register rd, Register rn, ShifterOperand so,
353a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Condition cond) {
354a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), BIC, 0, rn, rd, so);
355a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
356a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
357a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
358a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mvn(Register rd, ShifterOperand so, Condition cond) {
359a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), MVN, 0, R0, rd, so);
360a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
361a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
362a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
363a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mvns(Register rd, ShifterOperand so, Condition cond) {
364a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), MVN, 1, R0, rd, so);
365a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
366a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
367a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
368a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::clz(Register rd, Register rm, Condition cond) {
369a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
370a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rm, kNoRegister);
371a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
372a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, PC);
373a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rm, PC);
374a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
375a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B24 | B22 | B21 | (0xf << 16) |
376a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rd) << kRdShift) |
377a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (0xf << 8) | B4 | static_cast<int32_t>(rm);
378a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
379a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
380a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
381a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
382a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::movw(Register rd, uint16_t imm16, Condition cond) {
383a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
384a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
385a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B25 | B24 | ((imm16 >> 12) << 16) |
386a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
387a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
388a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
389a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
390a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
391a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::movt(Register rd, uint16_t imm16, Condition cond) {
392a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
393a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
394a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B25 | B24 | B22 | ((imm16 >> 12) << 16) |
395a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
396a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
397a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
398a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
399a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
400a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitMulOp(Condition cond, int32_t opcode,
401a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                          Register rd, Register rn,
402a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                          Register rm, Register rs) {
403a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
404a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, kNoRegister);
405a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rm, kNoRegister);
406a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rs, kNoRegister);
407a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
408a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = opcode |
409a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(cond) << kConditionShift) |
410a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(rn) << kRnShift) |
411a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(rd) << kRdShift) |
412a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(rs) << kRsShift) |
413a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      B7 | B4 |
414a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(rm) << kRmShift);
415a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
416a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
417a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
418a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
419a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mul(Register rd, Register rn,
420a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Register rm, Condition cond) {
421a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
422a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMulOp(cond, 0, R0, rd, rn, rm);
423a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
424a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
425a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
426a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mla(Register rd, Register rn,
427a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Register rm, Register ra, Condition cond) {
428a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
429a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMulOp(cond, B21, ra, rd, rn, rm);
430a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
431a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
432a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
433a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mls(Register rd, Register rn,
434a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Register rm, Register ra, Condition cond) {
435a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
436a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMulOp(cond, B22 | B21, ra, rd, rn, rm);
437a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
438a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
439a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
440a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::umull(Register rd_lo, Register rd_hi,
441a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Register rn, Register rm, Condition cond) {
442a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
443a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm);
444a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
445a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
446a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
447a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldr(Register rd, Address ad, Condition cond) {
448a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOp(cond, true, false, rd, ad);
449a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
450a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
451a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
452a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::str(Register rd, Address ad, Condition cond) {
453a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOp(cond, false, false, rd, ad);
454a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
455a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
456a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
457a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrb(Register rd, Address ad, Condition cond) {
458a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOp(cond, true, true, rd, ad);
459a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
460a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
461a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
462a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::strb(Register rd, Address ad, Condition cond) {
463a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOp(cond, false, true, rd, ad);
464a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
465a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
466a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
467a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrh(Register rd, Address ad, Condition cond) {
468a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad);
469a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
470a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
471a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
472a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::strh(Register rd, Address ad, Condition cond) {
473a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad);
474a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
475a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
476a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
477a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrsb(Register rd, Address ad, Condition cond) {
478a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad);
479a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
480a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
481a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
482a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrsh(Register rd, Address ad, Condition cond) {
483a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad);
484a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
485a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
486a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
487a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrd(Register rd, Address ad, Condition cond) {
488a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_EQ(rd % 2, 0);
489a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad);
490a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
491a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
492a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
493a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::strd(Register rd, Address ad, Condition cond) {
494a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_EQ(rd % 2, 0);
495a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad);
496a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
497a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
498a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
499a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldm(BlockAddressMode am,
500a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Register base,
501a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    RegList regs,
502a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Condition cond) {
503a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMultiMemOp(cond, am, true, base, regs);
504a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
505a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
506a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
507a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::stm(BlockAddressMode am,
508a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Register base,
509a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    RegList regs,
510a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    Condition cond) {
511a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMultiMemOp(cond, am, false, base, regs);
512a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
513a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
514a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
515a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrex(Register rt, Register rn, Condition cond) {
516a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, kNoRegister);
517a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
518a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
519a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
520a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B24 |
521a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B23 |
522a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     L   |
523a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rn) << kLdExRnShift) |
524a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt) << kLdExRtShift) |
525a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0;
526a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
527a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
528a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
529a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
530a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::strex(Register rd,
531a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Register rt,
532a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Register rn,
533a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Condition cond) {
534a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, kNoRegister);
535a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
536a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
537a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
538a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
539a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B24 |
540a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B23 |
541a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rn) << kStrExRnShift) |
542a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rd) << kStrExRdShift) |
543a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B10 | B9 | B8 | B7 | B4 |
544a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt) << kStrExRtShift);
545a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
546a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
547a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
548a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
549a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::clrex() {
550a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (kSpecialCondition << kConditionShift) |
551a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf;
552a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
553a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
554a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
555a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
556a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::nop(Condition cond) {
557a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
558a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
559a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B25 | B24 | B21 | (0xf << 12);
560a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
561a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
562a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
563a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
564a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovsr(SRegister sn, Register rt, Condition cond) {
565a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sn, kNoSRegister);
566a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
567a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
568a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
569a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
570a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
571a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 |
572a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) >> 1)*B16) |
573a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
574a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
575a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
576a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
577a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
578a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
579a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovrs(Register rt, SRegister sn, Condition cond) {
580a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sn, kNoSRegister);
581a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
582a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
583a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
584a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
585a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
586a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B20 |
587a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) >> 1)*B16) |
588a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
589a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
590a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
591a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
592a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
593a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
594a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovsrr(SRegister sm, Register rt, Register rt2,
595a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                        Condition cond) {
596a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, kNoSRegister);
597a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, S31);
598a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
599a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
600a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
601a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, kNoRegister);
602a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, SP);
603a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, PC);
604a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
605a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
606a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B22 |
607a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt2)*B16) |
608a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
609a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
610a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(sm) >> 1);
611a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
612a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
613a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
614a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
615a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovrrs(Register rt, Register rt2, SRegister sm,
616a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                        Condition cond) {
617a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, kNoSRegister);
618a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, S31);
619a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
620a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
621a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
622a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, kNoRegister);
623a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, SP);
624a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, PC);
625a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, rt2);
626a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
627a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
628a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B22 | B20 |
629a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt2)*B16) |
630a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
631a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
632a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(sm) >> 1);
633a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
634a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
635a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
636a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
637a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovdrr(DRegister dm, Register rt, Register rt2,
638a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                        Condition cond) {
639a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dm, kNoDRegister);
640a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
641a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
642a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
643a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, kNoRegister);
644a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, SP);
645a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, PC);
646a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
647a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
648a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B22 |
649a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt2)*B16) |
650a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
651a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
652a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(dm) & 0xf);
653a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
654a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
655a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
656a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
657a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovrrd(Register rt, Register rt2, DRegister dm,
658a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                              Condition cond) {
659a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dm, kNoDRegister);
660a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
661a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
662a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
663a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, kNoRegister);
664a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, SP);
665a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, PC);
666a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, rt2);
667a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
668a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
669a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B22 | B20 |
670a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt2)*B16) |
671a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
672a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
673a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(dm) & 0xf);
674a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
675a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
676a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
677a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
678a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vldrs(SRegister sd, Address ad, Condition cond) {
679a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sd, kNoSRegister);
680a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
681a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
682a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B24 | B20 |
683a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) & 1)*B22) |
684a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) >> 1)*B12) |
685a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | ad.vencoding();
686a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
687a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
688a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
689a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
690a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vstrs(SRegister sd, Address ad, Condition cond) {
691a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC);
692a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sd, kNoSRegister);
693a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
694a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
695a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B24 |
696a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) & 1)*B22) |
697a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) >> 1)*B12) |
698a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | ad.vencoding();
699a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
700a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
701a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
702a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
703a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vldrd(DRegister dd, Address ad, Condition cond) {
704a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dd, kNoDRegister);
705a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
706a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
707a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B24 | B20 |
708a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) >> 4)*B22) |
709a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
710a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | B8 | ad.vencoding();
711a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
712a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
713a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
714a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
715a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vstrd(DRegister dd, Address ad, Condition cond) {
716a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC);
717a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dd, kNoDRegister);
718a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
719a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
720a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B24 |
721a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) >> 4)*B22) |
722a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
723a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | B8 | ad.vencoding();
724a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
725a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
726a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
727a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
728a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitVFPsss(Condition cond, int32_t opcode,
729a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                           SRegister sd, SRegister sn, SRegister sm) {
730a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sd, kNoSRegister);
731a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sn, kNoSRegister);
732a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, kNoSRegister);
733a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
734a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
735a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B11 | B9 | opcode |
736a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) & 1)*B22) |
737a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) >> 1)*B16) |
738a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) >> 1)*B12) |
739a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) & 1)*B7) |
740a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sm) & 1)*B5) |
741a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(sm) >> 1);
742a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
743a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
744a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
745a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
746a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitVFPddd(Condition cond, int32_t opcode,
747a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                           DRegister dd, DRegister dn, DRegister dm) {
748a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dd, kNoDRegister);
749a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dn, kNoDRegister);
750a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dm, kNoDRegister);
751a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
752a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
753a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B11 | B9 | B8 | opcode |
754a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) >> 4)*B22) |
755a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dn) & 0xf)*B16) |
756a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
757a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dn) >> 4)*B7) |
758a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dm) >> 4)*B5) |
759a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(dm) & 0xf);
760a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
761a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
762a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
763a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
764a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) {
765a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm);
766a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
767a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
768a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
769a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) {
770a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm);
771a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
772a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
773a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
774a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirobool Assembler::vmovs(SRegister sd, float s_imm, Condition cond) {
775a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  uint32_t imm32 = bit_cast<uint32_t, float>(s_imm);
776a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  if (((imm32 & ((1 << 19) - 1)) == 0) &&
777a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) ||
778a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro       (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) {
779a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) |
780a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro        ((imm32 >> 19) & ((1 << 6) -1));
781a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf),
782a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro               sd, S0, S0);
783a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return true;
784a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
785a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  return false;
786a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
787a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
788a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
789a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirobool Assembler::vmovd(DRegister dd, double d_imm, Condition cond) {
790a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  uint64_t imm64 = bit_cast<uint64_t, double>(d_imm);
791a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  if (((imm64 & ((1LL << 48) - 1)) == 0) &&
792a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) ||
793a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro       (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) {
794a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) |
795a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro        ((imm64 >> 48) & ((1 << 6) -1));
796a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf),
797a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro               dd, D0, D0);
798a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return true;
799a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
800a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  return false;
801a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
802a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
803a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
804a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vadds(SRegister sd, SRegister sn, SRegister sm,
805a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Condition cond) {
806a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B21 | B20, sd, sn, sm);
807a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
808a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
809a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
810a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm,
811a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Condition cond) {
812a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B21 | B20, dd, dn, dm);
813a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
814a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
815a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
816a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm,
817a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Condition cond) {
818a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm);
819a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
820a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
821a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
822a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm,
823a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Condition cond) {
824a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm);
825a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
826a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
827a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
828a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm,
829a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Condition cond) {
830a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B21, sd, sn, sm);
831a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
832a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
833a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
834a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm,
835a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Condition cond) {
836a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B21, dd, dn, dm);
837a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
838a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
839a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
840a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm,
841a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Condition cond) {
842a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, 0, sd, sn, sm);
843a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
844a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
845a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
846a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm,
847a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Condition cond) {
848a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, 0, dd, dn, dm);
849a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
850a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
851a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
852a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm,
853a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Condition cond) {
854a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B6, sd, sn, sm);
855a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
856a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
857a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
858a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm,
859a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Condition cond) {
860a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B6, dd, dn, dm);
861a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
862a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
863a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
864a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm,
865a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Condition cond) {
866a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23, sd, sn, sm);
867a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
868a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
869a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
870a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm,
871a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                      Condition cond) {
872a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23, dd, dn, dm);
873a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
874a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
875a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
876a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vabss(SRegister sd, SRegister sm, Condition cond) {
877a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm);
878a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
879a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
880a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
881a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) {
882a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm);
883a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
884a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
885a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
886a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) {
887a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm);
888a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
889a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
890a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
891a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) {
892a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm);
893a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
894a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
895a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
896a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) {
897a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm);
898a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
899a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
900a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) {
901a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm);
902a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
903a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
904a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
905a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitVFPsd(Condition cond, int32_t opcode,
906a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                          SRegister sd, DRegister dm) {
907a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sd, kNoSRegister);
908a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dm, kNoDRegister);
909a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
910a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
911a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B11 | B9 | opcode |
912a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) & 1)*B22) |
913a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) >> 1)*B12) |
914a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dm) >> 4)*B5) |
915a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(dm) & 0xf);
916a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
917a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
918a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
919a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
920a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitVFPds(Condition cond, int32_t opcode,
921a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                          DRegister dd, SRegister sm) {
922a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dd, kNoDRegister);
923a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, kNoSRegister);
924a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
925a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
926a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B11 | B9 | opcode |
927a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) >> 4)*B22) |
928a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
929a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sm) & 1)*B5) |
930a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(sm) >> 1);
931a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
932a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
933a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
934a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
935a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) {
936a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm);
937a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
938a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
939a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
940a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) {
941a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm);
942a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
943a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
944a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
945a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) {
946a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm);
947a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
948a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
949a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
950a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) {
951a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm);
952a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
953a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
954a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
955a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) {
956a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm);
957a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
958a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
959a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
960a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) {
961a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm);
962a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
963a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
964a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
965a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) {
966a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm);
967a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
968a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
969a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
970a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) {
971a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm);
972a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
973a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
974a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
975a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) {
976a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm);
977a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
978a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
979a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
980a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) {
981a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm);
982a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
983a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
984a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
985a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) {
986a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm);
987a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
988a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
989a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
990a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) {
991a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm);
992a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
993a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
994a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
995a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcmpsz(SRegister sd, Condition cond) {
996a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0);
997a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
998a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
999a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1000a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcmpdz(DRegister dd, Condition cond) {
1001a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
1002a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1003a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1004a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1005a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmstat(Condition cond) {  // VMRS APSR_nzcv, FPSCR
1006a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
1007a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1008a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 |
1009a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(PC)*B12) |
1010a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | B4;
1011a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
1012a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1013a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1014a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1015a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::svc(uint32_t imm24) {
1016a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK(IsUint(24, imm24));
1017a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24;
1018a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
1019a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1020a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1021a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1022a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::bkpt(uint16_t imm16) {
1023a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (AL << kConditionShift) | B24 | B21 |
1024a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
1025a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
1026a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1027a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1028a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1029a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::b(Label* label, Condition cond) {
1030a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitBranch(cond, label, false);
1031a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1032a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1033a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1034a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::bl(Label* label, Condition cond) {
1035a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitBranch(cond, label, true);
1036a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1037a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1038a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1039a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::blx(Register rm, Condition cond) {
1040a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rm, kNoRegister);
1041a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
1042a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1043a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B24 | B21 | (0xfff << 8) | B5 | B4 |
1044a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rm) << kRmShift);
1045a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
1046a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1047a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1048a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1049a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::MarkExceptionHandler(Label* label) {
1050a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0));
1051a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Label l;
1052a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  b(&l);
1053a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitBranch(AL, label, false);
1054a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Bind(&l);
1055a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1056a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1057a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1058a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::Bind(Label* label) {
1059a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK(!label->IsBound());
1060a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int bound_pc = buffer_.Size();
1061a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  while (label->IsLinked()) {
1062a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    int32_t position = label->Position();
1063a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    int32_t next = buffer_.Load<int32_t>(position);
1064a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    int32_t encoded = Assembler::EncodeBranchOffset(bound_pc - position, next);
1065a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    buffer_.Store<int32_t>(position, encoded);
1066a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    label->position_ = Assembler::DecodeBranchOffset(next);
1067a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
1068a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  label->BindTo(bound_pc);
1069a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1070a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1071a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1072a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EncodeUint32InTstInstructions(uint32_t data) {
1073a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // TODO: Consider using movw ip, <16 bits>.
1074a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  while (!IsUint(8, data)) {
1075a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    tst(R0, ShifterOperand(data & 0xFF), VS);
1076a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    data >>= 8;
1077a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
1078a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  tst(R0, ShifterOperand(data), MI);
1079a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1080a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1081b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1082a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroint32_t Assembler::EncodeBranchOffset(int offset, int32_t inst) {
1083a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // The offset is off by 8 due to the way the ARM CPUs read PC.
1084a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  offset -= 8;
1085a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK(IsAligned(offset, 4));
1086a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK(IsInt(CountOneBits(kBranchOffsetMask), offset));
1087a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1088a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Properly preserve only the bits supported in the instruction.
1089a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  offset >>= 2;
1090a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  offset &= kBranchOffsetMask;
1091a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  return (inst & ~kBranchOffsetMask) | offset;
1092a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1093a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1094a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1095a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroint Assembler::DecodeBranchOffset(int32_t inst) {
1096a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Sign-extend, left-shift by 2, then add 8.
1097a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8);
1098a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1099a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1100b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::AddConstant(Register rd, int32_t value, Condition cond) {
1101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  AddConstant(rd, rd, value, cond);
1102b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1103b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1104b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1105b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::AddConstant(Register rd, Register rn, int32_t value,
1106b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                            Condition cond) {
1107b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (value == 0) {
1108b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (rd != rn) {
1109b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mov(rd, ShifterOperand(rn), cond);
1110b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1111b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return;
1112b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1113b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // We prefer to select the shorter code sequence rather than selecting add for
1114b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // positive values and sub for negatives ones, which would slightly improve
1115b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // the readability of generated code for some constants.
1116b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  ShifterOperand shifter_op;
1117b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (ShifterOperand::CanHold(value, &shifter_op)) {
1118b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    add(rd, rn, shifter_op, cond);
1119b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else if (ShifterOperand::CanHold(-value, &shifter_op)) {
1120b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    sub(rd, rn, shifter_op, cond);
1121b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1122b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(rn != IP);
1123b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (ShifterOperand::CanHold(~value, &shifter_op)) {
1124b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mvn(IP, shifter_op, cond);
1125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      add(rd, rn, ShifterOperand(IP), cond);
1126b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) {
1127b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mvn(IP, shifter_op, cond);
1128b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      sub(rd, rn, ShifterOperand(IP), cond);
1129b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    } else {
1130b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      movw(IP, Low16Bits(value), cond);
1131b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      uint16_t value_high = High16Bits(value);
1132b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      if (value_high != 0) {
1133b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers        movt(IP, value_high, cond);
1134b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      }
1135b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      add(rd, rn, ShifterOperand(IP), cond);
1136b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1137b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1138b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1139b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1140b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1141b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::AddConstantSetFlags(Register rd, Register rn, int32_t value,
1142b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                                    Condition cond) {
1143b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  ShifterOperand shifter_op;
1144b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (ShifterOperand::CanHold(value, &shifter_op)) {
1145b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    adds(rd, rn, shifter_op, cond);
1146b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else if (ShifterOperand::CanHold(-value, &shifter_op)) {
1147b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    subs(rd, rn, shifter_op, cond);
1148b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1149b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(rn != IP);
1150b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (ShifterOperand::CanHold(~value, &shifter_op)) {
1151b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mvn(IP, shifter_op, cond);
1152b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      adds(rd, rn, ShifterOperand(IP), cond);
1153b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) {
1154b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mvn(IP, shifter_op, cond);
1155b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      subs(rd, rn, ShifterOperand(IP), cond);
1156b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    } else {
1157b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      movw(IP, Low16Bits(value), cond);
1158b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      uint16_t value_high = High16Bits(value);
1159b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      if (value_high != 0) {
1160b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers        movt(IP, value_high, cond);
1161b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      }
1162b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      adds(rd, rn, ShifterOperand(IP), cond);
1163b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1164b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1165b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1166b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1167b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1168b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
1169b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  ShifterOperand shifter_op;
1170b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (ShifterOperand::CanHold(value, &shifter_op)) {
1171b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    mov(rd, shifter_op, cond);
1172b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else if (ShifterOperand::CanHold(~value, &shifter_op)) {
1173b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    mvn(rd, shifter_op, cond);
1174b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1175b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    movw(rd, Low16Bits(value), cond);
1176b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    uint16_t value_high = High16Bits(value);
1177b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (value_high != 0) {
1178b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      movt(rd, value_high, cond);
1179b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1180b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1181b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1182b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1183b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1184b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersbool Address::CanHoldLoadOffset(LoadOperandType type, int offset) {
1185b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  switch (type) {
1186b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSignedByte:
1187b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSignedHalfword:
1188b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadUnsignedHalfword:
1189b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadWordPair:
1190b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(8, offset);  // Addressing mode 3.
1191b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadUnsignedByte:
1192b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadWord:
1193b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(12, offset);  // Addressing mode 2.
1194b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSWord:
1195b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadDWord:
1196b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(10, offset);  // VFP addressing mode.
1197b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    default:
1198b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LOG(FATAL) << "UNREACHABLE";
1199b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return false;
1200b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1201b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1202b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1203b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1204b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersbool Address::CanHoldStoreOffset(StoreOperandType type, int offset) {
1205b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  switch (type) {
1206b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreHalfword:
1207b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreWordPair:
1208b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(8, offset);  // Addressing mode 3.
1209b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreByte:
1210b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreWord:
1211b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(12, offset);  // Addressing mode 2.
1212b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreSWord:
1213b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreDWord:
1214b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(10, offset);  // VFP addressing mode.
1215b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    default:
1216b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LOG(FATAL) << "UNREACHABLE";
1217b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return false;
1218b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1219b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1220b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1221b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1222b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Implementation note: this method must emit at most one instruction when
1223b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Address::CanHoldLoadOffset.
1224b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadFromOffset(LoadOperandType type,
1225b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                               Register reg,
1226b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                               Register base,
1227b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                               int32_t offset,
1228b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                               Condition cond) {
1229b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (!Address::CanHoldLoadOffset(type, offset)) {
1230b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(base != IP);
1231b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadImmediate(IP, offset, cond);
1232b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    add(IP, IP, ShifterOperand(base), cond);
1233b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    base = IP;
1234b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    offset = 0;
1235b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1236b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(Address::CanHoldLoadOffset(type, offset));
1237b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  switch (type) {
1238b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSignedByte:
1239b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrsb(reg, Address(base, offset), cond);
1240b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1241b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadUnsignedByte:
1242b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrb(reg, Address(base, offset), cond);
1243b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1244b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSignedHalfword:
1245b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrsh(reg, Address(base, offset), cond);
1246b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1247b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadUnsignedHalfword:
1248b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrh(reg, Address(base, offset), cond);
1249b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1250b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadWord:
1251b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldr(reg, Address(base, offset), cond);
1252b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1253b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadWordPair:
1254b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrd(reg, Address(base, offset), cond);
1255b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1256b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    default:
1257b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LOG(FATAL) << "UNREACHABLE";
1258b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1259b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1260b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1261b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1262b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Implementation note: this method must emit at most one instruction when
1263b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Address::CanHoldStoreOffset.
1264b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreToOffset(StoreOperandType type,
1265b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                              Register reg,
1266b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                              Register base,
1267b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                              int32_t offset,
1268b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                              Condition cond) {
1269b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (!Address::CanHoldStoreOffset(type, offset)) {
1270b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(reg != IP);
1271b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(base != IP);
1272b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadImmediate(IP, offset, cond);
1273b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    add(IP, IP, ShifterOperand(base), cond);
1274b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    base = IP;
1275b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    offset = 0;
1276b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1277b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(Address::CanHoldStoreOffset(type, offset));
1278b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  switch (type) {
1279b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreByte:
1280b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      strb(reg, Address(base, offset), cond);
1281b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1282b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreHalfword:
1283b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      strh(reg, Address(base, offset), cond);
1284b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1285b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreWord:
1286b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      str(reg, Address(base, offset), cond);
1287b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1288b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreWordPair:
1289b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      strd(reg, Address(base, offset), cond);
1290b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1291b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    default:
1292b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LOG(FATAL) << "UNREACHABLE";
1293b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1294b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1295b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1296b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Emit code that will create an activation on the stack
1297b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg) {
1298b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(IsAligned(frame_size, 16));
1299b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // TODO: use stm/ldm
1300b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, LR, SP, 0);
1301b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, method_reg.AsCoreRegister(), SP, -4);
1302b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  AddConstant(SP, -frame_size);
1303b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1304b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1305b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Emit code that will remove an activation from the stack
1306b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::RemoveFrame(size_t frame_size) {
1307b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(IsAligned(frame_size, 16));
1308b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, LR, SP, 0);
1309b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  AddConstant(SP, frame_size);
1310b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  mov(PC, ShifterOperand(LR));
1311b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1312b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1313b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::IncreaseFrameSize(size_t adjust) {
1314b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(IsAligned(adjust, 16));
1315b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  AddConstant(SP, -adjust);
1316b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1317b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1318b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::DecreaseFrameSize(size_t adjust) {
1319b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(IsAligned(adjust, 16));
1320b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  AddConstant(SP, adjust);
1321b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1322b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1323b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Store bytes from the given register onto the stack
1324b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::Store(FrameOffset dest, ManagedRegister src, size_t size) {
1325b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (src.IsCoreRegister()) {
1326b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_EQ(4u, size);
1327b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value());
1328b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1329b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // VFP
1330b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LOG(FATAL) << "TODO";
1331b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1332b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1333b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1334b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreRef(FrameOffset dest, ManagedRegister src) {
1335b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(src.IsCoreRegister());
1336b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value());
1337b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1338b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1339b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CopyRef(FrameOffset dest, FrameOffset src,
1340b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                        ManagedRegister scratch) {
1341b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value());
1342b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
1343b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1344b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1345b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadRef(ManagedRegister dest, ManagedRegister base,
1346b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                        MemberOffset offs) {
1347b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(dest.IsCoreRegister() && dest.IsCoreRegister());
1348b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, dest.AsCoreRegister(),
1349b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                 base.AsCoreRegister(), offs.Int32Value());
1350b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1351b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1352b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
1353b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                                      ManagedRegister scratch) {
1354b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1355b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadImmediate(scratch.AsCoreRegister(), imm);
1356b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
1357b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1358b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1359b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreImmediateToThread(ThreadOffset dest, uint32_t imm,
1360b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                                       ManagedRegister scratch) {
1361b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1362b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadImmediate(scratch.AsCoreRegister(), imm);
1363b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(), TR, dest.Int32Value());
1364b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1365b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1366b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::Load(ManagedRegister dest, FrameOffset src, size_t size) {
1367b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (dest.IsCoreRegister()) {
1368b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_EQ(4u, size);
1369b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadFromOffset(kLoadWord, dest.AsCoreRegister(), SP, src.Int32Value());
1370b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1371b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // TODO: VFP
1372b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LOG(FATAL) << "Unimplemented";
1373b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1374b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1375b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1376b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadRawPtrFromThread(ManagedRegister dest, ThreadOffset offs) {
1377b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(dest.IsCoreRegister());
1378b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, dest.AsCoreRegister(),
1379b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                 TR, offs.Int32Value());
1380b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1381b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1382b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CopyRawPtrFromThread(FrameOffset fr_offs, ThreadOffset thr_offs,
1383b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                          ManagedRegister scratch) {
1384b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1385b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1386b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                 TR, thr_offs.Int32Value());
1387b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(),
1388b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                SP, fr_offs.Int32Value());
1389b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1390b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1391b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CopyRawPtrToThread(ThreadOffset thr_offs, FrameOffset fr_offs,
1392b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                        ManagedRegister scratch) {
1393b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1394b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1395b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                 SP, fr_offs.Int32Value());
1396b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(),
1397b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                TR, thr_offs.Int32Value());
1398b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1399b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1400b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreStackOffsetToThread(ThreadOffset thr_offs,
1401b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                                         FrameOffset fr_offs,
1402b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                                         ManagedRegister scratch) {
1403b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1404b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  AddConstant(scratch.AsCoreRegister(), SP, fr_offs.Int32Value(), AL);
1405b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(),
1406b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                TR, thr_offs.Int32Value());
1407b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1408b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1409b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::Move(ManagedRegister dest, ManagedRegister src) {
1410b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (dest.IsCoreRegister()) {
1411b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(src.IsCoreRegister());
1412b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    mov(dest.AsCoreRegister(), ShifterOperand(src.AsCoreRegister()));
1413b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1414b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // TODO: VFP
1415b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LOG(FATAL) << "Unimplemented";
1416b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1417b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1418b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1419b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::Copy(FrameOffset dest, FrameOffset src, ManagedRegister scratch,
1420b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                     size_t size) {
1421b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1422b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (size == 4) {
1423b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1424b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                   SP, src.Int32Value());
1425b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    StoreToOffset(kStoreWord, scratch.AsCoreRegister(),
1426b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                  SP, dest.Int32Value());
1427b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1428b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // TODO: size != 4
1429b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LOG(FATAL) << "Unimplemented";
1430b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1431b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1432b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1433b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CreateStackHandle(ManagedRegister out_reg,
1434b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                                  FrameOffset handle_offset,
1435b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                                  ManagedRegister in_reg, bool null_allowed) {
1436b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(in_reg.IsCoreRegister());
1437b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(out_reg.IsCoreRegister());
1438b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (null_allowed) {
1439b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // Null values get a handle value of 0.  Otherwise, the handle value is
1440b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // the address in the stack handle block holding the reference.
1441b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // e.g. out_reg = (handle == 0) ? 0 : (SP+handle_offset)
1442b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    cmp(in_reg.AsCoreRegister(), ShifterOperand(0));
1443b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (!out_reg.Equals(in_reg)) {
1444b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LoadImmediate(out_reg.AsCoreRegister(), 0, EQ);
1445b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1446b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    AddConstant(out_reg.AsCoreRegister(), SP, handle_offset.Int32Value(), NE);
1447b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1448b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    AddConstant(out_reg.AsCoreRegister(), SP, handle_offset.Int32Value(), AL);
1449b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1450b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1451b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1452b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CreateStackHandle(FrameOffset out_off,
1453b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                                  FrameOffset handle_offset,
1454b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                                  ManagedRegister scratch, bool null_allowed) {
1455b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1456b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (null_allowed) {
1457b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP,
1458b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                   handle_offset.Int32Value());
1459b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // Null values get a handle value of 0.  Otherwise, the handle value is
1460b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // the address in the stack handle block holding the reference.
1461b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // e.g. scratch = (handle == 0) ? 0 : (SP+handle_offset)
1462b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    cmp(scratch.AsCoreRegister(), ShifterOperand(0));
1463b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    AddConstant(scratch.AsCoreRegister(), SP, handle_offset.Int32Value(), NE);
1464b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1465b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    AddConstant(scratch.AsCoreRegister(), SP, handle_offset.Int32Value(), AL);
1466b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1467b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, out_off.Int32Value());
1468b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1469b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1470b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadReferenceFromStackHandle(ManagedRegister out_reg,
1471b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                                             ManagedRegister in_reg,
1472b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                                             FrameOffset shb_offset) {
1473b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(out_reg.IsCoreRegister());
1474b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(in_reg.IsCoreRegister());
1475b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  Label null_arg;
1476b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (!out_reg.Equals(in_reg)) {
1477b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadImmediate(out_reg.AsCoreRegister(), 0, EQ);
1478b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1479b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  cmp(in_reg.AsCoreRegister(), ShifterOperand(0));
1480b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, out_reg.AsCoreRegister(), in_reg.AsCoreRegister(),
1481b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                 shb_offset.Int32Value(), NE);
1482b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1483b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1484b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::ValidateRef(ManagedRegister src, bool could_be_null) {
1485b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // TODO: not validating references
1486b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1487b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1488b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::ValidateRef(FrameOffset src, bool could_be_null) {
1489b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // TODO: not validating references
1490b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1491b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1492b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::Call(ManagedRegister base, MemberOffset offset,
1493b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                     ManagedRegister scratch) {
1494b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(base.IsCoreRegister());
1495b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1496b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1497b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                 base.AsCoreRegister(), offset.Int32Value());
1498b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  blx(scratch.AsCoreRegister());
1499b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // TODO: place reference map on call
1500b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1501b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1502b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Emit code that will lock the reference in the given register
1503b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LockReferenceOnStack(FrameOffset fr_offs) {
1504b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LOG(FATAL) << "TODO";
1505b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1506b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Emit code that will unlock the reference in the given register
1507b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::UnLockReferenceOnStack(FrameOffset fr_offs) {
1508b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LOG(FATAL) << "TODO";
1509b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1510b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
15116b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro}  // namespace art
1512