assembler_arm.cc revision b5d09b2f87202bc132ac3991d4b6d71f4f6d9264
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
16a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#include "assembler_arm.h"
182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
19578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "logging.h"
20578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "offsets.h"
21e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro#include "thread.h"
22578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "utils.h"
23a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
246b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapironamespace art {
252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace arm {
26a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
27a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// Instruction encoding bits.
28a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroenum {
29a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  H   = 1 << 5,   // halfword (or byte)
30a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  L   = 1 << 20,  // load (or store)
31a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  S   = 1 << 20,  // set condition code (or leave unchanged)
32a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  W   = 1 << 21,  // writeback base register (or leave unchanged)
33a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  A   = 1 << 21,  // accumulate in multiply instruction (or not)
34a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B   = 1 << 22,  // unsigned byte (or word)
35a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  N   = 1 << 22,  // long (or short)
36a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  U   = 1 << 23,  // positive (or negative) offset/index
37a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  P   = 1 << 24,  // offset/pre-indexed addressing (or post-indexed addressing)
38a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  I   = 1 << 25,  // immediate shifter operand (or not)
39a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
40a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B0 = 1,
41a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B1 = 1 << 1,
42a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B2 = 1 << 2,
43a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B3 = 1 << 3,
44a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B4 = 1 << 4,
45a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B5 = 1 << 5,
46a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B6 = 1 << 6,
47a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B7 = 1 << 7,
48a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B8 = 1 << 8,
49a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B9 = 1 << 9,
50a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B10 = 1 << 10,
51a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B11 = 1 << 11,
52a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B12 = 1 << 12,
53a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B16 = 1 << 16,
54a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B17 = 1 << 17,
55a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B18 = 1 << 18,
56a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B19 = 1 << 19,
57a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B20 = 1 << 20,
58a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B21 = 1 << 21,
59a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B22 = 1 << 22,
60a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B23 = 1 << 23,
61a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B24 = 1 << 24,
62a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B25 = 1 << 25,
63a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B26 = 1 << 26,
64a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B27 = 1 << 27,
65a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
66a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Instruction bit masks.
67a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  RdMask = 15 << 12,  // in str instruction
68a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CondMask = 15 << 28,
69a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CoprocessorMask = 15 << 8,
70a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  OpCodeMask = 15 << 21,  // in data-processing instructions
71a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Imm24Mask = (1 << 24) - 1,
72a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Off12Mask = (1 << 12) - 1,
73a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
74a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // ldrex/strex register field encodings.
75a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kLdExRnShift = 16,
76a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kLdExRtShift = 12,
77a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kStrExRnShift = 16,
78a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kStrExRdShift = 12,
79a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kStrExRtShift = 0,
80a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro};
81a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
82a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
831f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstatic const char* kRegisterNames[] = {
841f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
851f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  "fp", "ip", "sp", "lr", "pc"
861f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes};
871f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Register& rhs) {
881f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  if (rhs >= R0 && rhs <= PC) {
891f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes    os << kRegisterNames[rhs];
901f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  } else {
91b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "Register[" << static_cast<int>(rhs) << "]";
921f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  }
931f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  return os;
941f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}
951f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
961f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
971f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const SRegister& rhs) {
981f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  if (rhs >= S0 && rhs < kNumberOfSRegisters) {
99b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "s" << static_cast<int>(rhs);
1001f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  } else {
101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "SRegister[" << static_cast<int>(rhs) << "]";
1021f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  }
1031f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  return os;
1041f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}
1051f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
1061f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
1071f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const DRegister& rhs) {
1081f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  if (rhs >= D0 && rhs < kNumberOfDRegisters) {
109b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "d" << static_cast<int>(rhs);
1101f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  } else {
111b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "DRegister[" << static_cast<int>(rhs) << "]";
1121f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  }
1131f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  return os;
1141f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}
1151f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
1161f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
1171f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstatic const char* kConditionNames[] = {
118b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT",
119b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  "LE", "AL",
1201f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes};
1211f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Condition& rhs) {
1221f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  if (rhs >= EQ && rhs <= AL) {
1231f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes    os << kConditionNames[rhs];
1241f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  } else {
125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "Condition[" << static_cast<int>(rhs) << "]";
1261f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  }
1271f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  return os;
1281f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}
1291f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
1302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Emit(int32_t value) {
131a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
132a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  buffer_.Emit<int32_t>(value);
133a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
134a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
135a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitType01(Condition cond,
1372c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              int type,
1382c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              Opcode opcode,
1392c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              int set_cc,
1402c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              Register rn,
1412c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              Register rd,
1422c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              ShifterOperand so) {
143a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
144a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
145a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
146a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     type << kTypeShift |
147a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(opcode) << kOpcodeShift |
148a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     set_cc << kSShift |
149a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rn) << kRnShift |
150a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rd) << kRdShift |
151a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     so.encoding();
152a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
153a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
154a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
155a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitType5(Condition cond, int offset, bool link) {
157a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
158a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
159a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     5 << kTypeShift |
160a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (link ? 1 : 0) << kLinkShift;
1612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  Emit(ArmAssembler::EncodeBranchOffset(offset, encoding));
162a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
163a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
164a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitMemOp(Condition cond,
1662c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             bool load,
1672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             bool byte,
1682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             Register rd,
1692c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             Address ad) {
170a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
171a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
172a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
173a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B26 |
174a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (load ? L : 0) |
175a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (byte ? B : 0) |
176a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rd) << kRdShift) |
177a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ad.encoding();
178a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
179a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
180a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
181a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitMemOpAddressMode3(Condition cond,
1832c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                         int32_t mode,
1842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                         Register rd,
1852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                         Address ad) {
186a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
187a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
188a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
189a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B22  |
190a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     mode |
191a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rd) << kRdShift) |
192a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ad.encoding3();
193a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
194a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
195a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
196a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1972c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitMultiMemOp(Condition cond,
1982c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  BlockAddressMode am,
1992c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  bool load,
2002c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  Register base,
2012c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  RegList regs) {
202a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(base, kNoRegister);
203a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
204a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
205a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 |
206a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     am |
207a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (load ? L : 0) |
208a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(base) << kRnShift) |
209a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     regs;
210a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
211a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
212a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
213a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2142c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitShiftImmediate(Condition cond,
2152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                      Shift opcode,
2162c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                      Register rd,
2172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                      Register rm,
2182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                      ShifterOperand so) {
219a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
2201f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  CHECK_EQ(so.type(), 1U);
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() << kShiftImmShift |
225a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(opcode) << kShiftShift |
226a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rm);
227a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
228a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
229a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
230a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitShiftRegister(Condition cond,
2322c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                     Shift opcode,
2332c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                     Register rd,
2342c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                     Register rm,
2352c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                     ShifterOperand so) {
236a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
2371f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  CHECK_EQ(so.type(), 0U);
238a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
239a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(MOV) << kOpcodeShift |
240a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rd) << kRdShift |
241a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     so.encoding() << kShiftRegisterShift |
242a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(opcode) << kShiftShift |
243a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B4 |
244a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rm);
245a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
246a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
247a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
248a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitBranch(Condition cond, Label* label, bool link) {
250a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  if (label->IsBound()) {
251a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    EmitType5(cond, label->Position() - buffer_.Size(), link);
252a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  } else {
253a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    int position = buffer_.Size();
254a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    // Use the offset field of the branch instruction for linking the sites.
255a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    EmitType5(cond, label->position_, link);
256a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    label->LinkTo(position);
257a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
258a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
259a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2602c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::and_(Register rd, Register rn, ShifterOperand so,
2612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        Condition cond) {
262a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), AND, 0, rn, rd, so);
263a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
264a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
265a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2662c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::eor(Register rd, Register rn, ShifterOperand so,
2672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
268a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), EOR, 0, rn, rd, so);
269a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
270a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
271a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::sub(Register rd, Register rn, ShifterOperand so,
2732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
274a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), SUB, 0, rn, rd, so);
275a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
276a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2772c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::rsb(Register rd, Register rn, ShifterOperand so,
2782c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
279a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), RSB, 0, rn, rd, so);
280a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
281a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::rsbs(Register rd, Register rn, ShifterOperand so,
2832c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        Condition cond) {
284a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), RSB, 1, rn, rd, so);
285a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
286a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
287a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2882c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::add(Register rd, Register rn, ShifterOperand so,
2892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
290a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ADD, 0, rn, rd, so);
291a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
292a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
293a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::adds(Register rd, Register rn, ShifterOperand so,
2952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        Condition cond) {
296a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ADD, 1, rn, rd, so);
297a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
298a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
299a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3002c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::subs(Register rd, Register rn, ShifterOperand so,
3012c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        Condition cond) {
302a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), SUB, 1, rn, rd, so);
303a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
304a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
305a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::adc(Register rd, Register rn, ShifterOperand so,
3072c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
308a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ADC, 0, rn, rd, so);
309a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
310a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
311a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3122c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::sbc(Register rd, Register rn, ShifterOperand so,
3132c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
314a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), SBC, 0, rn, rd, so);
315a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
316a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
317a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::rsc(Register rd, Register rn, ShifterOperand so,
3192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
320a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), RSC, 0, rn, rd, so);
321a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
322a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
323a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::tst(Register rn, ShifterOperand so, Condition cond) {
325a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, PC);  // Reserve tst pc instruction for exception handler marker.
326a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), TST, 1, rn, R0, so);
327a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
328a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
329a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::teq(Register rn, ShifterOperand so, Condition cond) {
331a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, PC);  // Reserve teq pc instruction for exception handler marker.
332a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), TEQ, 1, rn, R0, so);
333a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
334a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
335a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::cmp(Register rn, ShifterOperand so, Condition cond) {
337a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), CMP, 1, rn, R0, so);
338a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
339a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
340a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3412c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::cmn(Register rn, ShifterOperand so, Condition cond) {
342a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), CMN, 1, rn, R0, so);
343a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
344a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
345a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3462c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::orr(Register rd, Register rn,
347a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    ShifterOperand so, Condition cond) {
348a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ORR, 0, rn, rd, so);
349a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
350a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
351a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3522c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::orrs(Register rd, Register rn,
3532c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        ShifterOperand so, Condition cond) {
354a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ORR, 1, rn, rd, so);
355a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
356a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
357a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3582c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mov(Register rd, ShifterOperand so, Condition cond) {
359a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), MOV, 0, R0, rd, so);
360a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
361a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
362a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::movs(Register rd, ShifterOperand so, Condition cond) {
364a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), MOV, 1, R0, rd, so);
365a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
366a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
367a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::bic(Register rd, Register rn, ShifterOperand so,
3692c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
370a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), BIC, 0, rn, rd, so);
371a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
372a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
373a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mvn(Register rd, ShifterOperand so, Condition cond) {
375a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), MVN, 0, R0, rd, so);
376a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
377a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
378a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mvns(Register rd, ShifterOperand so, Condition cond) {
380a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), MVN, 1, R0, rd, so);
381a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
382a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
383a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::clz(Register rd, Register rm, Condition cond) {
385a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
386a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rm, kNoRegister);
387a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
388a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, PC);
389a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rm, PC);
390a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
391a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B24 | B22 | B21 | (0xf << 16) |
392a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rd) << kRdShift) |
393a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (0xf << 8) | B4 | static_cast<int32_t>(rm);
394a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
395a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
396a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
397a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3982c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::movw(Register rd, uint16_t imm16, Condition cond) {
399a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
400a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
401a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B25 | B24 | ((imm16 >> 12) << 16) |
402a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
403a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
404a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
405a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
406a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4072c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::movt(Register rd, uint16_t imm16, Condition cond) {
408a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
409a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
410a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B25 | B24 | B22 | ((imm16 >> 12) << 16) |
411a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
412a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
413a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
414a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
415a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4162c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitMulOp(Condition cond, int32_t opcode,
4172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             Register rd, Register rn,
4182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             Register rm, Register rs) {
419a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
420a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, kNoRegister);
421a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rm, kNoRegister);
422a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rs, kNoRegister);
423a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
424a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = opcode |
425a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(cond) << kConditionShift) |
426a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(rn) << kRnShift) |
427a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(rd) << kRdShift) |
428a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(rs) << kRsShift) |
429a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      B7 | B4 |
430a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(rm) << kRmShift);
431a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
432a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
433a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
434a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4352c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mul(Register rd, Register rn, Register rm, Condition cond) {
436a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
437a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMulOp(cond, 0, R0, rd, rn, rm);
438a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
439a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
440a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4412c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mla(Register rd, Register rn, Register rm, Register ra,
4422c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
443a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
444a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMulOp(cond, B21, ra, rd, rn, rm);
445a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
446a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
447a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4482c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mls(Register rd, Register rn, Register rm, Register ra,
4492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
450a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
451a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMulOp(cond, B22 | B21, ra, rd, rn, rm);
452a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
453a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
454a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::umull(Register rd_lo, Register rd_hi, Register rn,
4562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Register rm, Condition cond) {
457a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
458a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm);
459a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
460a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
461a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldr(Register rd, Address ad, Condition cond) {
463a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOp(cond, true, false, rd, ad);
464a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
465a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
466a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::str(Register rd, Address ad, Condition cond) {
468a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOp(cond, false, false, rd, ad);
469a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
470a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
471a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrb(Register rd, Address ad, Condition cond) {
473a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOp(cond, true, true, rd, ad);
474a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
475a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
476a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4772c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::strb(Register rd, Address ad, Condition cond) {
478a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOp(cond, false, true, rd, ad);
479a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
480a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
481a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrh(Register rd, Address ad, Condition cond) {
483a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad);
484a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
485a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
486a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::strh(Register rd, Address ad, Condition cond) {
488a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad);
489a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
490a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
491a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4922c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrsb(Register rd, Address ad, Condition cond) {
493a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad);
494a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
495a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
496a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4972c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrsh(Register rd, Address ad, Condition cond) {
498a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad);
499a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
500a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
501a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5022c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrd(Register rd, Address ad, Condition cond) {
503a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_EQ(rd % 2, 0);
504a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad);
505a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
506a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
507a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5082c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::strd(Register rd, Address ad, Condition cond) {
509a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_EQ(rd % 2, 0);
510a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad);
511a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
512a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
513a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5142c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldm(BlockAddressMode am,
5152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Register base,
5162c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       RegList regs,
5172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
518a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMultiMemOp(cond, am, true, base, regs);
519a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
520a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
521a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::stm(BlockAddressMode am,
5232c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Register base,
5242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       RegList regs,
5252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
526a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMultiMemOp(cond, am, false, base, regs);
527a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
528a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
529a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrex(Register rt, Register rn, Condition cond) {
531a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, kNoRegister);
532a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
533a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
534a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
535a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B24 |
536a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B23 |
537a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     L   |
538a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rn) << kLdExRnShift) |
539a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt) << kLdExRtShift) |
540a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0;
541a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
542a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
543a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
544a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5452c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::strex(Register rd,
5462c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Register rt,
5472c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Register rn,
5482c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
549a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, kNoRegister);
550a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
551a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
552a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
553a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
554a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B24 |
555a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B23 |
556a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rn) << kStrExRnShift) |
557a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rd) << kStrExRdShift) |
558a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B10 | B9 | B8 | B7 | B4 |
559a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt) << kStrExRtShift);
560a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
561a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
562a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
563a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::clrex() {
565a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (kSpecialCondition << kConditionShift) |
566a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf;
567a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
568a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
569a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
570a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5712c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::nop(Condition cond) {
572a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
573a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
574a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B25 | B24 | B21 | (0xf << 12);
575a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
576a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
577a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
578a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovsr(SRegister sn, Register rt, 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 |
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
5942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovrs(Register rt, SRegister sn, Condition cond) {
595a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sn, kNoSRegister);
596a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
597a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
598a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
599a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
600a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
601a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B20 |
602a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) >> 1)*B16) |
603a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
604a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
605a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
606a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
607a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
608a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
6092c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovsrr(SRegister sm, Register rt, Register rt2,
6102c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                           Condition cond) {
611a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, kNoSRegister);
612a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, S31);
613a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
614a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
615a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
616a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, kNoRegister);
617a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, SP);
618a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, PC);
619a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
620a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
621a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B22 |
622a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt2)*B16) |
623a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
624a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
625a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(sm) >> 1);
626a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
627a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
628a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
629a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
6302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovrrs(Register rt, Register rt2, SRegister sm,
6312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                           Condition cond) {
632a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, kNoSRegister);
633a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, S31);
634a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
635a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
636a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
637a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, kNoRegister);
638a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, SP);
639a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, PC);
640a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, rt2);
641a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
642a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
643a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B22 | B20 |
644a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt2)*B16) |
645a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
646a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
647a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(sm) >> 1);
648a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
649a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
650a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
651a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
6522c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovdrr(DRegister dm, Register rt, Register rt2,
6532c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                           Condition cond) {
654a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dm, kNoDRegister);
655a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
656a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
657a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
658a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, kNoRegister);
659a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, SP);
660a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, PC);
661a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
662a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
663a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B22 |
664a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt2)*B16) |
665a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
666a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
667a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(dm) & 0xf);
668a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
669a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
670a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
671a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
6722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovrrd(Register rt, Register rt2, DRegister dm,
6732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                           Condition cond) {
674a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dm, kNoDRegister);
675a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
676a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
677a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
678a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, kNoRegister);
679a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, SP);
680a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, PC);
681a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, rt2);
682a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
683a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
684a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B22 | B20 |
685a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt2)*B16) |
686a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
687a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
688a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(dm) & 0xf);
689a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
690a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
691a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
692a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
6932c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vldrs(SRegister sd, Address ad, Condition cond) {
694a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sd, kNoSRegister);
695a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
696a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
697a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B24 | B20 |
698a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) & 1)*B22) |
699a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) >> 1)*B12) |
700a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | ad.vencoding();
701a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
702a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
703a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
704a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7052c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vstrs(SRegister sd, Address ad, Condition cond) {
706a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC);
707a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sd, kNoSRegister);
708a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
709a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
710a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B24 |
711a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) & 1)*B22) |
712a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) >> 1)*B12) |
713a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | ad.vencoding();
714a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
715a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
716a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
717a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vldrd(DRegister dd, Address ad, Condition cond) {
719a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dd, kNoDRegister);
720a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
721a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
722a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B24 | B20 |
723a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) >> 4)*B22) |
724a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
725a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | B8 | ad.vencoding();
726a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
727a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
728a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
729a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vstrd(DRegister dd, Address ad, Condition cond) {
731a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC);
732a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dd, kNoDRegister);
733a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
734a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
735a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B24 |
736a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) >> 4)*B22) |
737a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
738a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | B8 | ad.vencoding();
739a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
740a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
741a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
742a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7432c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitVFPsss(Condition cond, int32_t opcode,
7442c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              SRegister sd, SRegister sn, SRegister sm) {
745a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sd, kNoSRegister);
746a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sn, kNoSRegister);
747a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, kNoSRegister);
748a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
749a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
750a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B11 | B9 | opcode |
751a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) & 1)*B22) |
752a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) >> 1)*B16) |
753a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) >> 1)*B12) |
754a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) & 1)*B7) |
755a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sm) & 1)*B5) |
756a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(sm) >> 1);
757a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
758a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
759a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
760a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitVFPddd(Condition cond, int32_t opcode,
7622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              DRegister dd, DRegister dn, DRegister dm) {
763a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dd, kNoDRegister);
764a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dn, kNoDRegister);
765a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dm, kNoDRegister);
766a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
767a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
768a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B11 | B9 | B8 | opcode |
769a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) >> 4)*B22) |
770a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dn) & 0xf)*B16) |
771a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
772a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dn) >> 4)*B7) |
773a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dm) >> 4)*B5) |
774a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(dm) & 0xf);
775a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
776a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
777a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
778a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovs(SRegister sd, SRegister sm, Condition cond) {
780a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm);
781a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
782a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
783a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovd(DRegister dd, DRegister dm, Condition cond) {
785a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm);
786a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
787a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
788a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool ArmAssembler::vmovs(SRegister sd, float s_imm, Condition cond) {
790a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  uint32_t imm32 = bit_cast<uint32_t, float>(s_imm);
791a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  if (((imm32 & ((1 << 19) - 1)) == 0) &&
792a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) ||
793a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro       (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) {
794a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) |
795a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro        ((imm32 >> 19) & ((1 << 6) -1));
796a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf),
797a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro               sd, S0, S0);
798a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return true;
799a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
800a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  return false;
801a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
802a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
803a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8042c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool ArmAssembler::vmovd(DRegister dd, double d_imm, Condition cond) {
805a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  uint64_t imm64 = bit_cast<uint64_t, double>(d_imm);
806a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  if (((imm64 & ((1LL << 48) - 1)) == 0) &&
807a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) ||
808a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro       (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) {
809a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) |
810a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro        ((imm64 >> 48) & ((1 << 6) -1));
811a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf),
812a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro               dd, D0, D0);
813a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return true;
814a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
815a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  return false;
816a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
817a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
818a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vadds(SRegister sd, SRegister sn, SRegister sm,
8202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
821a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B21 | B20, sd, sn, sm);
822a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
823a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
824a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vaddd(DRegister dd, DRegister dn, DRegister dm,
8262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
827a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B21 | B20, dd, dn, dm);
828a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
829a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
830a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vsubs(SRegister sd, SRegister sn, SRegister sm,
8322c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
833a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm);
834a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
835a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
836a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8372c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vsubd(DRegister dd, DRegister dn, DRegister dm,
8382c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
839a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm);
840a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
841a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
842a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8432c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmuls(SRegister sd, SRegister sn, SRegister sm,
8442c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
845a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B21, sd, sn, sm);
846a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
847a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
848a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmuld(DRegister dd, DRegister dn, DRegister dm,
8502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
851a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B21, dd, dn, dm);
852a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
853a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
854a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmlas(SRegister sd, SRegister sn, SRegister sm,
8562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
857a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, 0, sd, sn, sm);
858a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
859a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
860a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmlad(DRegister dd, DRegister dn, DRegister dm,
8622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
863a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, 0, dd, dn, dm);
864a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
865a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
866a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmlss(SRegister sd, SRegister sn, SRegister sm,
8682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
869a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B6, sd, sn, sm);
870a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
871a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
872a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmlsd(DRegister dd, DRegister dn, DRegister dm,
8742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
875a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B6, dd, dn, dm);
876a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
877a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
878a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vdivs(SRegister sd, SRegister sn, SRegister sm,
8802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
881a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23, sd, sn, sm);
882a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
883a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
884a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vdivd(DRegister dd, DRegister dn, DRegister dm,
8862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
887a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23, dd, dn, dm);
888a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
889a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
890a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8912c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vabss(SRegister sd, SRegister sm, Condition cond) {
892a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm);
893a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
894a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
895a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8962c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vabsd(DRegister dd, DRegister dm, Condition cond) {
897a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm);
898a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
899a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
900a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9012c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vnegs(SRegister sd, SRegister sm, Condition cond) {
902a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm);
903a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
904a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
905a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vnegd(DRegister dd, DRegister dm, Condition cond) {
907a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm);
908a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
909a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
910a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9112c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vsqrts(SRegister sd, SRegister sm, Condition cond) {
912a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm);
913a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
914a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) {
916a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm);
917a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
918a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
919a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitVFPsd(Condition cond, int32_t opcode,
9212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             SRegister sd, DRegister dm) {
922a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sd, kNoSRegister);
923a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dm, kNoDRegister);
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>(sd) & 1)*B22) |
928a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) >> 1)*B12) |
929a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dm) >> 4)*B5) |
930a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(dm) & 0xf);
931a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
932a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
933a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
934a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9352c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitVFPds(Condition cond, int32_t opcode,
9362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             DRegister dd, SRegister sm) {
937a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dd, kNoDRegister);
938a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, kNoSRegister);
939a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
940a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
941a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B11 | B9 | opcode |
942a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) >> 4)*B22) |
943a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
944a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sm) & 1)*B5) |
945a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(sm) >> 1);
946a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
947a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
948a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
949a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) {
951a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm);
952a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
953a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
954a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtds(DRegister dd, SRegister sm, Condition cond) {
956a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm);
957a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
958a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
959a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9602c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtis(SRegister sd, SRegister sm, Condition cond) {
961a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm);
962a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
963a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
964a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtid(SRegister sd, DRegister dm, Condition cond) {
966a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm);
967a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
968a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
969a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9702c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) {
971a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm);
972a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
973a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
974a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9752c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) {
976a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm);
977a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
978a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
979a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtus(SRegister sd, SRegister sm, Condition cond) {
981a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm);
982a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
983a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
984a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtud(SRegister sd, DRegister dm, Condition cond) {
986a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm);
987a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
988a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
989a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9902c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) {
991a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm);
992a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
993a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
994a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) {
996a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm);
997a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
998a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
999a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10002c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcmps(SRegister sd, SRegister sm, Condition cond) {
1001a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm);
1002a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1003a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1004a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10052c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcmpd(DRegister dd, DRegister dm, Condition cond) {
1006a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm);
1007a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1008a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1009a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10102c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcmpsz(SRegister sd, Condition cond) {
1011a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0);
1012a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1013a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1014a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcmpdz(DRegister dd, Condition cond) {
1016a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
1017a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1018a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1019a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmstat(Condition cond) {  // VMRS APSR_nzcv, FPSCR
1021a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
1022a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1023a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 |
1024a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(PC)*B12) |
1025a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | B4;
1026a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
1027a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1028a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1029a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::svc(uint32_t imm24) {
1031a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK(IsUint(24, imm24));
1032a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24;
1033a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
1034a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1035a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1036a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10372c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::bkpt(uint16_t imm16) {
1038a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (AL << kConditionShift) | B24 | B21 |
1039a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
1040a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
1041a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1042a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1043a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10442c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::b(Label* label, Condition cond) {
1045a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitBranch(cond, label, false);
1046a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1047a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1048a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::bl(Label* label, Condition cond) {
1050a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitBranch(cond, label, true);
1051a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1052a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1053a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10542c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::blx(Register rm, Condition cond) {
1055a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rm, kNoRegister);
1056a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
1057a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1058a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B24 | B21 | (0xfff << 8) | B5 | B4 |
1059a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rm) << kRmShift);
1060a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
1061a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1062a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1063ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogersvoid ArmAssembler::bx(Register rm, Condition cond) {
1064ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers  CHECK_NE(rm, kNoRegister);
1065ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers  CHECK_NE(cond, kNoCondition);
1066ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1067ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers                     B24 | B21 | (0xfff << 8) | B4 |
1068ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers                     (static_cast<int32_t>(rm) << kRmShift);
1069ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers  Emit(encoding);
1070ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers}
1071a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::MarkExceptionHandler(Label* label) {
1073a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0));
1074a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Label l;
1075a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  b(&l);
1076a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitBranch(AL, label, false);
1077a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Bind(&l);
1078a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1079a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1080a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10812c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Bind(Label* label) {
1082a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK(!label->IsBound());
1083a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int bound_pc = buffer_.Size();
1084a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  while (label->IsLinked()) {
1085a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    int32_t position = label->Position();
1086a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    int32_t next = buffer_.Load<int32_t>(position);
10872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    int32_t encoded = ArmAssembler::EncodeBranchOffset(bound_pc - position, next);
1088a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    buffer_.Store<int32_t>(position, encoded);
10892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    label->position_ = ArmAssembler::DecodeBranchOffset(next);
1090a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
1091a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  label->BindTo(bound_pc);
1092a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1093a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1094a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EncodeUint32InTstInstructions(uint32_t data) {
1096a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // TODO: Consider using movw ip, <16 bits>.
1097a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  while (!IsUint(8, data)) {
1098a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    tst(R0, ShifterOperand(data & 0xFF), VS);
1099a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    data >>= 8;
1100a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
1101a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  tst(R0, ShifterOperand(data), MI);
1102a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1103a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1104b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
11052c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersint32_t ArmAssembler::EncodeBranchOffset(int offset, int32_t inst) {
1106a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // The offset is off by 8 due to the way the ARM CPUs read PC.
1107a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  offset -= 8;
110806b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes  CHECK_ALIGNED(offset, 4);
1109a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK(IsInt(CountOneBits(kBranchOffsetMask), offset));
1110a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1111a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Properly preserve only the bits supported in the instruction.
1112a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  offset >>= 2;
1113a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  offset &= kBranchOffsetMask;
1114a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  return (inst & ~kBranchOffsetMask) | offset;
1115a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1116a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1117a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
11182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersint ArmAssembler::DecodeBranchOffset(int32_t inst) {
1119a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Sign-extend, left-shift by 2, then add 8.
1120a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8);
1121a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1122a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
11232c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::AddConstant(Register rd, int32_t value, Condition cond) {
1124b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  AddConstant(rd, rd, value, cond);
1125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1126b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1127b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
11282c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::AddConstant(Register rd, Register rn, int32_t value,
11292c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                               Condition cond) {
1130b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (value == 0) {
1131b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (rd != rn) {
1132b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mov(rd, ShifterOperand(rn), cond);
1133b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1134b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return;
1135b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1136b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // We prefer to select the shorter code sequence rather than selecting add for
1137b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // positive values and sub for negatives ones, which would slightly improve
1138b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // the readability of generated code for some constants.
1139b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  ShifterOperand shifter_op;
1140b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (ShifterOperand::CanHold(value, &shifter_op)) {
1141b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    add(rd, rn, shifter_op, cond);
1142b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else if (ShifterOperand::CanHold(-value, &shifter_op)) {
1143b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    sub(rd, rn, shifter_op, cond);
1144b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1145b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(rn != IP);
1146b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (ShifterOperand::CanHold(~value, &shifter_op)) {
1147b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mvn(IP, shifter_op, cond);
1148b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      add(rd, rn, ShifterOperand(IP), cond);
1149b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) {
1150b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mvn(IP, shifter_op, cond);
1151b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      sub(rd, rn, ShifterOperand(IP), cond);
1152b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    } else {
1153b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      movw(IP, Low16Bits(value), cond);
1154b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      uint16_t value_high = High16Bits(value);
1155b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      if (value_high != 0) {
1156b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers        movt(IP, value_high, cond);
1157b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      }
1158b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      add(rd, rn, ShifterOperand(IP), cond);
1159b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1160b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1161b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1162b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1163b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
11642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::AddConstantSetFlags(Register rd, Register rn, int32_t value,
11652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                       Condition cond) {
1166b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  ShifterOperand shifter_op;
1167b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (ShifterOperand::CanHold(value, &shifter_op)) {
1168b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    adds(rd, rn, shifter_op, cond);
1169b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else if (ShifterOperand::CanHold(-value, &shifter_op)) {
1170b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    subs(rd, rn, shifter_op, cond);
1171b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1172b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(rn != IP);
1173b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (ShifterOperand::CanHold(~value, &shifter_op)) {
1174b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mvn(IP, shifter_op, cond);
1175b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      adds(rd, rn, ShifterOperand(IP), cond);
1176b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) {
1177b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mvn(IP, shifter_op, cond);
1178b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      subs(rd, rn, ShifterOperand(IP), cond);
1179b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    } else {
1180b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      movw(IP, Low16Bits(value), cond);
1181b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      uint16_t value_high = High16Bits(value);
1182b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      if (value_high != 0) {
1183b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers        movt(IP, value_high, cond);
1184b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      }
1185b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      adds(rd, rn, ShifterOperand(IP), cond);
1186b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1187b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1188b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1189b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1190b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
11912c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
1192b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  ShifterOperand shifter_op;
1193b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (ShifterOperand::CanHold(value, &shifter_op)) {
1194b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    mov(rd, shifter_op, cond);
1195b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else if (ShifterOperand::CanHold(~value, &shifter_op)) {
1196b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    mvn(rd, shifter_op, cond);
1197b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1198b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    movw(rd, Low16Bits(value), cond);
1199b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    uint16_t value_high = High16Bits(value);
1200b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (value_high != 0) {
1201b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      movt(rd, value_high, cond);
1202b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1203b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1204b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1205b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1206b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1207b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersbool Address::CanHoldLoadOffset(LoadOperandType type, int offset) {
1208b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  switch (type) {
1209b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSignedByte:
1210b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSignedHalfword:
1211b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadUnsignedHalfword:
1212b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadWordPair:
1213b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(8, offset);  // Addressing mode 3.
1214b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadUnsignedByte:
1215b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadWord:
1216b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(12, offset);  // Addressing mode 2.
1217b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSWord:
1218b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadDWord:
1219b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(10, offset);  // VFP addressing mode.
1220b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    default:
1221b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LOG(FATAL) << "UNREACHABLE";
1222b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return false;
1223b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1224b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1225b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1226b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1227b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersbool Address::CanHoldStoreOffset(StoreOperandType type, int offset) {
1228b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  switch (type) {
1229b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreHalfword:
1230b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreWordPair:
1231b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(8, offset);  // Addressing mode 3.
1232b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreByte:
1233b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreWord:
1234b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(12, offset);  // Addressing mode 2.
1235b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreSWord:
1236b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreDWord:
1237b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(10, offset);  // VFP addressing mode.
1238b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    default:
1239b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LOG(FATAL) << "UNREACHABLE";
1240b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return false;
1241b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1242b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1243b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1244b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1245b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Implementation note: this method must emit at most one instruction when
1246b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Address::CanHoldLoadOffset.
12472c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadFromOffset(LoadOperandType type,
1248b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                               Register reg,
1249b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                               Register base,
1250b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                               int32_t offset,
1251b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                               Condition cond) {
1252b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (!Address::CanHoldLoadOffset(type, offset)) {
1253b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(base != IP);
1254b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadImmediate(IP, offset, cond);
1255b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    add(IP, IP, ShifterOperand(base), cond);
1256b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    base = IP;
1257b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    offset = 0;
1258b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1259b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(Address::CanHoldLoadOffset(type, offset));
1260b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  switch (type) {
1261b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSignedByte:
1262b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrsb(reg, Address(base, offset), cond);
1263b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1264b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadUnsignedByte:
1265b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrb(reg, Address(base, offset), cond);
1266b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1267b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSignedHalfword:
1268b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrsh(reg, Address(base, offset), cond);
1269b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1270b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadUnsignedHalfword:
1271b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrh(reg, Address(base, offset), cond);
1272b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1273b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadWord:
1274b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldr(reg, Address(base, offset), cond);
1275b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1276b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadWordPair:
1277b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrd(reg, Address(base, offset), cond);
1278b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1279b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    default:
1280b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LOG(FATAL) << "UNREACHABLE";
1281b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1282b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1283b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1284e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when
1285e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldLoadOffset, as expected by JIT::GuardedLoadFromOffset.
12862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadSFromOffset(SRegister reg,
12872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   Register base,
12882c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   int32_t offset,
12892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   Condition cond) {
1290e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  if (!Address::CanHoldLoadOffset(kLoadSWord, offset)) {
1291e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK_NE(base, IP);
1292e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    LoadImmediate(IP, offset, cond);
1293e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    add(IP, IP, ShifterOperand(base), cond);
1294e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    base = IP;
1295e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    offset = 0;
1296e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  }
1297e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  CHECK(Address::CanHoldLoadOffset(kLoadSWord, offset));
1298e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  vldrs(reg, Address(base, offset), cond);
1299e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro}
1300e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro
1301e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when
1302e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldLoadOffset, as expected by JIT::GuardedLoadFromOffset.
13032c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadDFromOffset(DRegister reg,
13042c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   Register base,
13052c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   int32_t offset,
13062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   Condition cond) {
1307e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  if (!Address::CanHoldLoadOffset(kLoadDWord, offset)) {
1308e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK_NE(base, IP);
1309e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    LoadImmediate(IP, offset, cond);
1310e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    add(IP, IP, ShifterOperand(base), cond);
1311e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    base = IP;
1312e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    offset = 0;
1313e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  }
1314e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  CHECK(Address::CanHoldLoadOffset(kLoadDWord, offset));
1315e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  vldrd(reg, Address(base, offset), cond);
1316e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro}
1317b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1318b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Implementation note: this method must emit at most one instruction when
1319b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Address::CanHoldStoreOffset.
13202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreToOffset(StoreOperandType type,
13212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                 Register reg,
13222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                 Register base,
13232c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                 int32_t offset,
13242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                 Condition cond) {
1325b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (!Address::CanHoldStoreOffset(type, offset)) {
1326b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(reg != IP);
1327b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(base != IP);
1328b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadImmediate(IP, offset, cond);
1329b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    add(IP, IP, ShifterOperand(base), cond);
1330b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    base = IP;
1331b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    offset = 0;
1332b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1333b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(Address::CanHoldStoreOffset(type, offset));
1334b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  switch (type) {
1335b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreByte:
1336b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      strb(reg, Address(base, offset), cond);
1337b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1338b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreHalfword:
1339b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      strh(reg, Address(base, offset), cond);
1340b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1341b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreWord:
1342b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      str(reg, Address(base, offset), cond);
1343b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1344b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreWordPair:
1345b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      strd(reg, Address(base, offset), cond);
1346b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1347b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    default:
1348b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LOG(FATAL) << "UNREACHABLE";
1349b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1350b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1351b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1352e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when
1353e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldStoreOffset, as expected by JIT::GuardedStoreToOffset.
13542c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreSToOffset(SRegister reg,
13552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  Register base,
13562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  int32_t offset,
13572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  Condition cond) {
1358e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  if (!Address::CanHoldStoreOffset(kStoreSWord, offset)) {
1359e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK_NE(base, IP);
1360e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    LoadImmediate(IP, offset, cond);
1361e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    add(IP, IP, ShifterOperand(base), cond);
1362e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    base = IP;
1363e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    offset = 0;
1364e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  }
1365e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  CHECK(Address::CanHoldStoreOffset(kStoreSWord, offset));
1366e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  vstrs(reg, Address(base, offset), cond);
1367e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro}
1368e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro
1369e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when
1370e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldStoreOffset, as expected by JIT::GuardedStoreSToOffset.
13712c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreDToOffset(DRegister reg,
13722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  Register base,
13732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  int32_t offset,
13742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  Condition cond) {
1375e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  if (!Address::CanHoldStoreOffset(kStoreDWord, offset)) {
1376e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK_NE(base, IP);
1377e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    LoadImmediate(IP, offset, cond);
1378e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    add(IP, IP, ShifterOperand(base), cond);
1379e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    base = IP;
1380e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    offset = 0;
1381e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  }
1382e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  CHECK(Address::CanHoldStoreOffset(kStoreDWord, offset));
1383e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  vstrd(reg, Address(base, offset), cond);
1384e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro}
1385e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro
13862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Push(Register rd, Condition cond) {
13879b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  str(rd, Address(SP, -kRegisterSize, Address::PreIndex), cond);
13889b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
13899b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
13902c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Pop(Register rd, Condition cond) {
13919b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  ldr(rd, Address(SP, kRegisterSize, Address::PostIndex), cond);
13929b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
13939b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
13942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::PushList(RegList regs, Condition cond) {
13959b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  stm(DB_W, SP, regs, cond);
13969b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
13979b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
13982c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::PopList(RegList regs, Condition cond) {
13999b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  ldm(IA_W, SP, regs, cond);
14009b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
14019b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
14022c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Mov(Register rd, Register rm, Condition cond) {
14039b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  if (rd != rm) {
14049b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro    mov(rd, ShifterOperand(rm), cond);
14059b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  }
14069b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
14079b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
14082c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Lsl(Register rd, Register rm, uint32_t shift_imm,
14092c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
14109b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  CHECK_NE(shift_imm, 0u);  // Do not use Lsl if no shift is wanted.
14119b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  mov(rd, ShifterOperand(rm, LSL, shift_imm), cond);
14129b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
14139b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
14142c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Lsr(Register rd, Register rm, uint32_t shift_imm,
14152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
14169b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  CHECK_NE(shift_imm, 0u);  // Do not use Lsr if no shift is wanted.
14179b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
14189b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  mov(rd, ShifterOperand(rm, LSR, shift_imm), cond);
14199b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
14209b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
14212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Asr(Register rd, Register rm, uint32_t shift_imm,
14222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
14239b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  CHECK_NE(shift_imm, 0u);  // Do not use Asr if no shift is wanted.
14249b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
14259b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  mov(rd, ShifterOperand(rm, ASR, shift_imm), cond);
14269b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
14279b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
14282c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Ror(Register rd, Register rm, uint32_t shift_imm,
14292c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
14309b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  CHECK_NE(shift_imm, 0u);  // Use Rrx instruction.
14319b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  mov(rd, ShifterOperand(rm, ROR, shift_imm), cond);
14329b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
14339b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
14342c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Rrx(Register rd, Register rm, Condition cond) {
14359b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  mov(rd, ShifterOperand(rm, ROR, 0), cond);
14369b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
14379b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
14382c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
1439b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers                              const std::vector<ManagedRegister>& callee_save_regs,
1440b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers                              const std::vector<ManagedRegister>& entry_spills) {
144106b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes  CHECK_ALIGNED(frame_size, kStackAlignment);
1442b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  DCHECK_EQ(entry_spills.size(), 0u);
14432c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  CHECK_EQ(R0, method_reg.AsArm().AsCoreRegister());
1444bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
1445bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Push callee saves and link register
1446bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  RegList push_list = 1 << LR;
1447bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  size_t pushed_values = 1;
1448bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  for (size_t i = 0; i < callee_save_regs.size(); i++) {
1449bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    Register reg = callee_save_regs.at(i).AsArm().AsCoreRegister();
1450bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    push_list |= 1 << reg;
1451bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    pushed_values++;
14520d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers  }
1453bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  PushList(push_list);
1454bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
1455bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Increase frame to required size
1456bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  CHECK_GT(frame_size, pushed_values * kPointerSize);  // Must be at least space to push Method*
1457bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  size_t adjust = frame_size - (pushed_values * kPointerSize);
1458bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  IncreaseFrameSize(adjust);
1459bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
1460bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Write out Method*
1461bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  StoreToOffset(kStoreWord, R0, SP, 0);
1462b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1463b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
14642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::RemoveFrame(size_t frame_size,
1465bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers                              const std::vector<ManagedRegister>& callee_save_regs) {
146606b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes  CHECK_ALIGNED(frame_size, kStackAlignment);
1467bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Compute callee saves to pop and PC
1468bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  RegList pop_list = 1 << PC;
1469bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  size_t pop_values = 1;
1470bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  for (size_t i = 0; i < callee_save_regs.size(); i++) {
1471bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    Register reg = callee_save_regs.at(i).AsArm().AsCoreRegister();
1472bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    pop_list |= 1 << reg;
1473bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    pop_values++;
14740d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers  }
1475bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
1476bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Decrease frame to start of callee saves
1477bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  CHECK_GT(frame_size, pop_values * kPointerSize);
1478bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  size_t adjust = frame_size - (pop_values * kPointerSize);
1479bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  DecreaseFrameSize(adjust);
1480bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
1481bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Pop callee saves and PC
1482bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  PopList(pop_list);
14830d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers}
14840d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers
14852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::IncreaseFrameSize(size_t adjust) {
1486b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  AddConstant(SP, -adjust);
1487b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1488b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
14892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::DecreaseFrameSize(size_t adjust) {
1490b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  AddConstant(SP, adjust);
1491b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1492b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
14932c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Store(FrameOffset dest, ManagedRegister msrc, size_t size) {
14942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister src = msrc.AsArm();
1495e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  if (src.IsNoRegister()) {
1496e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK_EQ(0u, size);
1497e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  } else if (src.IsCoreRegister()) {
1498b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_EQ(4u, size);
1499b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value());
1500e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  } else if (src.IsRegisterPair()) {
1501e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK_EQ(8u, size);
1502e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    StoreToOffset(kStoreWord, src.AsRegisterPairLow(), SP, dest.Int32Value());
1503e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    StoreToOffset(kStoreWord, src.AsRegisterPairHigh(),
1504e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro                  SP, dest.Int32Value() + 4);
1505e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  } else if (src.IsSRegister()) {
1506e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    StoreSToOffset(src.AsSRegister(), SP, dest.Int32Value());
1507b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1508e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK(src.IsDRegister());
1509e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    StoreDToOffset(src.AsDRegister(), SP, dest.Int32Value());
1510b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1511b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1512b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
15132c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreRef(FrameOffset dest, ManagedRegister msrc) {
15142c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister src = msrc.AsArm();
1515b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(src.IsCoreRegister());
1516b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value());
1517b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1518b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
15192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreRawPtr(FrameOffset dest, ManagedRegister msrc) {
15202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister src = msrc.AsArm();
1521df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers  CHECK(src.IsCoreRegister());
1522df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers  StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value());
1523df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers}
1524df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers
15252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreSpanning(FrameOffset dest, ManagedRegister msrc,
15262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              FrameOffset in_off, ManagedRegister mscratch) {
15272c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister src = msrc.AsArm();
15282c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
15297a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers  StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value());
15307a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, in_off.Int32Value());
15317a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value() + 4);
15327a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers}
15337a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers
15342c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CopyRef(FrameOffset dest, FrameOffset src,
15352c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        ManagedRegister mscratch) {
15362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1537b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value());
1538b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
1539b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1540b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
15412c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadRef(ManagedRegister mdest, ManagedRegister base,
15422c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                           MemberOffset offs) {
15432c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister dest = mdest.AsArm();
1544b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(dest.IsCoreRegister() && dest.IsCoreRegister());
1545b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, dest.AsCoreRegister(),
15462c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                 base.AsArm().AsCoreRegister(), offs.Int32Value());
1547b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1548b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
15492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadRef(ManagedRegister mdest, FrameOffset  src) {
15502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister dest = mdest.AsArm();
1551362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes  CHECK(dest.IsCoreRegister());
1552362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes  LoadFromOffset(kLoadWord, dest.AsCoreRegister(), SP, src.Int32Value());
1553362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes}
15542c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
15552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadRawPtr(ManagedRegister mdest, ManagedRegister base,
1556a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers                           Offset offs) {
15572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister dest = mdest.AsArm();
1558a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers  CHECK(dest.IsCoreRegister() && dest.IsCoreRegister());
1559a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers  LoadFromOffset(kLoadWord, dest.AsCoreRegister(),
15602c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                 base.AsArm().AsCoreRegister(), offs.Int32Value());
1561a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers}
1562a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers
15632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
15642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                      ManagedRegister mscratch) {
15652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1566b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1567b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadImmediate(scratch.AsCoreRegister(), imm);
1568b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
1569b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1570b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
15712c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreImmediateToThread(ThreadOffset dest, uint32_t imm,
15722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                       ManagedRegister mscratch) {
15732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1574b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1575b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadImmediate(scratch.AsCoreRegister(), imm);
1576b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(), TR, dest.Int32Value());
1577b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1578b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
15792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Load(ManagedRegister mdest, FrameOffset src, size_t size) {
15802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister dest = mdest.AsArm();
1581e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  if (dest.IsNoRegister()) {
1582e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK_EQ(0u, size);
1583e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  } else if (dest.IsCoreRegister()) {
1584b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_EQ(4u, size);
1585b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadFromOffset(kLoadWord, dest.AsCoreRegister(), SP, src.Int32Value());
1586e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  } else if (dest.IsRegisterPair()) {
1587e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK_EQ(8u, size);
1588e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    LoadFromOffset(kLoadWord, dest.AsRegisterPairLow(), SP, src.Int32Value());
15895a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers    LoadFromOffset(kLoadWord, dest.AsRegisterPairHigh(), SP, src.Int32Value() + 4);
1590e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  } else if (dest.IsSRegister()) {
1591e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    LoadSFromOffset(dest.AsSRegister(), SP, src.Int32Value());
1592b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1593e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK(dest.IsDRegister());
1594e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    LoadDFromOffset(dest.AsDRegister(), SP, src.Int32Value());
1595b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1596b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1597b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
15985a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogersvoid ArmAssembler::Load(ManagedRegister mdest, ThreadOffset src, size_t size) {
15995a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  ArmManagedRegister dest = mdest.AsArm();
16005a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  if (dest.IsNoRegister()) {
16015a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers    CHECK_EQ(0u, size);
16025a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  } else if (dest.IsCoreRegister()) {
16035a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers    CHECK_EQ(4u, size);
16045a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers    LoadFromOffset(kLoadWord, dest.AsCoreRegister(), TR, src.Int32Value());
16055a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  } else if (dest.IsRegisterPair()) {
16065a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers    CHECK_EQ(8u, size);
16075a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers    LoadFromOffset(kLoadWord, dest.AsRegisterPairLow(), TR, src.Int32Value());
16085a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers    LoadFromOffset(kLoadWord, dest.AsRegisterPairHigh(), TR, src.Int32Value() + 4);
16095a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  } else if (dest.IsSRegister()) {
16105a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers    LoadSFromOffset(dest.AsSRegister(), TR, src.Int32Value());
16115a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  } else {
16125a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers    CHECK(dest.IsDRegister());
16135a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers    LoadDFromOffset(dest.AsDRegister(), TR, src.Int32Value());
16145a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  }
16155a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers}
16165a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers
16172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadRawPtrFromThread(ManagedRegister mdest,
16182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                        ThreadOffset offs) {
16192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister dest = mdest.AsArm();
1620b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(dest.IsCoreRegister());
1621b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, dest.AsCoreRegister(),
1622b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                 TR, offs.Int32Value());
1623b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1624b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
16252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CopyRawPtrFromThread(FrameOffset fr_offs,
16262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                        ThreadOffset thr_offs,
16272c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                        ManagedRegister mscratch) {
16282c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1629b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1630b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1631b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                 TR, thr_offs.Int32Value());
1632b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(),
1633b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                SP, fr_offs.Int32Value());
1634b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1635b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
16362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CopyRawPtrToThread(ThreadOffset thr_offs,
16372c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                      FrameOffset fr_offs,
16382c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                      ManagedRegister mscratch) {
16392c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1640b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1641b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1642b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                 SP, fr_offs.Int32Value());
1643b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(),
1644b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                TR, thr_offs.Int32Value());
1645b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1646b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
16472c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreStackOffsetToThread(ThreadOffset thr_offs,
16482c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                            FrameOffset fr_offs,
16492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                            ManagedRegister mscratch) {
16502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1651b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1652b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  AddConstant(scratch.AsCoreRegister(), SP, fr_offs.Int32Value(), AL);
1653b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(),
1654b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                TR, thr_offs.Int32Value());
1655b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1656b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
16572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreStackPointerToThread(ThreadOffset thr_offs) {
165845a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  StoreToOffset(kStoreWord, SP, TR, thr_offs.Int32Value());
165945a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers}
166045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
1661b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogersvoid ArmAssembler::Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) {
16622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister dest = mdest.AsArm();
16632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister src = msrc.AsArm();
1664e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  if (!dest.Equals(src)) {
1665e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    if (dest.IsCoreRegister()) {
1666e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro      CHECK(src.IsCoreRegister());
1667e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro      mov(dest.AsCoreRegister(), ShifterOperand(src.AsCoreRegister()));
16687a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers    } else if (dest.IsDRegister()) {
16697a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      CHECK(src.IsDRegister());
16707a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      vmovd(dest.AsDRegister(), src.AsDRegister());
16717a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers    } else if (dest.IsSRegister()) {
16727a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      CHECK(src.IsSRegister());
16737a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      vmovs(dest.AsSRegister(), src.AsSRegister());
1674e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    } else {
16757a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      CHECK(dest.IsRegisterPair());
16767a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      CHECK(src.IsRegisterPair());
16777a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      // Ensure that the first move doesn't clobber the input of the second
16787a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      if (src.AsRegisterPairHigh() != dest.AsRegisterPairLow()) {
16797a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers        mov(dest.AsRegisterPairLow(), ShifterOperand(src.AsRegisterPairLow()));
16807a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers        mov(dest.AsRegisterPairHigh(), ShifterOperand(src.AsRegisterPairHigh()));
16817a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      } else {
16827a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers        mov(dest.AsRegisterPairHigh(), ShifterOperand(src.AsRegisterPairHigh()));
16837a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers        mov(dest.AsRegisterPairLow(), ShifterOperand(src.AsRegisterPairLow()));
16847a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      }
1685e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    }
1686b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1687b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1688b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1689dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogersvoid ArmAssembler::Copy(FrameOffset dest, FrameOffset src, ManagedRegister mscratch, size_t size) {
16902c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1691b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
16925381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao  CHECK(size == 4 || size == 8);
1693b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (size == 4) {
1694dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers    LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value());
1695dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers    StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
16965381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao  } else if (size == 8) {
1697dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers    LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value());
1698dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers    StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
1699dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers    LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value() + 4);
1700dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers    StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value() + 4);
1701b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1702b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1703b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1704dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogersvoid ArmAssembler::Copy(FrameOffset dest, ManagedRegister src_base, Offset src_offset,
1705dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers                        ManagedRegister mscratch, size_t size) {
1706dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers  Register scratch = mscratch.AsArm().AsCoreRegister();
1707dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers  CHECK_EQ(size, 4u);
1708dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers  LoadFromOffset(kLoadWord, scratch, src_base.AsArm().AsCoreRegister(), src_offset.Int32Value());
1709dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers  StoreToOffset(kStoreWord, scratch, SP, dest.Int32Value());
1710dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers}
1711dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers
17125a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogersvoid ArmAssembler::Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
17135a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers                        ManagedRegister mscratch, size_t size) {
17145a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  Register scratch = mscratch.AsArm().AsCoreRegister();
17155a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  CHECK_EQ(size, 4u);
17165a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  LoadFromOffset(kLoadWord, scratch, SP, src.Int32Value());
17175a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  StoreToOffset(kStoreWord, scratch, dest_base.AsArm().AsCoreRegister(), dest_offset.Int32Value());
17185a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers}
17195a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers
1720dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogersvoid ArmAssembler::Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset,
1721dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers                        ManagedRegister mscratch, size_t size) {
1722dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers  UNIMPLEMENTED(FATAL);
1723dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers}
1724dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers
17255a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogersvoid ArmAssembler::Copy(ManagedRegister dest, Offset dest_offset,
17265a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers                        ManagedRegister src, Offset src_offset,
17275a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers                        ManagedRegister mscratch, size_t size) {
1728dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers  CHECK_EQ(size, 4u);
17295a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  Register scratch = mscratch.AsArm().AsCoreRegister();
17305a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  LoadFromOffset(kLoadWord, scratch, src.AsArm().AsCoreRegister(), src_offset.Int32Value());
17315a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  StoreToOffset(kStoreWord, scratch, dest.AsArm().AsCoreRegister(), dest_offset.Int32Value());
17325a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers}
17335a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers
17345a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogersvoid ArmAssembler::Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
17355a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers                        ManagedRegister scratch, size_t size) {
17365a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  UNIMPLEMENTED(FATAL);
1737dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers}
1738dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers
1739dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers
1740e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogersvoid ArmAssembler::MemoryBarrier(ManagedRegister mscratch) {
1741e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#if ANDROID_SMP != 0
1742e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#if defined(__ARM_HAVE_DMB)
1743e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  int32_t encoding = 0xf57ff05f;  // dmb
1744e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  Emit(encoding);
1745e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#elif  defined(__ARM_HAVE_LDREX_STREX)
1746e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  CHECK(mscratch.AsArm().AsCoreRegister() == R12);
1747e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  LoadImmediate(R12, 0);
1748e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  int32_t encoding = 0xee07cfba;  // mcr p15, 0, r12, c7, c10, 5
1749e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  Emit(encoding);
1750e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#else
1751e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  CHECK(mscratch.AsArm().AsCoreRegister() == R12);
1752e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  LoadImmediate(R12, 0xffff0fa0);  // kuser_memory_barrier
1753e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  blx(R12);
1754e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#endif
1755e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#endif
1756e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers}
1757e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers
17582c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CreateSirtEntry(ManagedRegister mout_reg,
17592c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   FrameOffset sirt_offset,
17602c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   ManagedRegister min_reg, bool null_allowed) {
17612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister out_reg = mout_reg.AsArm();
17622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister in_reg = min_reg.AsArm();
1763e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  CHECK(in_reg.IsNoRegister() || in_reg.IsCoreRegister());
1764b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(out_reg.IsCoreRegister());
1765b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (null_allowed) {
1766408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    // Null values get a SIRT entry value of 0.  Otherwise, the SIRT entry is
1767408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    // the address in the SIRT holding the reference.
1768b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // e.g. out_reg = (handle == 0) ? 0 : (SP+handle_offset)
1769e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    if (in_reg.IsNoRegister()) {
1770e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro      LoadFromOffset(kLoadWord, out_reg.AsCoreRegister(),
1771408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers                     SP, sirt_offset.Int32Value());
1772e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro      in_reg = out_reg;
1773e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    }
1774b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    cmp(in_reg.AsCoreRegister(), ShifterOperand(0));
1775b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (!out_reg.Equals(in_reg)) {
1776b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LoadImmediate(out_reg.AsCoreRegister(), 0, EQ);
1777b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1778408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    AddConstant(out_reg.AsCoreRegister(), SP, sirt_offset.Int32Value(), NE);
1779b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1780408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    AddConstant(out_reg.AsCoreRegister(), SP, sirt_offset.Int32Value(), AL);
1781b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1782b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1783b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
17842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CreateSirtEntry(FrameOffset out_off,
17852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   FrameOffset sirt_offset,
17862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   ManagedRegister mscratch,
17872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   bool null_allowed) {
17882c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1789b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1790b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (null_allowed) {
1791b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP,
1792408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers                   sirt_offset.Int32Value());
1793408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    // Null values get a SIRT entry value of 0.  Otherwise, the sirt entry is
1794408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    // the address in the SIRT holding the reference.
1795408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    // e.g. scratch = (scratch == 0) ? 0 : (SP+sirt_offset)
1796b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    cmp(scratch.AsCoreRegister(), ShifterOperand(0));
1797408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    AddConstant(scratch.AsCoreRegister(), SP, sirt_offset.Int32Value(), NE);
1798b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1799408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    AddConstant(scratch.AsCoreRegister(), SP, sirt_offset.Int32Value(), AL);
1800b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1801b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, out_off.Int32Value());
1802b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1803b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
18042c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadReferenceFromSirt(ManagedRegister mout_reg,
18052c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                         ManagedRegister min_reg) {
18062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister out_reg = mout_reg.AsArm();
18072c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister in_reg = min_reg.AsArm();
1808b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(out_reg.IsCoreRegister());
1809b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(in_reg.IsCoreRegister());
1810b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  Label null_arg;
1811b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (!out_reg.Equals(in_reg)) {
1812b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadImmediate(out_reg.AsCoreRegister(), 0, EQ);
1813b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1814b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  cmp(in_reg.AsCoreRegister(), ShifterOperand(0));
1815df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers  LoadFromOffset(kLoadWord, out_reg.AsCoreRegister(),
1816df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers                 in_reg.AsCoreRegister(), 0, NE);
1817b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1818b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
18192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::VerifyObject(ManagedRegister src, bool could_be_null) {
1820b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // TODO: not validating references
1821b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1822b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
18232c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::VerifyObject(FrameOffset src, bool could_be_null) {
1824b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // TODO: not validating references
1825b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1826b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
18272c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Call(ManagedRegister mbase, Offset offset,
18282c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        ManagedRegister mscratch) {
18292c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister base = mbase.AsArm();
18302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1831b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(base.IsCoreRegister());
1832b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(scratch.IsCoreRegister());
1833b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1834b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                 base.AsCoreRegister(), offset.Int32Value());
1835b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  blx(scratch.AsCoreRegister());
1836b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // TODO: place reference map on call
1837b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1838b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
18392c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Call(FrameOffset base, Offset offset,
18402c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        ManagedRegister mscratch) {
18412c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1842e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  CHECK(scratch.IsCoreRegister());
1843e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  // Call *(*(SP + base) + offset)
1844e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1845e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro                 SP, base.Int32Value());
1846e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1847e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro                 scratch.AsCoreRegister(), offset.Int32Value());
1848e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  blx(scratch.AsCoreRegister());
1849e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  // TODO: place reference map on call
1850e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro}
1851e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro
1852bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersvoid ArmAssembler::Call(ThreadOffset offset, ManagedRegister scratch) {
1853bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  UNIMPLEMENTED(FATAL);
1854bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers}
1855bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
18562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::GetCurrentThread(ManagedRegister tr) {
18572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  mov(tr.AsArm().AsCoreRegister(), ShifterOperand(TR));
1858668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao}
1859668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao
18602c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::GetCurrentThread(FrameOffset offset,
18612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                    ManagedRegister scratch) {
1862668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao  StoreToOffset(kStoreWord, TR, SP, offset.Int32Value(), AL);
1863668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao}
1864668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao
18652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::SuspendPoll(ManagedRegister mscratch,
18662c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                               ManagedRegister return_reg,
18672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                               FrameOffset return_save_location,
18682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                               size_t return_size) {
18692c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
18702c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmSuspendCountSlowPath* slow =
18712c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers      new ArmSuspendCountSlowPath(return_reg.AsArm(), return_save_location,
18722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  return_size);
1873e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  buffer_.EnqueueSlowPath(slow);
1874e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1875e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro                 TR, Thread::SuspendCountOffset().Int32Value());
1876e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  cmp(scratch.AsCoreRegister(), ShifterOperand(0));
1877e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  b(slow->Entry(), NE);
1878e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  Bind(slow->Continuation());
1879e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro}
1880e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro
18812c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmSuspendCountSlowPath::Emit(Assembler* sasm) {
18822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmAssembler* sp_asm = down_cast<ArmAssembler*>(sasm);
18832c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#define __ sp_asm->
18842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  __ Bind(&entry_);
1885e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  // Save return value
18862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  __ Store(return_save_location_, return_register_, return_size_);
1887e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  // Pass thread as argument
1888e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  __ mov(R0, ShifterOperand(TR));
1889e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  __ LoadFromOffset(kLoadWord, R12, TR, OFFSETOF_MEMBER(Thread, pCheckSuspendFromCode));
1890e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  // Note: assume that link register will be spilled/filled on method entry/exit
18912c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  __ blx(R12);
1892e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  // Reload return value
18932c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  __ Load(return_register_, return_save_location_, return_size_);
18942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  __ b(&continuation_);
18952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#undef __
189645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers}
189745a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
18982c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ExceptionPoll(ManagedRegister mscratch) {
18992c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
190067375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  ArmExceptionSlowPath* slow = new ArmExceptionSlowPath(scratch);
1901e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  buffer_.EnqueueSlowPath(slow);
1902e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1903e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro                 TR, Thread::ExceptionOffset().Int32Value());
1904e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  cmp(scratch.AsCoreRegister(), ShifterOperand(0));
1905e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  b(slow->Entry(), NE);
1906e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro}
1907e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro
19082c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmExceptionSlowPath::Emit(Assembler* sasm) {
19092c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmAssembler* sp_asm = down_cast<ArmAssembler*>(sasm);
19102c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#define __ sp_asm->
19112c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  __ Bind(&entry_);
191267375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers
191367375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  // Pass exception object as argument
191467375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  // Don't care about preserving R0 as this call won't return
191567375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  __ mov(R0, ShifterOperand(scratch_.AsCoreRegister()));
191667375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  // Set up call to Thread::Current()->pDeliverException
191767375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  __ LoadFromOffset(kLoadWord, R12, TR, OFFSETOF_MEMBER(Thread, pDeliverException));
19182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  __ blx(R12);
191967375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  // Call never returns
192067375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  __ bkpt(0);
19212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#undef __
192245a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers}
192345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
19242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers}  // namespace arm
19256b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro}  // namespace art
1926