13e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
23e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// for details. All rights reserved. Use of this source code is governed by a
33e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// BSD-style license that can be found in the LICENSE file.
43e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf//
53e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// This is forked from Dart revision df52deea9f25690eb8b66c5995da92b70f7ac1fe
63e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// Please update the (git) revision if we merge changes from Dart.
73e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// https://code.google.com/p/dart/wiki/GettingTheSource
83e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
93e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#ifndef VM_ASSEMBLER_ARM_H_
103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#define VM_ASSEMBLER_ARM_H_
113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#ifndef VM_ASSEMBLER_H_
133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#error Do not include assembler_arm.h directly; use assembler.h instead.
143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#endif
153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#include "platform/assert.h"
173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#include "platform/utils.h"
183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#include "vm/constants_arm.h"
193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#include "vm/cpu.h"
203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#include "vm/hash_map.h"
213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#include "vm/object.h"
223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#include "vm/simulator.h"
233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfnamespace dart {
253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// Forward declarations.
273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfclass RuntimeEntry;
283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfclass StubEntry;
293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
30c5abdc1301260c79f60d60ec1117e8044312da30Karl Schimpf#if 0
31174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf// Moved to ARM32::AssemblerARM32 as needed
323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// Instruction encoding bits.
333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfenum {
343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  H   = 1 << 5,   // halfword (or byte)
353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  L   = 1 << 20,  // load (or store)
363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  S   = 1 << 20,  // set condition code (or leave unchanged)
373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  W   = 1 << 21,  // writeback base register (or leave unchanged)
383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  A   = 1 << 21,  // accumulate in multiply instruction (or not)
393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B   = 1 << 22,  // unsigned byte (or word)
403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  D   = 1 << 22,  // high/lo bit of start of s/d register range
413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  N   = 1 << 22,  // long (or short)
423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  U   = 1 << 23,  // positive (or negative) offset/index
433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  P   = 1 << 24,  // offset/pre-indexed addressing (or post-indexed addressing)
443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  I   = 1 << 25,  // immediate shifter operand (or not)
453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B0 = 1,
473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B1 = 1 << 1,
483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B2 = 1 << 2,
493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B3 = 1 << 3,
503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B4 = 1 << 4,
513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B5 = 1 << 5,
523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B6 = 1 << 6,
533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B7 = 1 << 7,
543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B8 = 1 << 8,
553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B9 = 1 << 9,
563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B10 = 1 << 10,
573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B11 = 1 << 11,
583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B12 = 1 << 12,
593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B16 = 1 << 16,
603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B17 = 1 << 17,
613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B18 = 1 << 18,
623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B19 = 1 << 19,
633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B20 = 1 << 20,
643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B21 = 1 << 21,
653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B22 = 1 << 22,
663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B23 = 1 << 23,
673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B24 = 1 << 24,
683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B25 = 1 << 25,
693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B26 = 1 << 26,
703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  B27 = 1 << 27,
713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf};
72c5abdc1301260c79f60d60ec1117e8044312da30Karl Schimpf#endif
733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfclass Label : public ValueObject {
753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf public:
763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Label() : position_(0) { }
773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  ~Label() {
793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    // Assert if label is being destroyed with unresolved branches pending.
803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ASSERT(!IsLinked());
813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Returns the position for bound and linked labels. Cannot be used
843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // for unused labels.
853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  intptr_t Position() const {
863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ASSERT(!IsUnused());
873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return IsBound() ? -position_ - kWordSize : position_ - kWordSize;
883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  bool IsBound() const { return position_ < 0; }
913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  bool IsUnused() const { return position_ == 0; }
923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  bool IsLinked() const { return position_ > 0; }
933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf private:
953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  intptr_t position_;
963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Reinitialize() {
983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    position_ = 0;
993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
1003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
1013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void BindTo(intptr_t position) {
1023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ASSERT(!IsBound());
1033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    position_ = -position - kWordSize;
1043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ASSERT(IsBound());
1053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
1063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
1073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LinkTo(intptr_t position) {
1083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ASSERT(!IsBound());
1093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    position_ = position + kWordSize;
1103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ASSERT(IsLinked());
1113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
1123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
1133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  friend class Assembler;
1143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  DISALLOW_COPY_AND_ASSIGN(Label);
1153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf};
1163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
1173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
1183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// Encodes Addressing Mode 1 - Data-processing operands.
1193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfclass Operand : public ValueObject {
1203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf public:
1213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Data-processing operands - Uninitialized.
1223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Operand() : type_(-1), encoding_(-1) { }
1233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
1243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Data-processing operands - Copy constructor.
1253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Operand(const Operand& other)
1263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      : ValueObject(), type_(other.type_), encoding_(other.encoding_) { }
1273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
1283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Data-processing operands - Assignment operator.
1293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Operand& operator=(const Operand& other) {
1303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    type_ = other.type_;
1313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    encoding_ = other.encoding_;
1323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return *this;
1333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
1343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
135f8fc12f741cdbffaf82005d4f1324dc316d9d6dfKarl Schimpf#if 0
136f8fc12f741cdbffaf82005d4f1324dc316d9d6dfKarl Schimpf  // Moved to encodeRotatedImm8() in IceAssemblerARM32.cpp
1373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Data-processing operands - Immediate.
1383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  explicit Operand(uint32_t immediate) {
1393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ASSERT(immediate < (1 << kImmed8Bits));
1403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    type_ = 1;
1413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    encoding_ = immediate;
1423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
1433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
144f8fc12f741cdbffaf82005d4f1324dc316d9d6dfKarl Schimpf  // Moved to decodeOperand() and encodeRotatedImm8() in IceAssemblerARM32.cpp
1453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Data-processing operands - Rotated immediate.
1463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Operand(uint32_t rotate, uint32_t immed8) {
1473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ASSERT((rotate < (1 << kRotateBits)) && (immed8 < (1 << kImmed8Bits)));
1483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    type_ = 1;
1493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    encoding_ = (rotate << kRotateShift) | (immed8 << kImmed8Shift);
1503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
1513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
152745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf  // Moved to decodeOperand() in IceAssemblerARM32.cpp
1533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Data-processing operands - Register.
1543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  explicit Operand(Register rm) {
1553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    type_ = 0;
1563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    encoding_ = static_cast<uint32_t>(rm);
1573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
1583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
159f4d0a7a5819541ecb44ec7dafe151114981cdb88Karl Schimpf  // Moved to encodeShiftRotateImm5() in IceAssemblerARM32.cpp
1603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Data-processing operands - Logical shift/rotate by immediate.
1613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Operand(Register rm, Shift shift, uint32_t shift_imm) {
1623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ASSERT(shift_imm < (1 << kShiftImmBits));
1633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    type_ = 0;
1643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    encoding_ = shift_imm << kShiftImmShift |
1653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                static_cast<uint32_t>(shift) << kShiftShift |
1663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                static_cast<uint32_t>(rm);
1673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
1683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
169f4d0a7a5819541ecb44ec7dafe151114981cdb88Karl Schimpf  // Moved to encodeShiftRotateReg() in IceAssemblerARM32.cpp
1703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Data-processing operands - Logical shift/rotate by register.
1713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Operand(Register rm, Shift shift, Register rs) {
1723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    type_ = 0;
1733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    encoding_ = static_cast<uint32_t>(rs) << kShiftRegisterShift |
1743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                static_cast<uint32_t>(shift) << kShiftShift | (1 << 4) |
1753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                static_cast<uint32_t>(rm);
1763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
1773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
178f8fc12f741cdbffaf82005d4f1324dc316d9d6dfKarl Schimpf  // Already defined as ARM32::OperandARM32FlexImm::canHoldImm().
1793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  static bool CanHold(uint32_t immediate, Operand* o) {
1803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    // Avoid the more expensive test for frequent small immediate values.
1813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    if (immediate < (1 << kImmed8Bits)) {
1823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      o->type_ = 1;
1833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      o->encoding_ = (0 << kRotateShift) | (immediate << kImmed8Shift);
1843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      return true;
1853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    }
1863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    // Note that immediate must be unsigned for the test to work correctly.
1873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    for (int rot = 0; rot < 16; rot++) {
1883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      uint32_t imm8 = (immediate << 2*rot) | (immediate >> (32 - 2*rot));
1893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      if (imm8 < (1 << kImmed8Bits)) {
1903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf        o->type_ = 1;
1913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf        o->encoding_ = (rot << kRotateShift) | (imm8 << kImmed8Shift);
1923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf        return true;
1933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      }
1943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    }
1953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return false;
1963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
197f8fc12f741cdbffaf82005d4f1324dc316d9d6dfKarl Schimpf#endif
1983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
1993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf private:
2003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  bool is_valid() const { return (type_ == 0) || (type_ == 1); }
2013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  uint32_t type() const {
2033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ASSERT(is_valid());
2043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return type_;
2053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
2063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  uint32_t encoding() const {
2083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ASSERT(is_valid());
2093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return encoding_;
2103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
2113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  uint32_t type_;  // Encodes the type field (bits 27-25) in the instruction.
2133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  uint32_t encoding_;
2143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  friend class Assembler;
2163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  friend class Address;
2173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf};
2183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfenum OperandSize {
2213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  kByte,
2223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  kUnsignedByte,
2233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  kHalfword,
2243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  kUnsignedHalfword,
2253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  kWord,
2263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  kUnsignedWord,
2273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  kWordPair,
2283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  kSWord,
2293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  kDWord,
2303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  kRegList,
2313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf};
2323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// Load/store multiple addressing mode.
2353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfenum BlockAddressMode {
2363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // bit encoding P U W
2373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  DA           = (0|0|0) << 21,  // decrement after
2383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  IA           = (0|4|0) << 21,  // increment after
2393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  DB           = (8|0|0) << 21,  // decrement before
2403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  IB           = (8|4|0) << 21,  // increment before
2413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  DA_W         = (0|0|1) << 21,  // decrement after with writeback to base
2423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  IA_W         = (0|4|1) << 21,  // increment after with writeback to base
2433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  DB_W         = (8|0|1) << 21,  // decrement before with writeback to base
2443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  IB_W         = (8|4|1) << 21   // increment before with writeback to base
2453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf};
2463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfclass Address : public ValueObject {
2493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf public:
2503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  enum OffsetKind {
2513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    Immediate,
2523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    IndexRegister,
2533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ScaledIndexRegister,
2543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  };
2553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Memory operand addressing mode
2573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  enum Mode {
2583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    kModeMask    = (8|4|1) << 21,
2593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    // bit encoding P U W
2603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    Offset       = (8|4|0) << 21,  // offset (w/o writeback to base)
2613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    PreIndex     = (8|4|1) << 21,  // pre-indexed addressing with writeback
2623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    PostIndex    = (0|4|0) << 21,  // post-indexed addressing with writeback
2633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    NegOffset    = (8|0|0) << 21,  // negative offset (w/o writeback to base)
2643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    NegPreIndex  = (8|0|1) << 21,  // negative pre-indexed with writeback
2653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    NegPostIndex = (0|0|0) << 21   // negative post-indexed with writeback
2663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  };
2673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Address(const Address& other)
2693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      : ValueObject(), encoding_(other.encoding_), kind_(other.kind_) {
2703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
2713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Address& operator=(const Address& other) {
2733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    encoding_ = other.encoding_;
2743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    kind_ = other.kind_;
2753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return *this;
2763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
2773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  bool Equals(const Address& other) const {
2793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return (encoding_ == other.encoding_) && (kind_ == other.kind_);
2803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
2813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
282745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf#if 0
283745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf  // Moved to decodeImmRegOffset() in IceAssemblerARM32.cpp.
284745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf  // Used to model stack offsets.
2853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  explicit Address(Register rn, int32_t offset = 0, Mode am = Offset) {
2863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ASSERT(Utils::IsAbsoluteUint(12, offset));
2873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    kind_ = Immediate;
2883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    if (offset < 0) {
2893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      encoding_ = (am ^ (1 << kUShift)) | -offset;  // Flip U to adjust sign.
2903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    } else {
2913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      encoding_ = am | offset;
2923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    }
2933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    encoding_ |= static_cast<uint32_t>(rn) << kRnShift;
2943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
295745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf#endif
2963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
2973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // There is no register offset mode unless Mode is Offset, in which case the
2983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // shifted register case below should be used.
2993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Address(Register rn, Register r, Mode am);
3003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Address(Register rn, Register rm,
3023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf          Shift shift = LSL, uint32_t shift_imm = 0, Mode am = Offset) {
3033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    Operand o(rm, shift, shift_imm);
3043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    if ((shift == LSL) && (shift_imm == 0)) {
3063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      kind_ = IndexRegister;
3073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    } else {
3083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      kind_ = ScaledIndexRegister;
3093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    }
3103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    encoding_ = o.encoding() | am | (static_cast<uint32_t>(rn) << kRnShift);
3113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
3123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // There is no shifted register mode with a register shift.
3143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Address(Register rn, Register rm, Shift shift, Register r, Mode am = Offset);
3153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  static OperandSize OperandSizeFor(intptr_t cid);
3173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  static bool CanHoldLoadOffset(OperandSize size,
3193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                int32_t offset,
3203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                int32_t* offset_mask);
3213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  static bool CanHoldStoreOffset(OperandSize size,
3223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                 int32_t offset,
3233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                 int32_t* offset_mask);
3243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  static bool CanHoldImmediateOffset(bool is_load,
3253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                     intptr_t cid,
3263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                     int64_t offset);
3273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf private:
3293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Register rn() const {
3303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return Instr::At(reinterpret_cast<uword>(&encoding_))->RnField();
3313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
3323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Register rm() const {
3343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return ((kind() == IndexRegister) || (kind() == ScaledIndexRegister)) ?
3353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf        Instr::At(reinterpret_cast<uword>(&encoding_))->RmField() :
3363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf        kNoRegister;
3373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
3383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Mode mode() const { return static_cast<Mode>(encoding() & kModeMask); }
3403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  uint32_t encoding() const { return encoding_; }
3423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3431956788f4459e0fedf91c10e8c266ca72a5d5fa1Karl Schimpf#if 0
3441956788f4459e0fedf91c10e8c266ca72a5d5fa1Karl Schimpf// Moved to encodeImmRegOffsetEnc3 in IceAssemblerARM32.cpp
3453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Encoding for addressing mode 3.
3463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  uint32_t encoding3() const;
3471956788f4459e0fedf91c10e8c266ca72a5d5fa1Karl Schimpf#endif
3483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Encoding for vfp load/store addressing.
3503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  uint32_t vencoding() const;
3513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  OffsetKind kind() const { return kind_; }
3533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  uint32_t encoding_;
3553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  OffsetKind kind_;
3573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  friend class Assembler;
3593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf};
3603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfclass FieldAddress : public Address {
3633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf public:
3643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  FieldAddress(Register base, int32_t disp)
3653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      : Address(base, disp - kHeapObjectTag) { }
3663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // This addressing mode does not exist.
3683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  FieldAddress(Register base, Register r);
3693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  FieldAddress(const FieldAddress& other) : Address(other) { }
3713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  FieldAddress& operator=(const FieldAddress& other) {
3733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    Address::operator=(other);
3743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return *this;
3753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
3763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf};
3773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfclass Assembler : public ValueObject {
3803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf public:
3813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  explicit Assembler(bool use_far_branches = false)
3823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      : buffer_(),
3833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf        prologue_offset_(-1),
3843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf        use_far_branches_(use_far_branches),
3853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf        comments_(),
3863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf        constant_pool_allowed_(false) { }
3873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  ~Assembler() { }
3893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void PopRegister(Register r) { Pop(r); }
3913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Bind(Label* label);
3933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Jump(Label* label) { b(label); }
3943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Misc. functionality
3963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  intptr_t CodeSize() const { return buffer_.Size(); }
3973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  intptr_t prologue_offset() const { return prologue_offset_; }
3983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
3993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Count the fixups that produce a pointer offset, without processing
4003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // the fixups.  On ARM there are no pointers in code.
4013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  intptr_t CountPointerOffsets() const { return 0; }
4023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  const ZoneGrowableArray<intptr_t>& GetPointerOffsets() const {
4043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ASSERT(buffer_.pointer_offsets().length() == 0);  // No pointers in code.
4053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return buffer_.pointer_offsets();
4063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
4073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  ObjectPoolWrapper& object_pool_wrapper() { return object_pool_wrapper_; }
4093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  RawObjectPool* MakeObjectPool() {
4113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return object_pool_wrapper_.MakeObjectPool();
4123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
4133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  bool use_far_branches() const {
4153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return FLAG_use_far_branches || use_far_branches_;
4163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
4173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#if defined(TESTING) || defined(DEBUG)
4193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Used in unit tests and to ensure predictable verification code size in
4203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // FlowGraphCompiler::EmitEdgeCounter.
4213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void set_use_far_branches(bool b) {
4223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    use_far_branches_ = b;
4233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
4243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#endif  // TESTING || DEBUG
4253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void FinalizeInstructions(const MemoryRegion& region) {
4273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    buffer_.FinalizeInstructions(region);
4283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
4293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Debugging and bringup support.
4313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Stop(const char* message);
4323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Unimplemented(const char* message);
4333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Untested(const char* message);
4343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Unreachable(const char* message);
4353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  static void InitializeMemoryWithBreakpoints(uword data, intptr_t length);
4373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
4393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  static bool EmittingComments();
4403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  const Code::Comments& GetCodeComments() const;
4423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  static const char* RegisterName(Register reg);
4443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  static const char* FpuRegisterName(FpuRegister reg);
4463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
447c33f7bbd4160a88aa95f81876b54e90edf982ca3Karl Schimpf#if 0
448c33f7bbd4160a88aa95f81876b54e90edf982ca3Karl Schimpf  // Moved to ARM32::AssemblerARM32::and_()
4493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Data-processing instructions.
4503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void and_(Register rd, Register rn, Operand o, Condition cond = AL);
4513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
45262d367bdc5f04368566e6e67f4f1b801a225b14dKarl Schimpf  // Moved to ARM32::AssemblerARM32::eor()
4533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void eor(Register rd, Register rn, Operand o, Condition cond = AL);
4543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
455745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf  // Moved to ARM32::AssemberARM32::sub()
4563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void sub(Register rd, Register rn, Operand o, Condition cond = AL);
4573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void subs(Register rd, Register rn, Operand o, Condition cond = AL);
4583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
459dca86741c89dbcb3fa7b77e9124a5985f04ee2d7Karl Schimpf  // Moved to ARM32::AssemberARM32::rsb()
4603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void rsb(Register rd, Register rn, Operand o, Condition cond = AL);
4613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void rsbs(Register rd, Register rn, Operand o, Condition cond = AL);
4623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
463745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf  // Moved to ARM32::AssemblerARM32::add()
4643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void add(Register rd, Register rn, Operand o, Condition cond = AL);
4653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void adds(Register rd, Register rn, Operand o, Condition cond = AL);
4673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
468db0988808f99ee4895ea80c3e5c1b812e3d09e5bKarl Schimpf  // Moved to ARM32::AssemblerARM32::adc()
4693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void adc(Register rd, Register rn, Operand o, Condition cond = AL);
4703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void adcs(Register rd, Register rn, Operand o, Condition cond = AL);
4723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
473337ac9e775203b2449d7020931dc58f29d55cd44Karl Schimpf  // Moved to ARM32::AssemblerARM32::sbc()
4743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void sbc(Register rd, Register rn, Operand o, Condition cond = AL);
4753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
476337ac9e775203b2449d7020931dc58f29d55cd44Karl Schimpf  // Moved to ARM32::AssemblerARM32::sbc()
4773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void sbcs(Register rd, Register rn, Operand o, Condition cond = AL);
4783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
479337ac9e775203b2449d7020931dc58f29d55cd44Karl Schimpf  // Moved to ARM32::AssemblerARM32::rsc()
4803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void rsc(Register rd, Register rn, Operand o, Condition cond = AL);
4813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
482b81b90150e980671bc51e72c928ed0bad75bcd6aKarl Schimpf  // Moved to ARM32::AssemblerARM32::tst();
4833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void tst(Register rn, Operand o, Condition cond = AL);
484b81b90150e980671bc51e72c928ed0bad75bcd6aKarl Schimpf#endif
4853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void teq(Register rn, Operand o, Condition cond = AL);
4873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
488f8fc12f741cdbffaf82005d4f1324dc316d9d6dfKarl Schimpf#if 0
489f8fc12f741cdbffaf82005d4f1324dc316d9d6dfKarl Schimpf  // Moved to ARM32::AssemblerARM32::cmp()
4903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void cmp(Register rn, Operand o, Condition cond = AL);
4913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4924c435d328c90e128543733b54e27bfca2195e54dKarl Schimpf  // Moved to ARM32::AssemblerARM32::cmn()
4933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void cmn(Register rn, Operand o, Condition cond = AL);
4943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4959c08bee818e14fa266d7f13c829f6f4d2eb81485Karl Schimpf  // Moved to ARM32::IceAssemblerARM32::orr().
4963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void orr(Register rd, Register rn, Operand o, Condition cond = AL);
4973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void orrs(Register rd, Register rn, Operand o, Condition cond = AL);
4983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
4999c08bee818e14fa266d7f13c829f6f4d2eb81485Karl Schimpf  // Moved to ARM32::IceAssemblerARM32::mov()
5003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void mov(Register rd, Operand o, Condition cond = AL);
5013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void movs(Register rd, Operand o, Condition cond = AL);
5023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
5034f8805b70917bf0de9ba277a0af2d6f1d582be52Karl Schimpf  // Moved to ARM32::IceAssemblerARM32::bic()
5043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void bic(Register rd, Register rn, Operand o, Condition cond = AL);
5053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void bics(Register rd, Register rn, Operand o, Condition cond = AL);
5063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
507e559be77b93bdfa5b0877455f012219aa426f10fKarl Schimpf  // Moved to ARM32::IceAssemblerARM32::mvn()
5083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void mvn(Register rd, Operand o, Condition cond = AL);
5093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void mvns(Register rd, Operand o, Condition cond = AL);
5103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
5113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Miscellaneous data-processing instructions.
51265f80d72389d036abaa3714ca18d95bf59ebb1faKarl Schimpf  // Moved to ARM32::AssemblerARM32::clz()
5133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void clz(Register rd, Register rm, Condition cond = AL);
5143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
5153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Multiply instructions.
51665f80d72389d036abaa3714ca18d95bf59ebb1faKarl Schimpf
517697dc7966c9827f5cdac9f752351cb90e7bf00d5Karl Schimpf  // Moved to ARM32::AssemblerARM32::mul()
5183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void mul(Register rd, Register rn, Register rm, Condition cond = AL);
5193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void muls(Register rd, Register rn, Register rm, Condition cond = AL);
520080b65b5e73b17d39d1f08b84af3c075b3e46e77Karl Schimpf
521080b65b5e73b17d39d1f08b84af3c075b3e46e77Karl Schimpf  // Moved to ARM32::AssemblerARM32::mla()
5223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void mla(Register rd, Register rn, Register rm, Register ra,
5233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf           Condition cond = AL);
524a990f0c58921d886976e409e170f6c8ee40e9a23Karl Schimpf  // Moved to ARM32::AssemblerARM32::mls()
5253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void mls(Register rd, Register rn, Register rm, Register ra,
5263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf           Condition cond = AL);
527a990f0c58921d886976e409e170f6c8ee40e9a23Karl Schimpf#endif
528a990f0c58921d886976e409e170f6c8ee40e9a23Karl Schimpf
5293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void smull(Register rd_lo, Register rd_hi, Register rn, Register rm,
5303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf             Condition cond = AL);
531a990f0c58921d886976e409e170f6c8ee40e9a23Karl Schimpf
532430e84471a54f6e5a1727054be28680e489cf28dKarl Schimpf#if 0
533430e84471a54f6e5a1727054be28680e489cf28dKarl Schimpf  // Moved to ARM32::AssemblerARM32::umull();
5343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void umull(Register rd_lo, Register rd_hi, Register rn, Register rm,
5353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf             Condition cond = AL);
536430e84471a54f6e5a1727054be28680e489cf28dKarl Schimpf#endif
5373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void smlal(Register rd_lo, Register rd_hi, Register rn, Register rm,
5383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf             Condition cond = AL);
5393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void umlal(Register rd_lo, Register rd_hi, Register rn, Register rm,
5403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf             Condition cond = AL);
5413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
5423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Emulation of this instruction uses IP and the condition codes. Therefore,
5433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // none of the registers can be IP, and the instruction can only be used
5443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // unconditionally.
5453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void umaal(Register rd_lo, Register rd_hi, Register rn, Register rm);
5463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
5473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Division instructions.
548697dc7966c9827f5cdac9f752351cb90e7bf00d5Karl Schimpf#if 0
549697dc7966c9827f5cdac9f752351cb90e7bf00d5Karl Schimpf  // Moved to ARM32::AssemblerARM32::sdiv()
5503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void sdiv(Register rd, Register rn, Register rm, Condition cond = AL);
5511c28550f76d2da45def3b4bf43732c8d30b8c9f8Karl Schimpf  // Moved to ARM32::AssemblerARM32::udiv()
5523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void udiv(Register rd, Register rn, Register rm, Condition cond = AL);
5533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
554697dc7966c9827f5cdac9f752351cb90e7bf00d5Karl Schimpf  // Moved to ARM32::AssemblerARM32::ldr()
5553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Load/store instructions.
5563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void ldr(Register rd, Address ad, Condition cond = AL);
557697dc7966c9827f5cdac9f752351cb90e7bf00d5Karl Schimpf  // Moved to ARM32::AssemblerARM32::str()
5583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void str(Register rd, Address ad, Condition cond = AL);
5593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
560697dc7966c9827f5cdac9f752351cb90e7bf00d5Karl Schimpf  // Moved to ARM32::AssemblerARM32::ldr()
5613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void ldrb(Register rd, Address ad, Condition cond = AL);
562697dc7966c9827f5cdac9f752351cb90e7bf00d5Karl Schimpf  // Moved to ARM32::AssemblerARM32::str()
5633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void strb(Register rd, Address ad, Condition cond = AL);
5643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
565a990f0c58921d886976e409e170f6c8ee40e9a23Karl Schimpf  // Moved to ARM32::AssemblerARM32::ldr()
5663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void ldrh(Register rd, Address ad, Condition cond = AL);
567a990f0c58921d886976e409e170f6c8ee40e9a23Karl Schimpf  // Moved to ARM32::AssemblerARM32::str()
5683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void strh(Register rd, Address ad, Condition cond = AL);
569a990f0c58921d886976e409e170f6c8ee40e9a23Karl Schimpf#endif
5703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
5713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void ldrsb(Register rd, Address ad, Condition cond = AL);
5723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void ldrsh(Register rd, Address ad, Condition cond = AL);
5733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
5743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // ldrd and strd actually support the full range of addressing modes, but
5753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // we don't use them, and we need to split them up into two instructions for
5763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // ARMv5TE, so we only support the base + offset mode.
5773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void ldrd(Register rd, Register rn, int32_t offset, Condition cond = AL);
5783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void strd(Register rd, Register rn, int32_t offset, Condition cond = AL);
5793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
580f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf#if 0
581f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf  // Folded into ARM32::AssemblerARM32::popList(), since it is its only use (and
582f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf  // doesn't implement ARM LDM instructions).
5833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void ldm(BlockAddressMode am, Register base,
5843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf           RegList regs, Condition cond = AL);
585f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf
586f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf  // Folded into ARM32::AssemblerARM32::pushList(), since it is its only use
587f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf  // (and doesn't implement ARM STM instruction).
5883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void stm(BlockAddressMode am, Register base,
5893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf           RegList regs, Condition cond = AL);
5903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
5914175d45e14cf1eb0af11e0458a873e601dc395deKarl Schimpf  // Moved to ARM::AssemblerARM32::ldrex();
5923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void ldrex(Register rd, Register rn, Condition cond = AL);
5934175d45e14cf1eb0af11e0458a873e601dc395deKarl Schimpf  // Moved to ARM::AssemblerARM32::strex();
5943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void strex(Register rd, Register rt, Register rn, Condition cond = AL);
5954175d45e14cf1eb0af11e0458a873e601dc395deKarl Schimpf#endif
5963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
5973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Miscellaneous instructions.
5983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void clrex();
599a990f0c58921d886976e409e170f6c8ee40e9a23Karl Schimpf
60067574d83d05f5bde748843a73adcab6247736601Karl Schimpf#if 0
60167574d83d05f5bde748843a73adcab6247736601Karl Schimpf  // Moved to ARM32::AssemblerARM32::nop().
6023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void nop(Condition cond = AL);
6033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
604174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf  // Moved to ARM32::AssemblerARM32::bkpt()
6053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Note that gdb sets breakpoints using the undefined instruction 0xe7f001f0.
6063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void bkpt(uint16_t imm16);
6073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
6083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  static int32_t BkptEncoding(uint16_t imm16) {
6093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    // bkpt requires that the cond field is AL.
6103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return (AL << kConditionShift) | B24 | B21 |
6113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf           ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
6123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
6133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
614e1b6574f23b67c92fe367128b6597d54c55e88fbKarl Schimpf  // Not ported. PNaCl doesn't allow breakpoint instructions.
6153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  static uword GetBreakInstructionFiller() {
6163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return BkptEncoding(0);
6173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
6183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
6193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Floating point instructions (VFPv3-D16 and VFPv3-D32 profiles).
620e1b6574f23b67c92fe367128b6597d54c55e88fbKarl Schimpf
6214ff90be3620f73ddb41d062848325b22a6a0ac0eKarl Schimpf  // Moved to ARM32::AssemblerARM32::vmovsr().
6223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmovsr(SRegister sn, Register rt, Condition cond = AL);
623e1b6574f23b67c92fe367128b6597d54c55e88fbKarl Schimpf  // Moved to ARM32::AssemblerARM32::vmovrs().
6243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmovrs(Register rt, SRegister sn, Condition cond = AL);
625e1b6574f23b67c92fe367128b6597d54c55e88fbKarl Schimpf#endif
6263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmovsrr(SRegister sm, Register rt, Register rt2, Condition cond = AL);
6273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmovrrs(Register rt, Register rt2, SRegister sm, Condition cond = AL);
628a880ac8fcb772331ae7e27712e4da797c6927caaKarl Schimpf#if 0
629a880ac8fcb772331ae7e27712e4da797c6927caaKarl Schimpf  // Moved to ARM32::AssemblerARM32::vmovdrr().
6303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmovdrr(DRegister dm, Register rt, Register rt2, Condition cond = AL);
631a880ac8fcb772331ae7e27712e4da797c6927caaKarl Schimpf  // Moved to ARM32::AssemblerARM32::vmovrrd().
6323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmovrrd(Register rt, Register rt2, DRegister dm, Condition cond = AL);
6336de32b2199915462a4216399ff0f3af31ec88015Karl Schimpf  // Moved to ARM32::AssemblerARM32::vmovqir().
6343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmovdr(DRegister dd, int i, Register rt, Condition cond = AL);
6359aedc2e90f2220f7811ef8690a8b0fd59a4d7784Karl Schimpf  // Moved to ARM32::AssemblerARM32::vmovss().
6363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmovs(SRegister sd, SRegister sm, Condition cond = AL);
6379aedc2e90f2220f7811ef8690a8b0fd59a4d7784Karl Schimpf  // Moved to ARM32::AssemblerARM32::vmovdd().
6383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmovd(DRegister dd, DRegister dm, Condition cond = AL);
6399aedc2e90f2220f7811ef8690a8b0fd59a4d7784Karl Schimpf#endif
6403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmovq(QRegister qd, QRegister qm);
6413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
642c64448fbaf1dca1495a55e6c085555ca637e3e74Karl Schimpf#if 0
6433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Returns false if the immediate cannot be encoded.
644c64448fbaf1dca1495a55e6c085555ca637e3e74Karl Schimpf  // Moved to ARM32::AssemblerARM32::vmovs();
6453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  bool vmovs(SRegister sd, float s_imm, Condition cond = AL);
646c64448fbaf1dca1495a55e6c085555ca637e3e74Karl Schimpf  // Moved to ARM32::AssemblerARM32::vmovs();
6473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  bool vmovd(DRegister dd, double d_imm, Condition cond = AL);
6483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
649e1d71380ff9de84268c3865a89d16519385cef4aKarl Schimpf  // Moved to ARM32::AssemblerARM32::vldrs()
6503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vldrs(SRegister sd, Address ad, Condition cond = AL);
6514a55a602331f96c91be1697db4b27859ac58a270Karl Schimpf  // Moved to Arm32::AssemblerARM32::vstrs()
6523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vstrs(SRegister sd, Address ad, Condition cond = AL);
6534a55a602331f96c91be1697db4b27859ac58a270Karl Schimpf#endif
654e1d71380ff9de84268c3865a89d16519385cef4aKarl Schimpf  // Moved to ARM32::AssemblerARM32::vldrd()
6553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vldrd(DRegister dd, Address ad, Condition cond = AL);
6564a55a602331f96c91be1697db4b27859ac58a270Karl Schimpf#if 0
6574a55a602331f96c91be1697db4b27859ac58a270Karl Schimpf  // Moved to Arm32::AssemblerARM32::vstrd()
6583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vstrd(DRegister dd, Address ad, Condition cond = AL);
6594a55a602331f96c91be1697db4b27859ac58a270Karl Schimpf#endif
6603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
6613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vldms(BlockAddressMode am, Register base,
6623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf             SRegister first, SRegister last, Condition cond = AL);
6633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vstms(BlockAddressMode am, Register base,
6643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf             SRegister first, SRegister last, Condition cond = AL);
6653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
6663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vldmd(BlockAddressMode am, Register base,
6673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf             DRegister first, intptr_t count, Condition cond = AL);
6683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vstmd(BlockAddressMode am, Register base,
6693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf             DRegister first, intptr_t count, Condition cond = AL);
6703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
6714acf11ac13716f5998b56cb65c1c72341276cc5fKarl Schimpf#if 0
6724acf11ac13716f5998b56cb65c1c72341276cc5fKarl Schimpf  // Moved to Arm32::AssemblerARM32::vadds()
6733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vadds(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
6744acf11ac13716f5998b56cb65c1c72341276cc5fKarl Schimpf  // Moved to Arm32::AssemblerARM32::vaddd()
6753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vaddd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
6762c0764e2da74e61b1ef1316980972e5177512a74Karl Schimpf  // Moved to ARM32::AssemblerARM32::vaddqi().
6773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vaddqi(OperandSize sz, QRegister qd, QRegister qn, QRegister qm);
6782c0764e2da74e61b1ef1316980972e5177512a74Karl Schimpf  // Moved to ARM32::AssemblerARM32::vaddqf().
6793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vaddqs(QRegister qd, QRegister qn, QRegister qm);
680b3e2574c24ea0e81bbcb9c105a4cb153551a48f2Karl Schimpf  // Moved to Arm32::AssemblerARM32::vsubs()
6813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vsubs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
682b3e2574c24ea0e81bbcb9c105a4cb153551a48f2Karl Schimpf  // Moved to Arm32::AssemblerARM32::vsubd()
6833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vsubd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
68450cfcb065f0316432f6db66cd23e87765525ec86Karl Schimpf  // Moved to ARM32::AssemblerARM32::vsubqi().
6853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vsubqi(OperandSize sz, QRegister qd, QRegister qn, QRegister qm);
68650cfcb065f0316432f6db66cd23e87765525ec86Karl Schimpf  // Moved to ARM32::AssemblerARM32::vsubqf().
6873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vsubqs(QRegister qd, QRegister qn, QRegister qm);
6888a105fd788ba9bcdd4aa2b154d166e89b1a2337eKarl Schimpf  // Moved to Arm32::AssemblerARM32::vmuls()
6893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmuls(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
6908a105fd788ba9bcdd4aa2b154d166e89b1a2337eKarl Schimpf  // Moved to Arm32::AssemblerARM32::vmuld()
6913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmuld(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
692341158aaa16449090a09dad48c337449d3b4687aKarl Schimpf  // Moved to ARM32::AssemblerARM32::vmulqi().
6933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmulqi(OperandSize sz, QRegister qd, QRegister qn, QRegister qm);
694341158aaa16449090a09dad48c337449d3b4687aKarl Schimpf  // Moved to ARM32::AssemblerARM32::vmulqf().
6953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmulqs(QRegister qd, QRegister qn, QRegister qm);
69615e77d4698df65dfce5072b59df18500ff56daa3John Porto  // Moved to ARM32::AssemblerARM32::vshlqi().
6973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vshlqi(OperandSize sz, QRegister qd, QRegister qm, QRegister qn);
69815e77d4698df65dfce5072b59df18500ff56daa3John Porto  // Moved to ARM32::AssemblerARM32::vshlqu().
6993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vshlqu(OperandSize sz, QRegister qd, QRegister qm, QRegister qn);
700bd8e28e3b02fc830c37a94acfdd9e5585a7a2ab2Karl Schimpf  // Moved to Arm32::AssemblerARM32::vmlas()
7013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmlas(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
702bd8e28e3b02fc830c37a94acfdd9e5585a7a2ab2Karl Schimpf  // Moved to Arm32::AssemblerARM32::vmlad()
7033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmlad(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
704694cdbd8020f97334c24ad5cd39cf1d8b0b2868bKarl Schimpf  // Moved to Arm32::AssemblerARM32::vmlss()
7053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmlss(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
706694cdbd8020f97334c24ad5cd39cf1d8b0b2868bKarl Schimpf  // Moved to Arm32::AssemblerARM32::vmlsd()
7073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmlsd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
7083dbe780686601ac6ed753b81c91ca1b6ec84bdebKarl Schimpf  // Moved to Arm32::AssemblerARM32::vdivs()
7093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vdivs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
7103dbe780686601ac6ed753b81c91ca1b6ec84bdebKarl Schimpf  // Moved to Arm32::AssemblerARM32::vdivd()
7113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vdivd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
7123dbe780686601ac6ed753b81c91ca1b6ec84bdebKarl Schimpf#endif
7133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vminqs(QRegister qd, QRegister qn, QRegister qm);
7143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmaxqs(QRegister qd, QRegister qn, QRegister qm);
7153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vrecpeqs(QRegister qd, QRegister qm);
7163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vrecpsqs(QRegister qd, QRegister qn, QRegister qm);
7173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vrsqrteqs(QRegister qd, QRegister qm);
7183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vrsqrtsqs(QRegister qd, QRegister qn, QRegister qm);
7193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
7209aef39aff753787f6e67cee919eb6c284733c680Karl Schimpf#if 0
7219aef39aff753787f6e67cee919eb6c284733c680Karl Schimpf  // Moved to ARM32::AssemblerARM32::vorrq()
722625dfb384b3993329861d27e22689d4cc1ae1e4bKarl Schimpf  void veorq(QRegister qd, QRegister qn, QRegister qm);
723625dfb384b3993329861d27e22689d4cc1ae1e4bKarl Schimpf  // Moved to ARM32::AssemblerARM32::vorrq()
7243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vorrq(QRegister qd, QRegister qn, QRegister qm);
7259aef39aff753787f6e67cee919eb6c284733c680Karl Schimpf#endif
7263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vornq(QRegister qd, QRegister qn, QRegister qm);
727fd7975f14884a851379335a07c831fd6f33770f8Karl Schimpf#if 0
728fd7975f14884a851379335a07c831fd6f33770f8Karl Schimpf  // Moved to Arm32::AssemblerARM32::vandq().
7293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vandq(QRegister qd, QRegister qn, QRegister qm);
730a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto  // Moved to Arm32::AssemblerARM32::vandq().
7313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmvnq(QRegister qd, QRegister qm);
7323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
733a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto  // Moved to Arm32::AssemblerARM32::vceqqi().
7343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vceqqi(OperandSize sz, QRegister qd, QRegister qn, QRegister qm);
735a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto  // Moved to Arm32::AssemblerARM32::vceqqs().
7363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vceqqs(QRegister qd, QRegister qn, QRegister qm);
737a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto  // Moved to Arm32::AssemblerARM32::vcgeqi().
7383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcgeqi(OperandSize sz, QRegister qd, QRegister qn, QRegister qm);
739a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto  // Moved to Arm32::AssemblerARM32::vcugeqi().
7403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcugeqi(OperandSize sz, QRegister qd, QRegister qn, QRegister qm);
741a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto  // Moved to Arm32::AssemblerARM32::vcgeqs().
7423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcgeqs(QRegister qd, QRegister qn, QRegister qm);
743a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto  // Moved to Arm32::AssemblerARM32::vcgtqi().
7443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcgtqi(OperandSize sz, QRegister qd, QRegister qn, QRegister qm);
745a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto  // Moved to Arm32::AssemblerARM32::vcugtqi().
7463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcugtqi(OperandSize sz, QRegister qd, QRegister qn, QRegister qm);
747a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto  // Moved to Arm32::AssemblerARM32::vcgtqs().
7483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcgtqs(QRegister qd, QRegister qn, QRegister qm);
7493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
750bd4356d59ef318d8c82f3ef0c879dce147bb3146Karl Schimpf  // Moved to Arm32::AssemblerARM32::vabss().
7513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vabss(SRegister sd, SRegister sm, Condition cond = AL);
752425e06b05945520e3182e4ccf2bb3cb4db7f8690Karl Schimpf  // Moved to Arm32::AssemblerARM32::vabsd().
7533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vabsd(DRegister dd, DRegister dm, Condition cond = AL);
754425e06b05945520e3182e4ccf2bb3cb4db7f8690Karl Schimpf  // Moved to Arm32::AssemblerARM32::vabsq().
7553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vabsqs(QRegister qd, QRegister qm);
756425e06b05945520e3182e4ccf2bb3cb4db7f8690Karl Schimpf#endif
7573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vnegs(SRegister sd, SRegister sm, Condition cond = AL);
7583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vnegd(DRegister dd, DRegister dm, Condition cond = AL);
759266c5a25bb8c07b691aa6396ccef6f8d37df9cd0Karl Schimpf#if 0
76015e77d4698df65dfce5072b59df18500ff56daa3John Porto  // Moved to ARM32::AssemblerARM32::vnegqs().
76115e77d4698df65dfce5072b59df18500ff56daa3John Porto  void vnegqs(QRegister qd, QRegister qm);
762266c5a25bb8c07b691aa6396ccef6f8d37df9cd0Karl Schimpf  // Moved to ARM32::AssemblerARM32::vsqrts().
7633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vsqrts(SRegister sd, SRegister sm, Condition cond = AL);
764266c5a25bb8c07b691aa6396ccef6f8d37df9cd0Karl Schimpf  // Moved to ARM32::AssemblerARM32::vsqrts().
7653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vsqrtd(DRegister dd, DRegister dm, Condition cond = AL);
7663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
767ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf  // Moved to ARM32::AssemblerARM32::vcvtsd().
7683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcvtsd(SRegister sd, DRegister dm, Condition cond = AL);
769ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf  // Moved to ARM32::AssemblerARM32:vcvtds().
7703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcvtds(DRegister dd, SRegister sm, Condition cond = AL);
77194cc3e6190b3b91d1ac6c4e894391d48228f8e97Karl Schimpf  // Moved to ARM32::AssemblerARM32::vcvtis()
7723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcvtis(SRegister sd, SRegister sm, Condition cond = AL);
773ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf  // Moved to ARM32::AssemblerARM32::vcvtid()
7743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcvtid(SRegister sd, DRegister dm, Condition cond = AL);
775ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf  // Moved to ARM32::AssemblerARM32::vcvtsi()
7763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcvtsi(SRegister sd, SRegister sm, Condition cond = AL);
777ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf  // Moved to ARM32::AssemblerARM32::vcvtdi()
7783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcvtdi(DRegister dd, SRegister sm, Condition cond = AL);
779ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf  // Moved to ARM32::AssemblerARM32::vcvtus().
7803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcvtus(SRegister sd, SRegister sm, Condition cond = AL);
781ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf  // Moved to ARM32::AssemblerARM32::vcvtud().
7823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcvtud(SRegister sd, DRegister dm, Condition cond = AL);
783ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf  // Moved to ARM32::AssemblerARM32::vcvtsu()
7843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcvtsu(SRegister sd, SRegister sm, Condition cond = AL);
785ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf  // Moved to ARM32::AssemblerARM32::vcvtdu()
7863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcvtdu(DRegister dd, SRegister sm, Condition cond = AL);
7873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
788cd5e07ec935e179d4d087379afb480c3897d8316Karl Schimpf  // Moved to ARM23::AssemblerARM32::vcmps().
7893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcmps(SRegister sd, SRegister sm, Condition cond = AL);
790cd5e07ec935e179d4d087379afb480c3897d8316Karl Schimpf  // Moved to ARM23::AssemblerARM32::vcmpd().
7913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcmpd(DRegister dd, DRegister dm, Condition cond = AL);
792cd5e07ec935e179d4d087379afb480c3897d8316Karl Schimpf  // Moved to ARM23::AssemblerARM32::vcmpsz().
7933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcmpsz(SRegister sd, Condition cond = AL);
794cd5e07ec935e179d4d087379afb480c3897d8316Karl Schimpf  // Moved to ARM23::AssemblerARM32::vcmpdz().
7953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vcmpdz(DRegister dd, Condition cond = AL);
796cd5e07ec935e179d4d087379afb480c3897d8316Karl Schimpf
797ee7182759bc8e9acc9a8622e73ac315c4d2dd601Karl Schimpf  // APSR_nzcv version moved to ARM32::AssemblerARM32::vmrsAPSR_nzcv()
7983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmrs(Register rd, Condition cond = AL);
799ee7182759bc8e9acc9a8622e73ac315c4d2dd601Karl Schimpf#endif
8003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vmstat(Condition cond = AL);
8013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Duplicates the operand of size sz at index idx from dm to all elements of
8033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // qd. This is a special case of vtbl.
8043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vdup(OperandSize sz, QRegister qd, DRegister dm, int idx);
8053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Each byte of dm is an index into the table of bytes formed by concatenating
8073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // a list of 'length' registers starting with dn. The result is placed in dd.
8083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vtbl(DRegister dd, DRegister dn, int length, DRegister dm);
8093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // The words of qd and qm are interleaved with the low words of the result
8113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // in qd and the high words in qm.
8123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void vzipqw(QRegister qd, QRegister qm);
8133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Branch instructions.
815174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf#if 0
816174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf  // Moved to ARM32::AssemblerARM32::b();
8173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void b(Label* label, Condition cond = AL);
818174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf  // Moved to ARM32::AssemblerARM32::bl()
8193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void bl(Label* label, Condition cond = AL);
820174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf  // Moved to ARM32::AssemblerARM32::bx()
8213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void bx(Register rm, Condition cond = AL);
822174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf  // Moved to ARM32::AssemblerARM32::blx()
8233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void blx(Register rm, Condition cond = AL);
824174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf#endif
8253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Branch(const StubEntry& stub_entry,
8273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf              Patchability patchable = kNotPatchable,
8283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf              Register pp = PP,
8293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf              Condition cond = AL);
8303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void BranchLink(const StubEntry& stub_entry,
8323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  Patchability patchable = kNotPatchable);
8333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void BranchLink(const Code& code, Patchability patchable);
8343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Branch and link to an entry address. Call sequence can be patched.
8363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void BranchLinkPatchable(const StubEntry& stub_entry);
8373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void BranchLinkPatchable(const Code& code);
8383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Branch and link to [base + offset]. Call sequence is never patched.
8403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void BranchLinkOffset(Register base, int32_t offset);
8413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Add signed immediate value to rd. May clobber IP.
8433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void AddImmediate(Register rd, int32_t value, Condition cond = AL);
8443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void AddImmediate(Register rd, Register rn, int32_t value,
8453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                    Condition cond = AL);
8463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void AddImmediateSetFlags(Register rd, Register rn, int32_t value,
8473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                            Condition cond = AL);
8483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void SubImmediateSetFlags(Register rd, Register rn, int32_t value,
8493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                            Condition cond = AL);
8503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void AndImmediate(Register rd, Register rs, int32_t imm, Condition cond = AL);
8513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Test rn and immediate. May clobber IP.
8533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void TestImmediate(Register rn, int32_t imm, Condition cond = AL);
8543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Compare rn with signed immediate value. May clobber IP.
8563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void CompareImmediate(Register rn, int32_t value, Condition cond = AL);
8573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Signed integer division of left by right. Checks to see if integer
8603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // division is supported. If not, uses the FPU for division with
8613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // temporary registers tmpl and tmpr. tmpl and tmpr must be different
8623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // registers.
8633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void IntegerDivide(Register result, Register left, Register right,
8643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                     DRegister tmpl, DRegister tmpr);
8653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Load and Store.
8673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // These three do not clobber IP.
8683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadPatchableImmediate(Register rd, int32_t value, Condition cond = AL);
8693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadDecodableImmediate(Register rd, int32_t value, Condition cond = AL);
8703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadImmediate(Register rd, int32_t value, Condition cond = AL);
8713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // These two may clobber IP.
8723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadSImmediate(SRegister sd, float value, Condition cond = AL);
8733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadDImmediate(DRegister dd, double value,
8743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      Register scratch, Condition cond = AL);
8753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void MarkExceptionHandler(Label* label);
8773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Drop(intptr_t stack_elements);
8793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void RestoreCodePointer();
8813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadPoolPointer(Register reg = PP);
8823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadIsolate(Register rd);
8843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadObject(Register rd, const Object& object, Condition cond = AL);
8863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadUniqueObject(Register rd, const Object& object, Condition cond = AL);
8873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadFunctionFromCalleePool(Register dst,
8883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                  const Function& function,
8893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                  Register new_pp);
8903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadNativeEntry(Register dst,
8913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                       const ExternalLabel* label,
8923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                       Patchability patchable,
8933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                       Condition cond = AL);
8943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void PushObject(const Object& object);
8953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void CompareObject(Register rn, const Object& object);
8963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
8973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // When storing into a heap object field, knowledge of the previous content
8983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // is expressed through these constants.
8993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  enum FieldContent {
9003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    kEmptyOrSmiOrNull,  // Empty = garbage/zapped in release/debug mode.
9013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    kHeapObjectOrSmi,
9023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    kOnlySmi,
9033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  };
9043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
9053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void StoreIntoObject(Register object,  // Object we are storing into.
9063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                       const Address& dest,  // Where we are storing into.
9073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                       Register value,  // Value we are storing.
9083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                       bool can_value_be_smi = true);
9093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void StoreIntoObjectOffset(Register object,
9103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                             int32_t offset,
9113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                             Register value,
9123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                             bool can_value_be_smi = true);
9133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
9143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void StoreIntoObjectNoBarrier(Register object,
9153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                const Address& dest,
9163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                Register value,
9173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                FieldContent old_content = kHeapObjectOrSmi);
9183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void InitializeFieldNoBarrier(Register object,
9193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                const Address& dest,
9203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                Register value) {
9213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    StoreIntoObjectNoBarrier(object, dest, value, kEmptyOrSmiOrNull);
9223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
9233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void StoreIntoObjectNoBarrierOffset(
9243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      Register object,
9253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      int32_t offset,
9263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      Register value,
9273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      FieldContent old_content = kHeapObjectOrSmi);
9283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void StoreIntoObjectNoBarrier(Register object,
9293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                const Address& dest,
9303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                const Object& value,
9313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                FieldContent old_content = kHeapObjectOrSmi);
9323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void StoreIntoObjectNoBarrierOffset(
9333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      Register object,
9343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      int32_t offset,
9353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      const Object& value,
9363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf      FieldContent old_content = kHeapObjectOrSmi);
9373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
9383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Store value_even, value_odd, value_even, ... into the words in the address
9393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // range [begin, end), assumed to be uninitialized fields in object (tagged).
9403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // The stores must not need a generational store barrier (e.g., smi/null),
9413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // and (value_even, value_odd) must be a valid register pair.
9423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Destroys register 'begin'.
9433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void InitializeFieldsNoBarrier(Register object,
9443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                 Register begin,
9453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                 Register end,
9463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                 Register value_even,
9473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                 Register value_odd);
9483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Like above, for the range [base+begin_offset, base+end_offset), unrolled.
9493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void InitializeFieldsNoBarrierUnrolled(Register object,
9503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                         Register base,
9513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                         intptr_t begin_offset,
9523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                         intptr_t end_offset,
9533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                         Register value_even,
9543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                         Register value_odd);
9553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
9563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Stores a Smi value into a heap object field that always contains a Smi.
9573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void StoreIntoSmiField(const Address& dest, Register value);
9583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
9593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadClassId(Register result, Register object, Condition cond = AL);
9603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadClassById(Register result, Register class_id);
9613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadClass(Register result, Register object, Register scratch);
9623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void CompareClassId(Register object, intptr_t class_id, Register scratch);
9633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadClassIdMayBeSmi(Register result, Register object);
9643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadTaggedClassIdMayBeSmi(Register result, Register object);
9653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
9663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void ComputeRange(Register result,
9673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                    Register value,
9683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                    Register scratch,
9693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                    Label* miss);
9703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
9713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void UpdateRangeFeedback(Register value,
9723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                           intptr_t idx,
9733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                           Register ic_data,
9743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                           Register scratch1,
9753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                           Register scratch2,
9763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                           Label* miss);
9773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
9783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  intptr_t FindImmediate(int32_t imm);
9793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  bool CanLoadFromObjectPool(const Object& object) const;
9803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadFromOffset(OperandSize type,
9813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      Register reg,
9823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      Register base,
9833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      int32_t offset,
9843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      Condition cond = AL);
9853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadFieldFromOffset(OperandSize type,
9863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                           Register reg,
9873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                           Register base,
9883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                           int32_t offset,
9893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                           Condition cond = AL) {
9903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    LoadFromOffset(type, reg, base, offset - kHeapObjectTag, cond);
9913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
9923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void StoreToOffset(OperandSize type,
9933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                     Register reg,
9943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                     Register base,
9953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                     int32_t offset,
9963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                     Condition cond = AL);
9973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadSFromOffset(SRegister reg,
9983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                       Register base,
9993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                       int32_t offset,
10003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                       Condition cond = AL);
10013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void StoreSToOffset(SRegister reg,
10023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      Register base,
10033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      int32_t offset,
10043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      Condition cond = AL);
10053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadDFromOffset(DRegister reg,
10063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                       Register base,
10073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                       int32_t offset,
10083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                       Condition cond = AL);
10093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void StoreDToOffset(DRegister reg,
10103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      Register base,
10113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      int32_t offset,
10123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      Condition cond = AL);
10133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
10143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadMultipleDFromOffset(DRegister first,
10153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                               intptr_t count,
10163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                               Register base,
10173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                               int32_t offset);
10183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void StoreMultipleDToOffset(DRegister first,
10193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                              intptr_t count,
10203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                              Register base,
10213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                              int32_t offset);
10223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
10233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void CopyDoubleField(Register dst, Register src,
10243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                       Register tmp1, Register tmp2, DRegister dtmp);
10253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void CopyFloat32x4Field(Register dst, Register src,
10263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                          Register tmp1, Register tmp2, DRegister dtmp);
10273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void CopyFloat64x2Field(Register dst, Register src,
10283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                          Register tmp1, Register tmp2, DRegister dtmp);
10293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
10306cab56197153807395ff60d1d672b0098dd97a8aKarl Schimpf#if 0
10316cab56197153807395ff60d1d672b0098dd97a8aKarl Schimpf  // Moved to ARM32::AssemblerARM32::push().
10323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Push(Register rd, Condition cond = AL);
1033f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf
1034f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf  // Moved to ARM32::AssemblerARM32::pop().
10353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Pop(Register rd, Condition cond = AL);
10363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
1037f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf  // Moved to ARM32::AssemblerARM32::pushList().
10383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void PushList(RegList regs, Condition cond = AL);
10393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
1040f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf  // Moved to ARM32::AssemblerARM32::popList().
1041f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf  void PopList(RegList regs, Condition cond = AL);
1042f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf#endif
10433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void MoveRegister(Register rd, Register rm, Condition cond = AL);
10443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
10453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Convenience shift instructions. Use mov instruction with shifter operand
10463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // for variants setting the status flags.
1047f4d0a7a5819541ecb44ec7dafe151114981cdb88Karl Schimpf#if 0
1048f4d0a7a5819541ecb44ec7dafe151114981cdb88Karl Schimpf  // Moved to ARM32::AssemblerARM32::lsl()
10493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Lsl(Register rd, Register rm, const Operand& shift_imm,
10503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf           Condition cond = AL);
1051f4d0a7a5819541ecb44ec7dafe151114981cdb88Karl Schimpf  // Moved to ARM32::AssemblerARM32::lsl()
10523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Lsl(Register rd, Register rm, Register rs, Condition cond = AL);
10534ddce702d86894de5d7e60ed0178df86ed2e7dd1Karl Schimpf  // Moved to ARM32::AssemblerARM32::lsr()
10543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Lsr(Register rd, Register rm, const Operand& shift_imm,
10553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf           Condition cond = AL);
10564ddce702d86894de5d7e60ed0178df86ed2e7dd1Karl Schimpf  // Moved to ARM32::AssemblerARM32::lsr()
10573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Lsr(Register rd, Register rm, Register rs, Condition cond = AL);
10583ac9a49be518ff47e4ad0f6390268e232740cef5Karl Schimpf  // Moved to ARM32::AssemblerARM32::asr()
10593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Asr(Register rd, Register rm, const Operand& shift_imm,
10603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf           Condition cond = AL);
10613ac9a49be518ff47e4ad0f6390268e232740cef5Karl Schimpf  // Moved to ARM32::AssemblerARM32::asr()
10623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Asr(Register rd, Register rm, Register rs, Condition cond = AL);
10633ac9a49be518ff47e4ad0f6390268e232740cef5Karl Schimpf#endif
10643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Asrs(Register rd, Register rm, const Operand& shift_imm,
10653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf            Condition cond = AL);
10663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Ror(Register rd, Register rm, const Operand& shift_imm,
10673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf           Condition cond = AL);
10683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Ror(Register rd, Register rm, Register rs, Condition cond = AL);
10693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Rrx(Register rd, Register rm, Condition cond = AL);
10703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
10713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Fill rd with the sign of rm.
10723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void SignFill(Register rd, Register rm, Condition cond = AL);
10733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
10743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Vreciprocalqs(QRegister qd, QRegister qm);
10753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void VreciprocalSqrtqs(QRegister qd, QRegister qm);
10763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // If qm must be preserved, then provide a (non-QTMP) temporary.
10773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Vsqrtqs(QRegister qd, QRegister qm, QRegister temp);
10783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Vdivqs(QRegister qd, QRegister qn, QRegister qm);
10793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
10803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void SmiTag(Register reg, Condition cond = AL) {
10813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    Lsl(reg, reg, Operand(kSmiTagSize), cond);
10823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
10833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
10843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void SmiTag(Register dst, Register src, Condition cond = AL) {
10853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    Lsl(dst, src, Operand(kSmiTagSize), cond);
10863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
10873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
10883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void SmiUntag(Register reg, Condition cond = AL) {
10893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    Asr(reg, reg, Operand(kSmiTagSize), cond);
10903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
10913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
10923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void SmiUntag(Register dst, Register src, Condition cond = AL) {
10933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    Asr(dst, src, Operand(kSmiTagSize), cond);
10943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
10953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
10963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Untag the value in the register assuming it is a smi.
10973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Untagging shifts tag bit into the carry flag - if carry is clear
10983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // assumption was correct. In this case jump to the is_smi label.
10993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Otherwise fall-through.
11003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void SmiUntag(Register dst, Register src, Label* is_smi) {
11013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    ASSERT(kSmiTagSize == 1);
11023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    Asrs(dst, src, Operand(kSmiTagSize));
11033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    b(is_smi, CC);
11043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
11053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void CheckCodePointer();
11073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Function frame setup and tear down.
11093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EnterFrame(RegList regs, intptr_t frame_space);
11103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LeaveFrame(RegList regs);
11113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Ret();
11123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void ReserveAlignedFrameSpace(intptr_t frame_space);
11133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Create a frame for calling into runtime that preserves all volatile
11153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // registers.  Frame's SP is guaranteed to be correctly aligned and
11163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // frame_space bytes are reserved under it.
11173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EnterCallRuntimeFrame(intptr_t frame_space);
11183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LeaveCallRuntimeFrame();
11193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count);
11213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Set up a Dart frame on entry with a frame pointer and PC information to
11233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // enable easy access to the RawInstruction object of code corresponding
11243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // to this frame.
11253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EnterDartFrame(intptr_t frame_size);
11263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LeaveDartFrame(RestorePP restore_pp = kRestoreCallerPP);
11273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Set up a Dart frame for a function compiled for on-stack replacement.
11293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // The frame layout is a normal Dart frame, but the frame is partially set
11303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // up on entry (it is the frame of the unoptimized code).
11313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EnterOsrFrame(intptr_t extra_size);
11323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Set up a stub frame so that the stack traversal code can easily identify
11343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // a stub frame.
11353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EnterStubFrame();
11363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LeaveStubFrame();
11373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // The register into which the allocation stats table is loaded with
11393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // LoadAllocationStatsAddress should be passed to
11403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // IncrementAllocationStats(WithSize) as stats_addr_reg to update the
11413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // allocation stats. These are separate assembler macros so we can
11423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // avoid a dependent load too nearby the load of the table address.
11433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadAllocationStatsAddress(Register dest,
11443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                  intptr_t cid,
11453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                  bool inline_isolate = true);
11463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void IncrementAllocationStats(Register stats_addr,
11473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                intptr_t cid,
11483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                Heap::Space space);
11493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void IncrementAllocationStatsWithSize(Register stats_addr_reg,
11503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                        Register size_reg,
11513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                        Heap::Space space);
11523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Address ElementAddressForIntIndex(bool is_load,
11543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                    bool is_external,
11553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                    intptr_t cid,
11563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                    intptr_t index_scale,
11573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                    Register array,
11583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                    intptr_t index,
11593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                    Register temp);
11603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Address ElementAddressForRegIndex(bool is_load,
11623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                    bool is_external,
11633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                    intptr_t cid,
11643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                    intptr_t index_scale,
11653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                    Register array,
11663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                    Register index);
11673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // If allocation tracing for |cid| is enabled, will jump to |trace| label,
11693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // which will allocate in the runtime where tracing occurs.
11703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void MaybeTraceAllocation(intptr_t cid,
11713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                            Register temp_reg,
11723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                            Label* trace,
11733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                            bool inline_isolate = true);
11743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Inlined allocation of an instance of class 'cls', code has no runtime
11763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // calls. Jump to 'failure' if the instance cannot be allocated here.
11773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Allocated instance is returned in 'instance_reg'.
11783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Only the tags field of the object is initialized.
11793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void TryAllocate(const Class& cls,
11803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                   Label* failure,
11813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                   Register instance_reg,
11823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                   Register temp_reg);
11833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void TryAllocateArray(intptr_t cid,
11853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        intptr_t instance_size,
11863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        Label* failure,
11873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        Register instance,
11883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        Register end_address,
11893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        Register temp1,
11903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        Register temp2);
11913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Emit data (e.g encoded instruction or immediate) in instruction stream.
11933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void Emit(int32_t value);
11943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
11953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // On some other platforms, we draw a distinction between safe and unsafe
11963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // smis.
11973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  static bool IsSafe(const Object& object) { return true; }
11983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  static bool IsSafeSmi(const Object& object) { return object.IsSmi(); }
11993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  bool constant_pool_allowed() const {
12013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    return constant_pool_allowed_;
12023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
12033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void set_constant_pool_allowed(bool b) {
12043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    constant_pool_allowed_ = b;
12053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  }
12063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf private:
12083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  AssemblerBuffer buffer_;  // Contains position independent code.
12093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  ObjectPoolWrapper object_pool_wrapper_;
12103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  int32_t prologue_offset_;
12123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  bool use_far_branches_;
12143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12157cb2db327e386372003cdb45e2c3acef774fb902Karl Schimpf#if 0
12163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // If you are thinking of using one or both of these instructions directly,
12173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // instead LoadImmediate should probably be used.
12187cb2db327e386372003cdb45e2c3acef774fb902Karl Schimpf  // Moved to ARM::AssemblerARM32::movw
12193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void movw(Register rd, uint16_t imm16, Condition cond = AL);
12207cb2db327e386372003cdb45e2c3acef774fb902Karl Schimpf  // Moved to ARM::AssemblerARM32::movt
12213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void movt(Register rd, uint16_t imm16, Condition cond = AL);
12227cb2db327e386372003cdb45e2c3acef774fb902Karl Schimpf#endif
12233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void BindARMv6(Label* label);
12253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void BindARMv7(Label* label);
12263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadWordFromPoolOffset(Register rd,
12283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                              int32_t offset,
12293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                              Register pp,
12303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                              Condition cond);
12313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void BranchLink(const ExternalLabel* label);
12333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  class CodeComment : public ZoneAllocated {
12353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf   public:
12363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    CodeComment(intptr_t pc_offset, const String& comment)
12373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf        : pc_offset_(pc_offset), comment_(comment) { }
12383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    intptr_t pc_offset() const { return pc_offset_; }
12403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    const String& comment() const { return comment_; }
12413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf   private:
12433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    intptr_t pc_offset_;
12443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    const String& comment_;
12453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf    DISALLOW_COPY_AND_ASSIGN(CodeComment);
12473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  };
12483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  GrowableArray<CodeComment*> comments_;
12503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  bool constant_pool_allowed_;
12523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void LoadObjectHelper(Register rd,
12543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        const Object& object,
12553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        Condition cond,
12563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        bool is_unique,
12573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        Register pp);
12583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
125985342a763f5381892ae19933db7250b8d7447b8cKarl Schimpf#if 0
1260745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf  // Moved to ARM32::AssemblerARM32::emitType01()
12613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitType01(Condition cond,
12623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  int type,
12633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  Opcode opcode,
12643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  int set_cc,
12653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  Register rn,
12663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  Register rd,
12673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  Operand o);
12683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
1269137e62bd843313d4b8697621989e0e6f5c2e7f81Karl Schimpf  // Moved to ARM32::AssemblerARM32::emitType05()
12703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitType5(Condition cond, int32_t offset, bool link);
12713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
1272745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf  // Moved to ARM32::AssemberARM32::emitMemOp()
12733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitMemOp(Condition cond,
12743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 bool load,
12753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 bool byte,
12763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 Register rd,
12773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 Address ad);
12783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12791956788f4459e0fedf91c10e8c266ca72a5d5fa1Karl Schimpf  // Moved to AssemblerARM32::emitMemOpEnc3();
12803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitMemOpAddressMode3(Condition cond,
12813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                             int32_t mode,
12823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                             Register rd,
12833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                             Address ad);
12843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12856cab56197153807395ff60d1d672b0098dd97a8aKarl Schimpf  // Moved to ARM32::AssemblerARM32::emitMultiMemOp()
12863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitMultiMemOp(Condition cond,
12873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      BlockAddressMode am,
12883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      bool load,
12893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      Register base,
12903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                      RegList regs);
12916cab56197153807395ff60d1d672b0098dd97a8aKarl Schimpf#endif
12923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitShiftImmediate(Condition cond,
12943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                          Shift opcode,
12953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                          Register rd,
12963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                          Register rm,
12973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                          Operand o);
12983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
12993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitShiftRegister(Condition cond,
13003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                         Shift opcode,
13013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                         Register rd,
13023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                         Register rm,
13033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                         Operand o);
13043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
1305396de5322ca78d9a2b313edec7f9d98ad66ad6b9Karl Schimpf#if 0
1306396de5322ca78d9a2b313edec7f9d98ad66ad6b9Karl Schimpf  // Moved to ARM32::AssemblerARM32::emitMulOp()
13073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitMulOp(Condition cond,
13083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 int32_t opcode,
13093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 Register rd,
13103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 Register rn,
13113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 Register rm,
13123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 Register rs);
13133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
13144acf11ac13716f5998b56cb65c1c72341276cc5fKarl Schimpf  // Moved to ARM32::AssemblerARM32::emitDivOp();
13153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitDivOp(Condition cond,
13163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 int32_t opcode,
13173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 Register rd,
13183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 Register rn,
13193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 Register rm);
1320697dc7966c9827f5cdac9f752351cb90e7bf00d5Karl Schimpf#endif
13213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
13223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitMultiVSMemOp(Condition cond,
13233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        BlockAddressMode am,
13243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        bool load,
13253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        Register base,
13263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        SRegister start,
13273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        uint32_t count);
13283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
13293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitMultiVDMemOp(Condition cond,
13303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        BlockAddressMode am,
13313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        bool load,
13323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        Register base,
13333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        DRegister start,
13343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                        int32_t count);
13353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
13364acf11ac13716f5998b56cb65c1c72341276cc5fKarl Schimpf#if 0
13374acf11ac13716f5998b56cb65c1c72341276cc5fKarl Schimpf  // Moved to ARM32::AssemblerARM32::emitVFPsss
13383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitVFPsss(Condition cond,
13393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  int32_t opcode,
13403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  SRegister sd,
13413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  SRegister sn,
13423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  SRegister sm);
13433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
13444acf11ac13716f5998b56cb65c1c72341276cc5fKarl Schimpf  // Moved to ARM32::AssemblerARM32::emitVFPddd
13453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitVFPddd(Condition cond,
13463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  int32_t opcode,
13473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  DRegister dd,
13483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  DRegister dn,
13493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                  DRegister dm);
13503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
13516c7181c5d3f082cbc04b58dd4745253139ad51e0Karl Schimpf  // Moved to ARM32::AssemblerARM32::emitVFPsd
13523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitVFPsd(Condition cond,
13533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 int32_t opcode,
13543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 SRegister sd,
13553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 DRegister dm);
13563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
13576c7181c5d3f082cbc04b58dd4745253139ad51e0Karl Schimpf  // Moved to ARM32::AssemblerARM32::emitVFPds
13583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitVFPds(Condition cond,
13593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 int32_t opcode,
13603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 DRegister dd,
13613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                 SRegister sm);
13623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
13632c0764e2da74e61b1ef1316980972e5177512a74Karl Schimpf  // Moved to ARM32::AssemblerARM32::emitSIMDqqq()
13643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitSIMDqqq(int32_t opcode, OperandSize sz,
13653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                   QRegister qd, QRegister qn, QRegister qm);
13662c0764e2da74e61b1ef1316980972e5177512a74Karl Schimpf#endif
13673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
13683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitSIMDddd(int32_t opcode, OperandSize sz,
13693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                   DRegister dd, DRegister dn, DRegister dm);
13703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
13713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void EmitFarBranch(Condition cond, int32_t offset, bool link);
1372137e62bd843313d4b8697621989e0e6f5c2e7f81Karl Schimpf#if 0
1373174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf  // Moved to ARM32::AssemblerARM32::emitBranch()
1374174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf  void EmitBranch(Condition cond, Label* label, bool link);
1375137e62bd843313d4b8697621989e0e6f5c2e7f81Karl Schimpf  // Moved to ARM32::AssemblerARM32::encodeBranchoffset().
13763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  int32_t EncodeBranchOffset(int32_t offset, int32_t inst);
1377137e62bd843313d4b8697621989e0e6f5c2e7f81Karl Schimpf  // Moved to ARM32::AssemberARM32::decodeBranchOffset().
13783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  static int32_t DecodeBranchOffset(int32_t inst);
1379137e62bd843313d4b8697621989e0e6f5c2e7f81Karl Schimpf#endif
13803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  int32_t EncodeTstOffset(int32_t offset, int32_t inst);
13813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  int32_t DecodeTstOffset(int32_t inst);
13823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
13833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void StoreIntoObjectFilter(Register object, Register value, Label* no_update);
13843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
13853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Shorter filtering sequence that assumes that value is not a smi.
13863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void StoreIntoObjectFilterNoSmi(Register object,
13873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                  Register value,
13883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                                  Label* no_update);
13893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
13903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Helpers for write-barrier verification.
13913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
13923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Returns VerifiedMemory::offset() as an Operand.
13933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  Operand GetVerifiedMemoryShadow();
13943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Writes value to [base + offset] and also its shadow location, if enabled.
13953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void WriteShadowedField(Register base,
13963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                          intptr_t offset,
13973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                          Register value,
13983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                          Condition cond = AL);
13993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void WriteShadowedFieldPair(Register base,
14003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                              intptr_t offset,
14013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                              Register value_even,
14023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                              Register value_odd,
14033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                              Condition cond = AL);
14043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // Writes new_value to address and its shadow location, if enabled, after
14053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  // verifying that its old value matches its shadow.
14063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  void VerifiedWrite(const Address& address,
14073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                     Register new_value,
14083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf                     FieldContent old_content);
14093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
1410bb0bacfda50db67da64e92ed2a79d590ec3cbcd1Karl Schimpf#if 0
1411bb0bacfda50db67da64e92ed2a79d590ec3cbcd1Karl Schimpf  // Added the following missing operations:
1412bb0bacfda50db67da64e92ed2a79d590ec3cbcd1Karl Schimpf  //
141318cce427c2297b64f54125c82e30522226df0f0eKarl Schimpf  // ARM32::AssemblerARM32::uxt() (uxtb and uxth)
1414a3c32146545c7c54c465606d5b5e71882ddb56e6Karl Schimpf  // ARM32::AssemblerARM32::vpop()
1415a3c32146545c7c54c465606d5b5e71882ddb56e6Karl Schimpf  // ARM32::AssemblerARM32::vpush()
1416397f602c4e4e5697806bf74e37a651ab78680628John Porto  // ARM32::AssemblerARM32::rbit()
1417397f602c4e4e5697806bf74e37a651ab78680628John Porto  // ARM32::AssemblerARM32::vbslq()
141818cce427c2297b64f54125c82e30522226df0f0eKarl Schimpf  // ARM32::AssemblerARM32::veord()
141918cce427c2297b64f54125c82e30522226df0f0eKarl Schimpf  // ARM32::AssemblerARM32::vld1qr()
1420397f602c4e4e5697806bf74e37a651ab78680628John Porto  // ARM32::AssemblerARM32::vshlqc
1421397f602c4e4e5697806bf74e37a651ab78680628John Porto  // ARM32::AssemblerARM32::vshrqic
1422397f602c4e4e5697806bf74e37a651ab78680628John Porto  // ARM32::AssemblerARM32::vshrquc
142318cce427c2297b64f54125c82e30522226df0f0eKarl Schimpf  // ARM32::AssemblerARM32::vst1qr()
14246de32b2199915462a4216399ff0f3af31ec88015Karl Schimpf  // ARM32::AssemblerARM32::vmorqi()
1425b627f0945fd64e05a1b373e5b6be4bc17e4482abKarl Schimpf  // ARM32::AssemblerARM32::vmovqc()
1426bb0bacfda50db67da64e92ed2a79d590ec3cbcd1Karl Schimpf#endif
1427bb0bacfda50db67da64e92ed2a79d590ec3cbcd1Karl Schimpf
14283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  DISALLOW_ALLOCATION();
14293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf  DISALLOW_COPY_AND_ASSIGN(Assembler);
14303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf};
14313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
14323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf}  // namespace dart
14333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf
14343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#endif  // VM_ASSEMBLER_ARM_H_
1435