assembler_arm.cc revision 00f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abac
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"
2057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers#include "oat/runtime/oat_support_entrypoints.h"
21578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "offsets.h"
22e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro#include "thread.h"
23578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "utils.h"
24a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
256b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapironamespace art {
262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace arm {
27a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro
28a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// Instruction encoding bits.
29a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroenum {
30a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  H   = 1 << 5,   // halfword (or byte)
31a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  L   = 1 << 20,  // load (or store)
32a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  S   = 1 << 20,  // set condition code (or leave unchanged)
33a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  W   = 1 << 21,  // writeback base register (or leave unchanged)
34a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  A   = 1 << 21,  // accumulate in multiply instruction (or not)
35a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B   = 1 << 22,  // unsigned byte (or word)
36a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  N   = 1 << 22,  // long (or short)
37a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  U   = 1 << 23,  // positive (or negative) offset/index
38a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  P   = 1 << 24,  // offset/pre-indexed addressing (or post-indexed addressing)
39a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  I   = 1 << 25,  // immediate shifter operand (or not)
40a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
41a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B0 = 1,
42a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B1 = 1 << 1,
43a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B2 = 1 << 2,
44a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B3 = 1 << 3,
45a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B4 = 1 << 4,
46a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B5 = 1 << 5,
47a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B6 = 1 << 6,
48a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B7 = 1 << 7,
49a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B8 = 1 << 8,
50a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B9 = 1 << 9,
51a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B10 = 1 << 10,
52a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B11 = 1 << 11,
53a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B12 = 1 << 12,
54a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B16 = 1 << 16,
55a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B17 = 1 << 17,
56a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B18 = 1 << 18,
57a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B19 = 1 << 19,
58a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B20 = 1 << 20,
59a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B21 = 1 << 21,
60a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B22 = 1 << 22,
61a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B23 = 1 << 23,
62a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B24 = 1 << 24,
63a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B25 = 1 << 25,
64a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B26 = 1 << 26,
65a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  B27 = 1 << 27,
66a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
67a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Instruction bit masks.
68a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  RdMask = 15 << 12,  // in str instruction
69a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CondMask = 15 << 28,
70a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CoprocessorMask = 15 << 8,
71a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  OpCodeMask = 15 << 21,  // in data-processing instructions
72a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Imm24Mask = (1 << 24) - 1,
73a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Off12Mask = (1 << 12) - 1,
74a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
75a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // ldrex/strex register field encodings.
76a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kLdExRnShift = 16,
77a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kLdExRtShift = 12,
78a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kStrExRnShift = 16,
79a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kStrExRdShift = 12,
80a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  kStrExRtShift = 0,
81a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro};
82a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
83a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
841f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstatic const char* kRegisterNames[] = {
851f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
861f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  "fp", "ip", "sp", "lr", "pc"
871f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes};
881f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Register& rhs) {
891f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  if (rhs >= R0 && rhs <= PC) {
901f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes    os << kRegisterNames[rhs];
911f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  } else {
92b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "Register[" << static_cast<int>(rhs) << "]";
931f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  }
941f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  return os;
951f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}
961f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
971f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
981f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const SRegister& rhs) {
991f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  if (rhs >= S0 && rhs < kNumberOfSRegisters) {
100b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "s" << static_cast<int>(rhs);
1011f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  } else {
102b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "SRegister[" << static_cast<int>(rhs) << "]";
1031f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  }
1041f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  return os;
1051f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}
1061f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
1071f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
1081f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const DRegister& rhs) {
1091f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  if (rhs >= D0 && rhs < kNumberOfDRegisters) {
110b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "d" << static_cast<int>(rhs);
1111f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  } else {
112b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "DRegister[" << static_cast<int>(rhs) << "]";
1131f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  }
1141f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  return os;
1151f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}
1161f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
1171f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
1181f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstatic const char* kConditionNames[] = {
119b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT",
120b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  "LE", "AL",
1211f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes};
1221f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Condition& rhs) {
1231f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  if (rhs >= EQ && rhs <= AL) {
1241f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes    os << kConditionNames[rhs];
1251f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  } else {
126b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    os << "Condition[" << static_cast<int>(rhs) << "]";
1271f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  }
1281f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  return os;
1291f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}
1301f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes
1312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Emit(int32_t value) {
132a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
133a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  buffer_.Emit<int32_t>(value);
134a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
135a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
136a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1372c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitType01(Condition cond,
1382c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              int type,
1392c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              Opcode opcode,
1402c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              int set_cc,
1412c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              Register rn,
1422c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              Register rd,
1432c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              ShifterOperand so) {
144a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
145a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
146a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
147a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     type << kTypeShift |
148a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(opcode) << kOpcodeShift |
149a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     set_cc << kSShift |
150a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rn) << kRnShift |
151a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rd) << kRdShift |
152a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     so.encoding();
153a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
154a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
155a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
156a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitType5(Condition cond, int offset, bool link) {
158a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
159a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
160a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     5 << kTypeShift |
161a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (link ? 1 : 0) << kLinkShift;
1622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  Emit(ArmAssembler::EncodeBranchOffset(offset, encoding));
163a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
164a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
165a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1662c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitMemOp(Condition cond,
1672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             bool load,
1682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             bool byte,
1692c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             Register rd,
1702c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             Address ad) {
171a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
172a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
173a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
174a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B26 |
175a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (load ? L : 0) |
176a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (byte ? B : 0) |
177a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rd) << kRdShift) |
178a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ad.encoding();
179a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
180a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
181a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
182a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1832c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitMemOpAddressMode3(Condition cond,
1842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                         int32_t mode,
1852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                         Register rd,
1862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                         Address ad) {
187a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
188a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
189a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
190a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B22  |
191a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     mode |
192a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rd) << kRdShift) |
193a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ad.encoding3();
194a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
195a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
196a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
197a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1982c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitMultiMemOp(Condition cond,
1992c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  BlockAddressMode am,
2002c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  bool load,
2012c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  Register base,
2022c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  RegList regs) {
203a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(base, kNoRegister);
204a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
205a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
206a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 |
207a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     am |
208a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (load ? L : 0) |
209a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(base) << kRnShift) |
210a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     regs;
211a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
212a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
213a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
214a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitShiftImmediate(Condition cond,
2162c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                      Shift opcode,
2172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                      Register rd,
2182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                      Register rm,
2192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                      ShifterOperand so) {
220a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
2211f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  CHECK_EQ(so.type(), 1U);
222a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
223a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(MOV) << kOpcodeShift |
224a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rd) << kRdShift |
225a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     so.encoding() << kShiftImmShift |
226a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(opcode) << kShiftShift |
227a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rm);
228a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
229a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
230a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
231a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2322c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitShiftRegister(Condition cond,
2332c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                     Shift opcode,
2342c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                     Register rd,
2352c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                     Register rm,
2362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                     ShifterOperand so) {
237a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
2381f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes  CHECK_EQ(so.type(), 0U);
239a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
240a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(MOV) << kOpcodeShift |
241a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rd) << kRdShift |
242a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     so.encoding() << kShiftRegisterShift |
243a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(opcode) << kShiftShift |
244a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B4 |
245a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rm);
246a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
247a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
248a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
249a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitBranch(Condition cond, Label* label, bool link) {
251a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  if (label->IsBound()) {
252a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    EmitType5(cond, label->Position() - buffer_.Size(), link);
253a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  } else {
254a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    int position = buffer_.Size();
255a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    // Use the offset field of the branch instruction for linking the sites.
256a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    EmitType5(cond, label->position_, link);
257a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    label->LinkTo(position);
258a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
259a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
260a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::and_(Register rd, Register rn, ShifterOperand so,
2622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        Condition cond) {
263a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), AND, 0, rn, rd, so);
264a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
265a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
266a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::eor(Register rd, Register rn, ShifterOperand so,
2682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
269a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), EOR, 0, rn, rd, so);
270a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
271a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
272a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::sub(Register rd, Register rn, ShifterOperand so,
2742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
275a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), SUB, 0, rn, rd, so);
276a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
277a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2782c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::rsb(Register rd, Register rn, ShifterOperand so,
2792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
280a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), RSB, 0, rn, rd, so);
281a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
282a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2832c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::rsbs(Register rd, Register rn, ShifterOperand so,
2842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        Condition cond) {
285a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), RSB, 1, rn, rd, so);
286a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
287a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
288a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::add(Register rd, Register rn, ShifterOperand so,
2902c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
291a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ADD, 0, rn, rd, so);
292a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
293a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
294a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
2952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::adds(Register rd, Register rn, ShifterOperand so,
2962c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        Condition cond) {
297a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ADD, 1, rn, rd, so);
298a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
299a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
300a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3012c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::subs(Register rd, Register rn, ShifterOperand so,
3022c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        Condition cond) {
303a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), SUB, 1, rn, rd, so);
304a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
305a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
306a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3072c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::adc(Register rd, Register rn, ShifterOperand so,
3082c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
309a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ADC, 0, rn, rd, so);
310a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
311a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
312a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3132c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::sbc(Register rd, Register rn, ShifterOperand so,
3142c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
315a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), SBC, 0, rn, rd, so);
316a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
317a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
318a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::rsc(Register rd, Register rn, ShifterOperand so,
3202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
321a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), RSC, 0, rn, rd, so);
322a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
323a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
324a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::tst(Register rn, ShifterOperand so, Condition cond) {
326a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, PC);  // Reserve tst pc instruction for exception handler marker.
327a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), TST, 1, rn, R0, so);
328a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
329a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
330a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::teq(Register rn, ShifterOperand so, Condition cond) {
332a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, PC);  // Reserve teq pc instruction for exception handler marker.
333a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), TEQ, 1, rn, R0, so);
334a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
335a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
336a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3372c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::cmp(Register rn, ShifterOperand so, Condition cond) {
338a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), CMP, 1, rn, R0, so);
339a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
340a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
341a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3422c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::cmn(Register rn, ShifterOperand so, Condition cond) {
343a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), CMN, 1, rn, R0, so);
344a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
345a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
346a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3472c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::orr(Register rd, Register rn,
348a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                    ShifterOperand so, Condition cond) {
349a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ORR, 0, rn, rd, so);
350a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
351a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
352a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3532c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::orrs(Register rd, Register rn,
3542c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        ShifterOperand so, Condition cond) {
355a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), ORR, 1, rn, rd, so);
356a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
357a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
358a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3592c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mov(Register rd, ShifterOperand so, Condition cond) {
360a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), MOV, 0, R0, rd, so);
361a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
362a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
363a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::movs(Register rd, ShifterOperand so, Condition cond) {
365a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), MOV, 1, R0, rd, so);
366a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
367a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
368a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3692c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::bic(Register rd, Register rn, ShifterOperand so,
3702c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
371a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), BIC, 0, rn, rd, so);
372a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
373a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
374a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3752c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mvn(Register rd, ShifterOperand so, Condition cond) {
376a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), MVN, 0, R0, rd, so);
377a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
378a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
379a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mvns(Register rd, ShifterOperand so, Condition cond) {
381a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(cond, so.type(), MVN, 1, R0, rd, so);
382a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
383a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
384a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::clz(Register rd, Register rm, Condition cond) {
386a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
387a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rm, kNoRegister);
388a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
389a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, PC);
390a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rm, PC);
391a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
392a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B24 | B22 | B21 | (0xf << 16) |
393a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rd) << kRdShift) |
394a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (0xf << 8) | B4 | static_cast<int32_t>(rm);
395a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
396a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
397a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
398a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
3992c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::movw(Register rd, uint16_t imm16, Condition cond) {
400a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
401a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
402a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B25 | B24 | ((imm16 >> 12) << 16) |
403a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
404a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
405a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
406a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
407a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4082c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::movt(Register rd, uint16_t imm16, Condition cond) {
409a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
410a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
411a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B25 | B24 | B22 | ((imm16 >> 12) << 16) |
412a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
413a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
414a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
415a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
416a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitMulOp(Condition cond, int32_t opcode,
4182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             Register rd, Register rn,
4192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             Register rm, Register rs) {
420a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
421a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, kNoRegister);
422a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rm, kNoRegister);
423a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rs, kNoRegister);
424a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
425a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = opcode |
426a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(cond) << kConditionShift) |
427a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(rn) << kRnShift) |
428a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(rd) << kRdShift) |
429a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(rs) << kRsShift) |
430a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      B7 | B4 |
431a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      (static_cast<int32_t>(rm) << kRmShift);
432a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
433a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
434a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
435a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mul(Register rd, Register rn, Register rm, Condition cond) {
437a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
438a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMulOp(cond, 0, R0, rd, rn, rm);
439a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
440a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
441a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4422c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mla(Register rd, Register rn, Register rm, Register ra,
4432c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
444a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
445a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMulOp(cond, B21, ra, rd, rn, rm);
446a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
447a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
448a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mls(Register rd, Register rn, Register rm, Register ra,
4502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
451a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
452a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMulOp(cond, B22 | B21, ra, rd, rn, rm);
453a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
454a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
455a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::umull(Register rd_lo, Register rd_hi, Register rn,
4572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Register rm, Condition cond) {
458a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
459a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm);
460a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
461a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
462a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldr(Register rd, Address ad, Condition cond) {
464a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOp(cond, true, false, rd, ad);
465a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
466a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
467a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::str(Register rd, Address ad, Condition cond) {
469a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOp(cond, false, false, rd, ad);
470a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
471a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
472a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrb(Register rd, Address ad, Condition cond) {
474a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOp(cond, true, true, rd, ad);
475a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
476a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
477a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4782c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::strb(Register rd, Address ad, Condition cond) {
479a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOp(cond, false, true, rd, ad);
480a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
481a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
482a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4832c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrh(Register rd, Address ad, Condition cond) {
484a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad);
485a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
486a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
487a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4882c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::strh(Register rd, Address ad, Condition cond) {
489a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad);
490a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
491a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
492a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4932c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrsb(Register rd, Address ad, Condition cond) {
494a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad);
495a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
496a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
497a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
4982c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrsh(Register rd, Address ad, Condition cond) {
499a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad);
500a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
501a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
502a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5032c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrd(Register rd, Address ad, Condition cond) {
504a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_EQ(rd % 2, 0);
505a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad);
506a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
507a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
508a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5092c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::strd(Register rd, Address ad, Condition cond) {
510a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_EQ(rd % 2, 0);
511a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad);
512a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
513a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
514a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldm(BlockAddressMode am,
5162c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Register base,
5172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       RegList regs,
5182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
519a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMultiMemOp(cond, am, true, base, regs);
520a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
521a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
522a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5232c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::stm(BlockAddressMode am,
5242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Register base,
5252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       RegList regs,
5262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
527a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitMultiMemOp(cond, am, false, base, regs);
528a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
529a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
530a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrex(Register rt, Register rn, Condition cond) {
532a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, kNoRegister);
533a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
534a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
535a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
536a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B24 |
537a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B23 |
538a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     L   |
539a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rn) << kLdExRnShift) |
540a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt) << kLdExRtShift) |
541a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0;
542a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
543a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
544a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
545a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5462c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::strex(Register rd,
5472c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Register rt,
5482c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Register rn,
5492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
550a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rn, kNoRegister);
551a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rd, kNoRegister);
552a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
553a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
554a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
555a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B24 |
556a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B23 |
557a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rn) << kStrExRnShift) |
558a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rd) << kStrExRdShift) |
559a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B10 | B9 | B8 | B7 | B4 |
560a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt) << kStrExRtShift);
561a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
562a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
563a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
564a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::clrex() {
566a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (kSpecialCondition << kConditionShift) |
567a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf;
568a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
569a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
570a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
571a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::nop(Condition cond) {
573a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
574a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
575a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B25 | B24 | B21 | (0xf << 12);
576a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
577a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
578a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
579a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovsr(SRegister sn, Register rt, Condition cond) {
581a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sn, kNoSRegister);
582a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
583a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
584a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
585a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
586a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
587a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 |
588a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) >> 1)*B16) |
589a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
590a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
591a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
592a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
593a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
594a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
5952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovrs(Register rt, SRegister sn, Condition cond) {
596a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sn, kNoSRegister);
597a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
598a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
599a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
600a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
601a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
602a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B20 |
603a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) >> 1)*B16) |
604a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
605a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
606a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
607a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
608a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
609a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
6102c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovsrr(SRegister sm, Register rt, Register rt2,
6112c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                           Condition cond) {
612a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, kNoSRegister);
613a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, S31);
614a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
615a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
616a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
617a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, kNoRegister);
618a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, SP);
619a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, PC);
620a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
621a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
622a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B22 |
623a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt2)*B16) |
624a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
625a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
626a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(sm) >> 1);
627a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
628a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
629a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
630a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
6312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovrrs(Register rt, Register rt2, SRegister sm,
6322c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                           Condition cond) {
633a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, kNoSRegister);
634a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, S31);
635a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
636a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
637a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
638a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, kNoRegister);
639a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, SP);
640a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, PC);
641a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, rt2);
642a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
643a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
644a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B22 | B20 |
645a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt2)*B16) |
646a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
647a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
648a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(sm) >> 1);
649a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
650a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
651a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
652a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
6532c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovdrr(DRegister dm, Register rt, Register rt2,
6542c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                           Condition cond) {
655a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dm, kNoDRegister);
656a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
657a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
658a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
659a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, kNoRegister);
660a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, SP);
661a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, PC);
662a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
663a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
664a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B22 |
665a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt2)*B16) |
666a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
667a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
668a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(dm) & 0xf);
669a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
670a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
671a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
672a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
6732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovrrd(Register rt, Register rt2, DRegister dm,
6742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                           Condition cond) {
675a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dm, kNoDRegister);
676a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, kNoRegister);
677a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, SP);
678a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, PC);
679a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, kNoRegister);
680a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, SP);
681a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt2, PC);
682a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rt, rt2);
683a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
684a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
685a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B22 | B20 |
686a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt2)*B16) |
687a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
688a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
689a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(dm) & 0xf);
690a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
691a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
692a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
693a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
6942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vldrs(SRegister sd, Address ad, Condition cond) {
695a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sd, kNoSRegister);
696a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
697a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
698a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B24 | B20 |
699a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) & 1)*B22) |
700a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) >> 1)*B12) |
701a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | ad.vencoding();
702a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
703a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
704a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
705a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vstrs(SRegister sd, Address ad, Condition cond) {
707a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC);
708a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sd, kNoSRegister);
709a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
710a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
711a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B24 |
712a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) & 1)*B22) |
713a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) >> 1)*B12) |
714a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | ad.vencoding();
715a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
716a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
717a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
718a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vldrd(DRegister dd, Address ad, Condition cond) {
720a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dd, kNoDRegister);
721a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
722a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
723a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B24 | B20 |
724a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) >> 4)*B22) |
725a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
726a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | B8 | ad.vencoding();
727a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
728a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
729a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
730a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vstrd(DRegister dd, Address ad, Condition cond) {
732a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC);
733a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dd, kNoDRegister);
734a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
735a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
736a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B24 |
737a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) >> 4)*B22) |
738a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
739a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | B8 | ad.vencoding();
740a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
741a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
742a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
743a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7442c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitVFPsss(Condition cond, int32_t opcode,
7452c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              SRegister sd, SRegister sn, SRegister sm) {
746a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sd, kNoSRegister);
747a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sn, kNoSRegister);
748a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, kNoSRegister);
749a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
750a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
751a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B11 | B9 | opcode |
752a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) & 1)*B22) |
753a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) >> 1)*B16) |
754a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) >> 1)*B12) |
755a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sn) & 1)*B7) |
756a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sm) & 1)*B5) |
757a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(sm) >> 1);
758a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
759a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
760a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
761a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitVFPddd(Condition cond, int32_t opcode,
7632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              DRegister dd, DRegister dn, DRegister dm) {
764a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dd, kNoDRegister);
765a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dn, kNoDRegister);
766a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dm, kNoDRegister);
767a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
768a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
769a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B11 | B9 | B8 | opcode |
770a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) >> 4)*B22) |
771a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dn) & 0xf)*B16) |
772a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
773a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dn) >> 4)*B7) |
774a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dm) >> 4)*B5) |
775a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(dm) & 0xf);
776a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
777a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
778a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
779a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovs(SRegister sd, SRegister sm, Condition cond) {
781a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm);
782a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
783a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
784a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovd(DRegister dd, DRegister dm, Condition cond) {
786a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm);
787a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
788a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
789a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
7902c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool ArmAssembler::vmovs(SRegister sd, float s_imm, Condition cond) {
791a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  uint32_t imm32 = bit_cast<uint32_t, float>(s_imm);
792a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  if (((imm32 & ((1 << 19) - 1)) == 0) &&
793a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) ||
794a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro       (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) {
795a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) |
796a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro        ((imm32 >> 19) & ((1 << 6) -1));
797a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf),
798a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro               sd, S0, S0);
799a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return true;
800a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
801a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  return false;
802a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
803a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
804a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8052c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool ArmAssembler::vmovd(DRegister dd, double d_imm, Condition cond) {
806a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  uint64_t imm64 = bit_cast<uint64_t, double>(d_imm);
807a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  if (((imm64 & ((1LL << 48) - 1)) == 0) &&
808a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro      ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) ||
809a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro       (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) {
810a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) |
811a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro        ((imm64 >> 48) & ((1 << 6) -1));
812a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf),
813a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro               dd, D0, D0);
814a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    return true;
815a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
816a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  return false;
817a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
818a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
819a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vadds(SRegister sd, SRegister sn, SRegister sm,
8212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
822a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B21 | B20, sd, sn, sm);
823a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
824a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
825a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vaddd(DRegister dd, DRegister dn, DRegister dm,
8272c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
828a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B21 | B20, dd, dn, dm);
829a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
830a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
831a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8322c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vsubs(SRegister sd, SRegister sn, SRegister sm,
8332c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
834a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm);
835a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
836a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
837a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8382c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vsubd(DRegister dd, DRegister dn, DRegister dm,
8392c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
840a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm);
841a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
842a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
843a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8442c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmuls(SRegister sd, SRegister sn, SRegister sm,
8452c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
846a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B21, sd, sn, sm);
847a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
848a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
849a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmuld(DRegister dd, DRegister dn, DRegister dm,
8512c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
852a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B21, dd, dn, dm);
853a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
854a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
855a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmlas(SRegister sd, SRegister sn, SRegister sm,
8572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
858a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, 0, sd, sn, sm);
859a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
860a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
861a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmlad(DRegister dd, DRegister dn, DRegister dm,
8632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
864a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, 0, dd, dn, dm);
865a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
866a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
867a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmlss(SRegister sd, SRegister sn, SRegister sm,
8692c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
870a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B6, sd, sn, sm);
871a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
872a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
873a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmlsd(DRegister dd, DRegister dn, DRegister dm,
8752c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
876a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B6, dd, dn, dm);
877a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
878a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
879a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vdivs(SRegister sd, SRegister sn, SRegister sm,
8812c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
882a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23, sd, sn, sm);
883a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
884a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
885a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vdivd(DRegister dd, DRegister dn, DRegister dm,
8872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                         Condition cond) {
888a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23, dd, dn, dm);
889a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
890a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
891a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8922c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vabss(SRegister sd, SRegister sm, Condition cond) {
893a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm);
894a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
895a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
896a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
8972c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vabsd(DRegister dd, DRegister dm, Condition cond) {
898a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm);
899a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
900a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
901a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9022c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vnegs(SRegister sd, SRegister sm, Condition cond) {
903a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm);
904a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
905a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
906a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9072c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vnegd(DRegister dd, DRegister dm, Condition cond) {
908a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm);
909a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
910a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
911a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9122c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vsqrts(SRegister sd, SRegister sm, Condition cond) {
913a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm);
914a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
915a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9162c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) {
917a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm);
918a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
919a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
920a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitVFPsd(Condition cond, int32_t opcode,
9222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             SRegister sd, DRegister dm) {
923a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sd, kNoSRegister);
924a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dm, kNoDRegister);
925a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
926a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
927a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B11 | B9 | opcode |
928a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) & 1)*B22) |
929a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sd) >> 1)*B12) |
930a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dm) >> 4)*B5) |
931a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(dm) & 0xf);
932a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
933a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
934a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
935a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitVFPds(Condition cond, int32_t opcode,
9372c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                             DRegister dd, SRegister sm) {
938a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(dd, kNoDRegister);
939a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(sm, kNoSRegister);
940a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
941a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
942a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B11 | B9 | opcode |
943a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) >> 4)*B22) |
944a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
945a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((static_cast<int32_t>(sm) & 1)*B5) |
946a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(sm) >> 1);
947a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
948a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
949a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
950a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9512c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) {
952a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm);
953a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
954a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
955a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtds(DRegister dd, SRegister sm, Condition cond) {
957a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm);
958a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
959a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
960a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtis(SRegister sd, SRegister sm, Condition cond) {
962a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm);
963a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
964a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
965a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9662c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtid(SRegister sd, DRegister dm, Condition cond) {
967a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm);
968a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
969a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
970a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9712c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) {
972a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm);
973a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
974a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
975a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9762c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) {
977a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm);
978a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
979a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
980a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9812c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtus(SRegister sd, SRegister sm, Condition cond) {
982a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm);
983a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
984a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
985a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtud(SRegister sd, DRegister dm, Condition cond) {
987a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm);
988a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
989a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
990a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9912c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) {
992a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm);
993a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
994a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
995a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
9962c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) {
997a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm);
998a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
999a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1000a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10012c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcmps(SRegister sd, SRegister sm, Condition cond) {
1002a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm);
1003a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1004a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1005a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcmpd(DRegister dd, DRegister dm, Condition cond) {
1007a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm);
1008a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1009a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1010a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10112c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcmpsz(SRegister sd, Condition cond) {
1012a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0);
1013a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1014a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1015a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10162c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcmpdz(DRegister dd, Condition cond) {
1017a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
1018a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1019a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1020a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmstat(Condition cond) {  // VMRS APSR_nzcv, FPSCR
1022a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
1023a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1024a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 |
1025a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(PC)*B12) |
1026a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B11 | B9 | B4;
1027a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
1028a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1029a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1030a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::svc(uint32_t imm24) {
1032bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(IsUint(24, imm24)) << imm24;
1033a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24;
1034a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
1035a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1036a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1037a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10382c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::bkpt(uint16_t imm16) {
1039a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (AL << kConditionShift) | B24 | B21 |
1040a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
1041a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
1042a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1043a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1044a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10452c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::b(Label* label, Condition cond) {
1046a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitBranch(cond, label, false);
1047a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1048a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1049a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::bl(Label* label, Condition cond) {
1051a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitBranch(cond, label, true);
1052a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1053a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1054a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::blx(Register rm, Condition cond) {
1056a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(rm, kNoRegister);
1057a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK_NE(cond, kNoCondition);
1058a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1059a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     B24 | B21 | (0xfff << 8) | B5 | B4 |
1060a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro                     (static_cast<int32_t>(rm) << kRmShift);
1061a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Emit(encoding);
1062a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1063a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1064ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogersvoid ArmAssembler::bx(Register rm, Condition cond) {
1065ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers  CHECK_NE(rm, kNoRegister);
1066ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers  CHECK_NE(cond, kNoCondition);
1067ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1068ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers                     B24 | B21 | (0xfff << 8) | B4 |
1069ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers                     (static_cast<int32_t>(rm) << kRmShift);
1070ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers  Emit(encoding);
1071ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers}
1072a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::MarkExceptionHandler(Label* label) {
1074a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0));
1075a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Label l;
1076a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  b(&l);
1077a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  EmitBranch(AL, label, false);
1078a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  Bind(&l);
1079a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1080a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1081a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Bind(Label* label) {
1083a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  CHECK(!label->IsBound());
1084a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  int bound_pc = buffer_.Size();
1085a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  while (label->IsLinked()) {
1086a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    int32_t position = label->Position();
1087a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    int32_t next = buffer_.Load<int32_t>(position);
10882c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    int32_t encoded = ArmAssembler::EncodeBranchOffset(bound_pc - position, next);
1089a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    buffer_.Store<int32_t>(position, encoded);
10902c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers    label->position_ = ArmAssembler::DecodeBranchOffset(next);
1091a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
1092a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  label->BindTo(bound_pc);
1093a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1094a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1095a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
10962c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EncodeUint32InTstInstructions(uint32_t data) {
1097a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // TODO: Consider using movw ip, <16 bits>.
1098a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  while (!IsUint(8, data)) {
1099a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    tst(R0, ShifterOperand(data & 0xFF), VS);
1100a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro    data >>= 8;
1101a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  }
1102a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  tst(R0, ShifterOperand(data), MI);
1103a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1104a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1105b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
11062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersint32_t ArmAssembler::EncodeBranchOffset(int offset, int32_t inst) {
1107a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // The offset is off by 8 due to the way the ARM CPUs read PC.
1108a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  offset -= 8;
110906b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes  CHECK_ALIGNED(offset, 4);
1110bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(IsInt(CountOneBits(kBranchOffsetMask), offset)) << offset;
1111a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1112a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Properly preserve only the bits supported in the instruction.
1113a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  offset >>= 2;
1114a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  offset &= kBranchOffsetMask;
1115a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  return (inst & ~kBranchOffsetMask) | offset;
1116a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1117a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
1118a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
11192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersint ArmAssembler::DecodeBranchOffset(int32_t inst) {
1120a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  // Sign-extend, left-shift by 2, then add 8.
1121a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro  return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8);
1122a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}
1123a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro
11242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::AddConstant(Register rd, int32_t value, Condition cond) {
1125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  AddConstant(rd, rd, value, cond);
1126b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1127b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1128b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
11292c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::AddConstant(Register rd, Register rn, int32_t value,
11302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                               Condition cond) {
1131b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (value == 0) {
1132b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (rd != rn) {
1133b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mov(rd, ShifterOperand(rn), cond);
1134b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1135b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    return;
1136b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1137b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // We prefer to select the shorter code sequence rather than selecting add for
1138b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // positive values and sub for negatives ones, which would slightly improve
1139b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // the readability of generated code for some constants.
1140b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  ShifterOperand shifter_op;
1141b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (ShifterOperand::CanHold(value, &shifter_op)) {
1142b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    add(rd, rn, shifter_op, cond);
1143b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else if (ShifterOperand::CanHold(-value, &shifter_op)) {
1144b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    sub(rd, rn, shifter_op, cond);
1145b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1146b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(rn != IP);
1147b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (ShifterOperand::CanHold(~value, &shifter_op)) {
1148b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mvn(IP, shifter_op, cond);
1149b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      add(rd, rn, ShifterOperand(IP), cond);
1150b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) {
1151b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mvn(IP, shifter_op, cond);
1152b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      sub(rd, rn, ShifterOperand(IP), cond);
1153b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    } else {
1154b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      movw(IP, Low16Bits(value), cond);
1155b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      uint16_t value_high = High16Bits(value);
1156b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      if (value_high != 0) {
1157b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers        movt(IP, value_high, cond);
1158b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      }
1159b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      add(rd, rn, ShifterOperand(IP), cond);
1160b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1161b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1162b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1163b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1164b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
11652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::AddConstantSetFlags(Register rd, Register rn, int32_t value,
11662c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                       Condition cond) {
1167b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  ShifterOperand shifter_op;
1168b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (ShifterOperand::CanHold(value, &shifter_op)) {
1169b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    adds(rd, rn, shifter_op, cond);
1170b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else if (ShifterOperand::CanHold(-value, &shifter_op)) {
1171b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    subs(rd, rn, shifter_op, cond);
1172b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1173b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(rn != IP);
1174b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (ShifterOperand::CanHold(~value, &shifter_op)) {
1175b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mvn(IP, shifter_op, cond);
1176b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      adds(rd, rn, ShifterOperand(IP), cond);
1177b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) {
1178b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      mvn(IP, shifter_op, cond);
1179b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      subs(rd, rn, ShifterOperand(IP), cond);
1180b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    } else {
1181b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      movw(IP, Low16Bits(value), cond);
1182b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      uint16_t value_high = High16Bits(value);
1183b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      if (value_high != 0) {
1184b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers        movt(IP, value_high, cond);
1185b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      }
1186b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      adds(rd, rn, ShifterOperand(IP), cond);
1187b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1188b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1189b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1190b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1191b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
11922c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
1193b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  ShifterOperand shifter_op;
1194b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (ShifterOperand::CanHold(value, &shifter_op)) {
1195b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    mov(rd, shifter_op, cond);
1196b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else if (ShifterOperand::CanHold(~value, &shifter_op)) {
1197b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    mvn(rd, shifter_op, cond);
1198b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1199b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    movw(rd, Low16Bits(value), cond);
1200b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    uint16_t value_high = High16Bits(value);
1201b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (value_high != 0) {
1202b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      movt(rd, value_high, cond);
1203b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1204b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1205b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1206b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1207b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1208b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersbool Address::CanHoldLoadOffset(LoadOperandType type, int offset) {
1209b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  switch (type) {
1210b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSignedByte:
1211b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSignedHalfword:
1212b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadUnsignedHalfword:
1213b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadWordPair:
1214b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(8, offset);  // Addressing mode 3.
1215b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadUnsignedByte:
1216b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadWord:
1217b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(12, offset);  // Addressing mode 2.
1218b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSWord:
1219b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadDWord:
1220b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(10, offset);  // VFP addressing mode.
1221b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    default:
1222b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LOG(FATAL) << "UNREACHABLE";
1223b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return false;
1224b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1225b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1226b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1227b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1228b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersbool Address::CanHoldStoreOffset(StoreOperandType type, int offset) {
1229b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  switch (type) {
1230b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreHalfword:
1231b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreWordPair:
1232b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(8, offset);  // Addressing mode 3.
1233b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreByte:
1234b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreWord:
1235b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(12, offset);  // Addressing mode 2.
1236b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreSWord:
1237b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreDWord:
1238b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return IsAbsoluteUint(10, offset);  // VFP addressing mode.
1239b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    default:
1240b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LOG(FATAL) << "UNREACHABLE";
1241b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      return false;
1242b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1243b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1244b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1245b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1246b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Implementation note: this method must emit at most one instruction when
1247b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Address::CanHoldLoadOffset.
12482c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadFromOffset(LoadOperandType type,
1249b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                               Register reg,
1250b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                               Register base,
1251b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                               int32_t offset,
1252b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                               Condition cond) {
1253b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (!Address::CanHoldLoadOffset(type, offset)) {
1254b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(base != IP);
1255b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadImmediate(IP, offset, cond);
1256b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    add(IP, IP, ShifterOperand(base), cond);
1257b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    base = IP;
1258b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    offset = 0;
1259b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1260b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(Address::CanHoldLoadOffset(type, offset));
1261b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  switch (type) {
1262b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSignedByte:
1263b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrsb(reg, Address(base, offset), cond);
1264b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1265b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadUnsignedByte:
1266b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrb(reg, Address(base, offset), cond);
1267b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1268b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadSignedHalfword:
1269b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrsh(reg, Address(base, offset), cond);
1270b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1271b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadUnsignedHalfword:
1272b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrh(reg, Address(base, offset), cond);
1273b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1274b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadWord:
1275b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldr(reg, Address(base, offset), cond);
1276b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1277b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kLoadWordPair:
1278b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      ldrd(reg, Address(base, offset), cond);
1279b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1280b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    default:
1281b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LOG(FATAL) << "UNREACHABLE";
1282b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1283b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1284b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1285e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when
1286e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldLoadOffset, as expected by JIT::GuardedLoadFromOffset.
12872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadSFromOffset(SRegister reg,
12882c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   Register base,
12892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   int32_t offset,
12902c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   Condition cond) {
1291e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  if (!Address::CanHoldLoadOffset(kLoadSWord, offset)) {
1292e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK_NE(base, IP);
1293e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    LoadImmediate(IP, offset, cond);
1294e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    add(IP, IP, ShifterOperand(base), cond);
1295e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    base = IP;
1296e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    offset = 0;
1297e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  }
1298e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  CHECK(Address::CanHoldLoadOffset(kLoadSWord, offset));
1299e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  vldrs(reg, Address(base, offset), cond);
1300e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro}
1301e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro
1302e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when
1303e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldLoadOffset, as expected by JIT::GuardedLoadFromOffset.
13042c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadDFromOffset(DRegister reg,
13052c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   Register base,
13062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   int32_t offset,
13072c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   Condition cond) {
1308e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  if (!Address::CanHoldLoadOffset(kLoadDWord, offset)) {
1309e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK_NE(base, IP);
1310e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    LoadImmediate(IP, offset, cond);
1311e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    add(IP, IP, ShifterOperand(base), cond);
1312e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    base = IP;
1313e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    offset = 0;
1314e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  }
1315e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  CHECK(Address::CanHoldLoadOffset(kLoadDWord, offset));
1316e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  vldrd(reg, Address(base, offset), cond);
1317e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro}
1318b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1319b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Implementation note: this method must emit at most one instruction when
1320b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Address::CanHoldStoreOffset.
13212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreToOffset(StoreOperandType type,
13222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                 Register reg,
13232c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                 Register base,
13242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                 int32_t offset,
13252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                 Condition cond) {
1326b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (!Address::CanHoldStoreOffset(type, offset)) {
1327b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(reg != IP);
1328b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK(base != IP);
1329b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadImmediate(IP, offset, cond);
1330b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    add(IP, IP, ShifterOperand(base), cond);
1331b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    base = IP;
1332b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    offset = 0;
1333b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1334b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  CHECK(Address::CanHoldStoreOffset(type, offset));
1335b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  switch (type) {
1336b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreByte:
1337b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      strb(reg, Address(base, offset), cond);
1338b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1339b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreHalfword:
1340b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      strh(reg, Address(base, offset), cond);
1341b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1342b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreWord:
1343b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      str(reg, Address(base, offset), cond);
1344b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1345b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    case kStoreWordPair:
1346b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      strd(reg, Address(base, offset), cond);
1347b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      break;
1348b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    default:
1349b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LOG(FATAL) << "UNREACHABLE";
1350b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1351b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1352b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1353e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when
1354e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldStoreOffset, as expected by JIT::GuardedStoreToOffset.
13552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreSToOffset(SRegister reg,
13562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  Register base,
13572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  int32_t offset,
13582c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  Condition cond) {
1359e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  if (!Address::CanHoldStoreOffset(kStoreSWord, offset)) {
1360e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK_NE(base, IP);
1361e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    LoadImmediate(IP, offset, cond);
1362e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    add(IP, IP, ShifterOperand(base), cond);
1363e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    base = IP;
1364e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    offset = 0;
1365e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  }
1366e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  CHECK(Address::CanHoldStoreOffset(kStoreSWord, offset));
1367e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  vstrs(reg, Address(base, offset), cond);
1368e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro}
1369e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro
1370e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when
1371e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldStoreOffset, as expected by JIT::GuardedStoreSToOffset.
13722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreDToOffset(DRegister reg,
13732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  Register base,
13742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  int32_t offset,
13752c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  Condition cond) {
1376e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  if (!Address::CanHoldStoreOffset(kStoreDWord, offset)) {
1377e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK_NE(base, IP);
1378e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    LoadImmediate(IP, offset, cond);
1379e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    add(IP, IP, ShifterOperand(base), cond);
1380e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    base = IP;
1381e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    offset = 0;
1382e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  }
1383e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  CHECK(Address::CanHoldStoreOffset(kStoreDWord, offset));
1384e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  vstrd(reg, Address(base, offset), cond);
1385e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro}
1386e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro
13872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Push(Register rd, Condition cond) {
13889b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  str(rd, Address(SP, -kRegisterSize, Address::PreIndex), cond);
13899b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
13909b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
13912c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Pop(Register rd, Condition cond) {
13929b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  ldr(rd, Address(SP, kRegisterSize, Address::PostIndex), cond);
13939b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
13949b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
13952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::PushList(RegList regs, Condition cond) {
13969b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  stm(DB_W, SP, regs, cond);
13979b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
13989b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
13992c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::PopList(RegList regs, Condition cond) {
14009b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  ldm(IA_W, SP, regs, cond);
14019b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
14029b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
14032c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Mov(Register rd, Register rm, Condition cond) {
14049b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  if (rd != rm) {
14059b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro    mov(rd, ShifterOperand(rm), cond);
14069b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  }
14079b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
14089b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
14092c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Lsl(Register rd, Register rm, uint32_t shift_imm,
14102c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
14119b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  CHECK_NE(shift_imm, 0u);  // Do not use Lsl if no shift is wanted.
14129b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  mov(rd, ShifterOperand(rm, LSL, shift_imm), cond);
14139b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
14149b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
14152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Lsr(Register rd, Register rm, uint32_t shift_imm,
14162c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
14179b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  CHECK_NE(shift_imm, 0u);  // Do not use Lsr if no shift is wanted.
14189b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
14199b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  mov(rd, ShifterOperand(rm, LSR, shift_imm), cond);
14209b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
14219b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
14222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Asr(Register rd, Register rm, uint32_t shift_imm,
14232c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
14249b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  CHECK_NE(shift_imm, 0u);  // Do not use Asr if no shift is wanted.
14259b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
14269b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  mov(rd, ShifterOperand(rm, ASR, shift_imm), cond);
14279b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
14289b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
14292c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Ror(Register rd, Register rm, uint32_t shift_imm,
14302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                       Condition cond) {
14319b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  CHECK_NE(shift_imm, 0u);  // Use Rrx instruction.
14329b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  mov(rd, ShifterOperand(rm, ROR, shift_imm), cond);
14339b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
14349b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
14352c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Rrx(Register rd, Register rm, Condition cond) {
14369b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  mov(rd, ShifterOperand(rm, ROR, 0), cond);
14379b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro}
14389b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro
14392c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
1440b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers                              const std::vector<ManagedRegister>& callee_save_regs,
1441b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers                              const std::vector<ManagedRegister>& entry_spills) {
144206b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes  CHECK_ALIGNED(frame_size, kStackAlignment);
14432c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  CHECK_EQ(R0, method_reg.AsArm().AsCoreRegister());
1444bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
144500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan 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
145500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan 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
146000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Write out Method*.
1461bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  StoreToOffset(kStoreWord, R0, SP, 0);
146200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
146300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Write out entry spills.
146400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  for (size_t i = 0; i < entry_spills.size(); ++i) {
146500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Register reg = entry_spills.at(i).AsArm().AsCoreRegister();
146600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    StoreToOffset(kStoreWord, reg, SP, frame_size + kPointerSize + (i * kPointerSize));
146700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
1468b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1469b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
14702c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::RemoveFrame(size_t frame_size,
1471bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers                              const std::vector<ManagedRegister>& callee_save_regs) {
147206b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes  CHECK_ALIGNED(frame_size, kStackAlignment);
1473bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Compute callee saves to pop and PC
1474bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  RegList pop_list = 1 << PC;
1475bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  size_t pop_values = 1;
1476bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  for (size_t i = 0; i < callee_save_regs.size(); i++) {
1477bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    Register reg = callee_save_regs.at(i).AsArm().AsCoreRegister();
1478bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    pop_list |= 1 << reg;
1479bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers    pop_values++;
14800d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers  }
1481bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
1482bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Decrease frame to start of callee saves
1483bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  CHECK_GT(frame_size, pop_values * kPointerSize);
1484bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  size_t adjust = frame_size - (pop_values * kPointerSize);
1485bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  DecreaseFrameSize(adjust);
1486bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
1487bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  // Pop callee saves and PC
1488bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  PopList(pop_list);
14890d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers}
14900d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers
14912c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::IncreaseFrameSize(size_t adjust) {
1492b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  AddConstant(SP, -adjust);
1493b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1494b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
14952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::DecreaseFrameSize(size_t adjust) {
1496b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  AddConstant(SP, adjust);
1497b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1498b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
14992c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Store(FrameOffset dest, ManagedRegister msrc, size_t size) {
15002c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister src = msrc.AsArm();
1501e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  if (src.IsNoRegister()) {
1502e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK_EQ(0u, size);
1503e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  } else if (src.IsCoreRegister()) {
1504b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    CHECK_EQ(4u, size);
1505b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value());
1506e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  } else if (src.IsRegisterPair()) {
1507e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    CHECK_EQ(8u, size);
1508e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    StoreToOffset(kStoreWord, src.AsRegisterPairLow(), SP, dest.Int32Value());
1509e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    StoreToOffset(kStoreWord, src.AsRegisterPairHigh(),
1510e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro                  SP, dest.Int32Value() + 4);
1511e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  } else if (src.IsSRegister()) {
1512e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    StoreSToOffset(src.AsSRegister(), SP, dest.Int32Value());
1513b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1514bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes    CHECK(src.IsDRegister()) << src;
1515e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    StoreDToOffset(src.AsDRegister(), SP, dest.Int32Value());
1516b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1517b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1518b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
15192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreRef(FrameOffset dest, ManagedRegister msrc) {
15202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister src = msrc.AsArm();
1521bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(src.IsCoreRegister()) << src;
1522b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value());
1523b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1524b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
15252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreRawPtr(FrameOffset dest, ManagedRegister msrc) {
15262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister src = msrc.AsArm();
1527bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(src.IsCoreRegister()) << src;
1528df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers  StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value());
1529df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers}
1530df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers
15312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreSpanning(FrameOffset dest, ManagedRegister msrc,
15322c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                              FrameOffset in_off, ManagedRegister mscratch) {
15332c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister src = msrc.AsArm();
15342c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
15357a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers  StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value());
15367a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, in_off.Int32Value());
15377a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value() + 4);
15387a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers}
15397a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers
15402c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CopyRef(FrameOffset dest, FrameOffset src,
15412c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        ManagedRegister mscratch) {
15422c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1543b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value());
1544b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
1545b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1546b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
15472c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadRef(ManagedRegister mdest, ManagedRegister base,
15482c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                           MemberOffset offs) {
1549bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  ArmManagedRegister dst = mdest.AsArm();
1550bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(dst.IsCoreRegister() && dst.IsCoreRegister()) << dst;
1551bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  LoadFromOffset(kLoadWord, dst.AsCoreRegister(),
15522c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                 base.AsArm().AsCoreRegister(), offs.Int32Value());
1553b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1554b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
15552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadRef(ManagedRegister mdest, FrameOffset  src) {
1556bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  ArmManagedRegister dst = mdest.AsArm();
1557bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(dst.IsCoreRegister()) << dst;
1558bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  LoadFromOffset(kLoadWord, dst.AsCoreRegister(), SP, src.Int32Value());
1559362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes}
15602c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers
15612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadRawPtr(ManagedRegister mdest, ManagedRegister base,
1562a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers                           Offset offs) {
1563bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  ArmManagedRegister dst = mdest.AsArm();
1564bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(dst.IsCoreRegister() && dst.IsCoreRegister()) << dst;
1565bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  LoadFromOffset(kLoadWord, dst.AsCoreRegister(),
15662c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                 base.AsArm().AsCoreRegister(), offs.Int32Value());
1567a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers}
1568a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers
15692c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
15702c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                      ManagedRegister mscratch) {
15712c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1572bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(scratch.IsCoreRegister()) << scratch;
1573b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadImmediate(scratch.AsCoreRegister(), imm);
1574b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
1575b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1576b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
15772c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreImmediateToThread(ThreadOffset dest, uint32_t imm,
15782c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                       ManagedRegister mscratch) {
15792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1580bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(scratch.IsCoreRegister()) << scratch;
1581b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadImmediate(scratch.AsCoreRegister(), imm);
1582b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(), TR, dest.Int32Value());
1583b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1584b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1585bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughesstatic void EmitLoad(ArmAssembler* assembler, ManagedRegister m_dst,
1586bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes                     Register src_register, int32_t src_offset, size_t size) {
1587bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  ArmManagedRegister dst = m_dst.AsArm();
1588bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  if (dst.IsNoRegister()) {
1589bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes    CHECK_EQ(0u, size) << dst;
1590bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  } else if (dst.IsCoreRegister()) {
1591bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes    CHECK_EQ(4u, size) << dst;
1592bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes    assembler->LoadFromOffset(kLoadWord, dst.AsCoreRegister(), src_register, src_offset);
1593bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  } else if (dst.IsRegisterPair()) {
1594bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes    CHECK_EQ(8u, size) << dst;
1595bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes    assembler->LoadFromOffset(kLoadWord, dst.AsRegisterPairLow(), src_register, src_offset);
1596bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes    assembler->LoadFromOffset(kLoadWord, dst.AsRegisterPairHigh(), src_register, src_offset + 4);
1597bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  } else if (dst.IsSRegister()) {
1598bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes    assembler->LoadSFromOffset(dst.AsSRegister(), src_register, src_offset);
1599b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1600bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes    CHECK(dst.IsDRegister()) << dst;
1601bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes    assembler->LoadDFromOffset(dst.AsDRegister(), src_register, src_offset);
1602b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1603b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1604b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1605bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughesvoid ArmAssembler::Load(ManagedRegister m_dst, FrameOffset src, size_t size) {
1606bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  return EmitLoad(this, m_dst, SP, src.Int32Value(), size);
16075a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers}
16085a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers
1609bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughesvoid ArmAssembler::Load(ManagedRegister m_dst, ThreadOffset src, size_t size) {
1610bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  return EmitLoad(this, m_dst, TR, src.Int32Value(), size);
1611bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes}
1612bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes
1613bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughesvoid ArmAssembler::LoadRawPtrFromThread(ManagedRegister m_dst, ThreadOffset offs) {
1614bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  ArmManagedRegister dst = m_dst.AsArm();
1615bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(dst.IsCoreRegister()) << dst;
1616bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  LoadFromOffset(kLoadWord, dst.AsCoreRegister(), TR, offs.Int32Value());
1617b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1618b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
16192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CopyRawPtrFromThread(FrameOffset fr_offs,
16202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                        ThreadOffset thr_offs,
16212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                        ManagedRegister mscratch) {
16222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1623bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(scratch.IsCoreRegister()) << scratch;
1624b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1625b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                 TR, thr_offs.Int32Value());
1626b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(),
1627b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                SP, fr_offs.Int32Value());
1628b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1629b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
16302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CopyRawPtrToThread(ThreadOffset thr_offs,
16312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                      FrameOffset fr_offs,
16322c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                      ManagedRegister mscratch) {
16332c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1634bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(scratch.IsCoreRegister()) << scratch;
1635b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1636b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                 SP, fr_offs.Int32Value());
1637b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(),
1638b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                TR, thr_offs.Int32Value());
1639b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1640b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
16412c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreStackOffsetToThread(ThreadOffset thr_offs,
16422c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                            FrameOffset fr_offs,
16432c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                            ManagedRegister mscratch) {
16442c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1645bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(scratch.IsCoreRegister()) << scratch;
1646b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  AddConstant(scratch.AsCoreRegister(), SP, fr_offs.Int32Value(), AL);
1647b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(),
1648b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                TR, thr_offs.Int32Value());
1649b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1650b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
16512c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreStackPointerToThread(ThreadOffset thr_offs) {
165245a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers  StoreToOffset(kStoreWord, SP, TR, thr_offs.Int32Value());
165345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers}
165445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
165558136caeec7cb677bb83c2eafd1f4bab5afd96c8jeffhaovoid ArmAssembler::SignExtend(ManagedRegister /*mreg*/, size_t /*size*/) {
165658136caeec7cb677bb83c2eafd1f4bab5afd96c8jeffhao  UNIMPLEMENTED(FATAL) << "no sign extension necessary for arm";
165758136caeec7cb677bb83c2eafd1f4bab5afd96c8jeffhao}
165858136caeec7cb677bb83c2eafd1f4bab5afd96c8jeffhao
1659cee4d0c1c2faacf0eae748a24cc7e455e067d977jeffhaovoid ArmAssembler::ZeroExtend(ManagedRegister /*mreg*/, size_t /*size*/) {
1660cee4d0c1c2faacf0eae748a24cc7e455e067d977jeffhao  UNIMPLEMENTED(FATAL) << "no zero extension necessary for arm";
1661cee4d0c1c2faacf0eae748a24cc7e455e067d977jeffhao}
1662cee4d0c1c2faacf0eae748a24cc7e455e067d977jeffhao
1663bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughesvoid ArmAssembler::Move(ManagedRegister m_dst, ManagedRegister m_src, size_t /*size*/) {
1664bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  ArmManagedRegister dst = m_dst.AsArm();
1665bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  ArmManagedRegister src = m_src.AsArm();
1666bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  if (!dst.Equals(src)) {
1667bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes    if (dst.IsCoreRegister()) {
1668bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes      CHECK(src.IsCoreRegister()) << src;
1669bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes      mov(dst.AsCoreRegister(), ShifterOperand(src.AsCoreRegister()));
1670bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes    } else if (dst.IsDRegister()) {
1671bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes      CHECK(src.IsDRegister()) << src;
1672bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes      vmovd(dst.AsDRegister(), src.AsDRegister());
1673bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes    } else if (dst.IsSRegister()) {
1674bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes      CHECK(src.IsSRegister()) << src;
1675bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes      vmovs(dst.AsSRegister(), src.AsSRegister());
1676e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    } else {
1677bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes      CHECK(dst.IsRegisterPair()) << dst;
1678bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes      CHECK(src.IsRegisterPair()) << src;
16797a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      // Ensure that the first move doesn't clobber the input of the second
1680bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes      if (src.AsRegisterPairHigh() != dst.AsRegisterPairLow()) {
1681bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes        mov(dst.AsRegisterPairLow(), ShifterOperand(src.AsRegisterPairLow()));
1682bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes        mov(dst.AsRegisterPairHigh(), ShifterOperand(src.AsRegisterPairHigh()));
16837a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      } else {
1684bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes        mov(dst.AsRegisterPairHigh(), ShifterOperand(src.AsRegisterPairHigh()));
1685bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes        mov(dst.AsRegisterPairLow(), ShifterOperand(src.AsRegisterPairLow()));
16867a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers      }
1687e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    }
1688b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1689b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1690b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1691dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogersvoid ArmAssembler::Copy(FrameOffset dest, FrameOffset src, ManagedRegister mscratch, size_t size) {
16922c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1693bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(scratch.IsCoreRegister()) << scratch;
1694bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(size == 4 || size == 8) << size;
1695b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (size == 4) {
1696dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers    LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value());
1697dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers    StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
16985381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao  } else if (size == 8) {
1699dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers    LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value());
1700dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers    StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
1701dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers    LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value() + 4);
1702dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers    StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value() + 4);
1703b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1704b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1705b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
1706dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogersvoid ArmAssembler::Copy(FrameOffset dest, ManagedRegister src_base, Offset src_offset,
1707dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers                        ManagedRegister mscratch, size_t size) {
1708dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers  Register scratch = mscratch.AsArm().AsCoreRegister();
1709dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers  CHECK_EQ(size, 4u);
1710dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers  LoadFromOffset(kLoadWord, scratch, src_base.AsArm().AsCoreRegister(), src_offset.Int32Value());
1711dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers  StoreToOffset(kStoreWord, scratch, SP, dest.Int32Value());
1712dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers}
1713dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers
17145a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogersvoid ArmAssembler::Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
17155a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers                        ManagedRegister mscratch, size_t size) {
17165a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  Register scratch = mscratch.AsArm().AsCoreRegister();
17175a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  CHECK_EQ(size, 4u);
17185a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  LoadFromOffset(kLoadWord, scratch, SP, src.Int32Value());
17195a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  StoreToOffset(kStoreWord, scratch, dest_base.AsArm().AsCoreRegister(), dest_offset.Int32Value());
17205a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers}
17215a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers
17221bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesvoid ArmAssembler::Copy(FrameOffset /*dst*/, FrameOffset /*src_base*/, Offset /*src_offset*/,
17231bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                        ManagedRegister /*mscratch*/, size_t /*size*/) {
1724dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers  UNIMPLEMENTED(FATAL);
1725dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers}
1726dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers
17275a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogersvoid ArmAssembler::Copy(ManagedRegister dest, Offset dest_offset,
17285a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers                        ManagedRegister src, Offset src_offset,
17295a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers                        ManagedRegister mscratch, size_t size) {
1730dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers  CHECK_EQ(size, 4u);
17315a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  Register scratch = mscratch.AsArm().AsCoreRegister();
17325a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  LoadFromOffset(kLoadWord, scratch, src.AsArm().AsCoreRegister(), src_offset.Int32Value());
17335a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  StoreToOffset(kStoreWord, scratch, dest.AsArm().AsCoreRegister(), dest_offset.Int32Value());
17345a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers}
17355a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers
17361bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesvoid ArmAssembler::Copy(FrameOffset /*dst*/, Offset /*dest_offset*/, FrameOffset /*src*/, Offset /*src_offset*/,
17371bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                        ManagedRegister /*scratch*/, size_t /*size*/) {
17385a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers  UNIMPLEMENTED(FATAL);
1739dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers}
1740dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers
1741dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers
1742e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogersvoid ArmAssembler::MemoryBarrier(ManagedRegister mscratch) {
1743bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK_EQ(mscratch.AsArm().AsCoreRegister(), R12);
1744e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#if ANDROID_SMP != 0
1745e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#if defined(__ARM_HAVE_DMB)
1746e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  int32_t encoding = 0xf57ff05f;  // dmb
1747e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  Emit(encoding);
1748e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#elif  defined(__ARM_HAVE_LDREX_STREX)
1749e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  LoadImmediate(R12, 0);
1750e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  int32_t encoding = 0xee07cfba;  // mcr p15, 0, r12, c7, c10, 5
1751e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  Emit(encoding);
1752e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#else
1753e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  LoadImmediate(R12, 0xffff0fa0);  // kuser_memory_barrier
1754e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  blx(R12);
1755e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#endif
1756e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#endif
1757e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers}
1758e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers
17592c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CreateSirtEntry(ManagedRegister mout_reg,
17602c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   FrameOffset sirt_offset,
17612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   ManagedRegister min_reg, bool null_allowed) {
17622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister out_reg = mout_reg.AsArm();
17632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister in_reg = min_reg.AsArm();
1764bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(in_reg.IsNoRegister() || in_reg.IsCoreRegister()) << in_reg;
1765bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(out_reg.IsCoreRegister()) << out_reg;
1766b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (null_allowed) {
1767408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    // Null values get a SIRT entry value of 0.  Otherwise, the SIRT entry is
1768408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    // the address in the SIRT holding the reference.
1769b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    // e.g. out_reg = (handle == 0) ? 0 : (SP+handle_offset)
1770e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    if (in_reg.IsNoRegister()) {
1771e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro      LoadFromOffset(kLoadWord, out_reg.AsCoreRegister(),
1772408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers                     SP, sirt_offset.Int32Value());
1773e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro      in_reg = out_reg;
1774e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro    }
1775b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    cmp(in_reg.AsCoreRegister(), ShifterOperand(0));
1776b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    if (!out_reg.Equals(in_reg)) {
1777b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers      LoadImmediate(out_reg.AsCoreRegister(), 0, EQ);
1778b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    }
1779408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    AddConstant(out_reg.AsCoreRegister(), SP, sirt_offset.Int32Value(), NE);
1780b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1781408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    AddConstant(out_reg.AsCoreRegister(), SP, sirt_offset.Int32Value(), AL);
1782b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1783b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1784b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
17852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CreateSirtEntry(FrameOffset out_off,
17862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   FrameOffset sirt_offset,
17872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   ManagedRegister mscratch,
17882c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                   bool null_allowed) {
17892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1790bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(scratch.IsCoreRegister()) << scratch;
1791b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (null_allowed) {
1792b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP,
1793408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers                   sirt_offset.Int32Value());
1794408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    // Null values get a SIRT entry value of 0.  Otherwise, the sirt entry is
1795408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    // the address in the SIRT holding the reference.
1796408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    // e.g. scratch = (scratch == 0) ? 0 : (SP+sirt_offset)
1797b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    cmp(scratch.AsCoreRegister(), ShifterOperand(0));
1798408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    AddConstant(scratch.AsCoreRegister(), SP, sirt_offset.Int32Value(), NE);
1799b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  } else {
1800408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers    AddConstant(scratch.AsCoreRegister(), SP, sirt_offset.Int32Value(), AL);
1801b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1802b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, out_off.Int32Value());
1803b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1804b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
18052c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadReferenceFromSirt(ManagedRegister mout_reg,
18062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                         ManagedRegister min_reg) {
18072c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister out_reg = mout_reg.AsArm();
18082c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister in_reg = min_reg.AsArm();
1809bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(out_reg.IsCoreRegister()) << out_reg;
1810bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(in_reg.IsCoreRegister()) << in_reg;
1811b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  Label null_arg;
1812b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  if (!out_reg.Equals(in_reg)) {
1813b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers    LoadImmediate(out_reg.AsCoreRegister(), 0, EQ);
1814b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  }
1815b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  cmp(in_reg.AsCoreRegister(), ShifterOperand(0));
1816df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers  LoadFromOffset(kLoadWord, out_reg.AsCoreRegister(),
1817df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers                 in_reg.AsCoreRegister(), 0, NE);
1818b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1819b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
18201bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesvoid ArmAssembler::VerifyObject(ManagedRegister /*src*/, bool /*could_be_null*/) {
1821b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // TODO: not validating references
1822b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1823b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
18241bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesvoid ArmAssembler::VerifyObject(FrameOffset /*src*/, bool /*could_be_null*/) {
1825b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // TODO: not validating references
1826b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1827b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
18282c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Call(ManagedRegister mbase, Offset offset,
18292c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        ManagedRegister mscratch) {
18302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister base = mbase.AsArm();
18312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1832bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(base.IsCoreRegister()) << base;
1833bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(scratch.IsCoreRegister()) << scratch;
1834b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1835b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers                 base.AsCoreRegister(), offset.Int32Value());
1836b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  blx(scratch.AsCoreRegister());
1837b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers  // TODO: place reference map on call
1838b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}
1839b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers
18402c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Call(FrameOffset base, Offset offset,
18412c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                        ManagedRegister mscratch) {
18422c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
1843bf2739d3b58ee5b2f190007499f1fbfd0b3441ceElliott Hughes  CHECK(scratch.IsCoreRegister()) << scratch;
1844e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  // Call *(*(SP + base) + offset)
1845e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1846e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro                 SP, base.Int32Value());
1847e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1848e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro                 scratch.AsCoreRegister(), offset.Int32Value());
1849e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  blx(scratch.AsCoreRegister());
1850e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  // TODO: place reference map on call
1851e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro}
1852e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro
18531bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesvoid ArmAssembler::Call(ThreadOffset /*offset*/, ManagedRegister /*scratch*/) {
1854bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers  UNIMPLEMENTED(FATAL);
1855bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers}
1856bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers
18572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::GetCurrentThread(ManagedRegister tr) {
18582c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  mov(tr.AsArm().AsCoreRegister(), ShifterOperand(TR));
1859668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao}
1860668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao
18612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::GetCurrentThread(FrameOffset offset,
18621bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                                    ManagedRegister /*scratch*/) {
1863668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao  StoreToOffset(kStoreWord, TR, SP, offset.Int32Value(), AL);
1864668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao}
1865668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao
18662c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::SuspendPoll(ManagedRegister mscratch,
18672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                               ManagedRegister return_reg,
18682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                               FrameOffset return_save_location,
18692c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                               size_t return_size) {
18702c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
18712c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmSuspendCountSlowPath* slow =
18722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers      new ArmSuspendCountSlowPath(return_reg.AsArm(), return_save_location,
18732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers                                  return_size);
1874e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  buffer_.EnqueueSlowPath(slow);
1875e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1876e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro                 TR, Thread::SuspendCountOffset().Int32Value());
1877e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  cmp(scratch.AsCoreRegister(), ShifterOperand(0));
1878e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  b(slow->Entry(), NE);
1879e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  Bind(slow->Continuation());
1880e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro}
1881e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro
18822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmSuspendCountSlowPath::Emit(Assembler* sasm) {
18832c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmAssembler* sp_asm = down_cast<ArmAssembler*>(sasm);
18842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#define __ sp_asm->
18852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  __ Bind(&entry_);
1886e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  // Save return value
18872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  __ Store(return_save_location_, return_register_, return_size_);
1888e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  // Pass thread as argument
1889e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers  __ mov(R0, ShifterOperand(TR));
189057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  __ LoadFromOffset(kLoadWord, R12, TR, ENTRYPOINT_OFFSET(pCheckSuspendFromCode));
1891e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  // Note: assume that link register will be spilled/filled on method entry/exit
18922c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  __ blx(R12);
1893e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  // Reload return value
18942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  __ Load(return_register_, return_save_location_, return_size_);
18952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  __ b(&continuation_);
18962c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#undef __
189745a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers}
189845a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
189900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid ArmAssembler::ExceptionPoll(ManagedRegister mscratch, size_t stack_adjust) {
19002c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmManagedRegister scratch = mscratch.AsArm();
190100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ArmExceptionSlowPath* slow = new ArmExceptionSlowPath(scratch, stack_adjust);
1902e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  buffer_.EnqueueSlowPath(slow);
1903e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
1904e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro                 TR, Thread::ExceptionOffset().Int32Value());
1905e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  cmp(scratch.AsCoreRegister(), ShifterOperand(0));
1906e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro  b(slow->Entry(), NE);
1907e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro}
1908e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro
19092c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmExceptionSlowPath::Emit(Assembler* sasm) {
19102c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  ArmAssembler* sp_asm = down_cast<ArmAssembler*>(sasm);
19112c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#define __ sp_asm->
19122c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  __ Bind(&entry_);
191300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (stack_adjust_ != 0) {  // Fix up the frame.
191400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    __ DecreaseFrameSize(stack_adjust_);
191500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
191667375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  // Pass exception object as argument
191767375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  // Don't care about preserving R0 as this call won't return
191867375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  __ mov(R0, ShifterOperand(scratch_.AsCoreRegister()));
191967375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  // Set up call to Thread::Current()->pDeliverException
192057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers  __ LoadFromOffset(kLoadWord, R12, TR, ENTRYPOINT_OFFSET(pDeliverException));
19212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers  __ blx(R12);
192267375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  // Call never returns
192367375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers  __ bkpt(0);
19242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#undef __
192545a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers}
192645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers
19272c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers}  // namespace arm
19286b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro}  // namespace art
1929