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#include "vm/globals.h" // NOLINT 103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#if defined(TARGET_ARCH_ARM) 113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#include "vm/assembler.h" 133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#include "vm/cpu.h" 143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#include "vm/longjump.h" 153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#include "vm/runtime_entry.h" 163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#include "vm/simulator.h" 173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#include "vm/stack_frame.h" 183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#include "vm/stub_code.h" 193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// An extra check since we are assuming the existence of /proc/cpuinfo below. 213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) 223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#error ARM cross-compile only supported on Linux 233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#endif 243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfnamespace dart { 263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl SchimpfDECLARE_FLAG(bool, allow_absolute_addresses); 283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl SchimpfDEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); 293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl SchimpfDECLARE_FLAG(bool, inline_alloc); 303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 311956788f4459e0fedf91c10e8c266ca72a5d5fa1Karl Schimpf#if 0 321956788f4459e0fedf91c10e8c266ca72a5d5fa1Karl Schimpf// Moved to encodeImmRegOffsetEnc3 in IceAssemblerARM32.cpp 333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfuint32_t Address::encoding3() const { 343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (kind_ == Immediate) { 353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf uint32_t offset = encoding_ & kOffset12Mask; 363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(offset < 256); 373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return (encoding_ & ~kOffset12Mask) | B22 | 383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((offset & 0xf0) << 4) | (offset & 0xf); 393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(kind_ == IndexRegister); 413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return encoding_; 423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 431956788f4459e0fedf91c10e8c266ca72a5d5fa1Karl Schimpf#endif 443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfuint32_t Address::vencoding() const { 463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(kind_ == Immediate); 473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf uint32_t offset = encoding_ & kOffset12Mask; 483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(offset < (1 << 10)); // In the range 0 to +1020. 493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(Utils::IsAligned(offset, 4)); // Multiple of 4. 503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int mode = encoding_ & ((8|4|1) << 21); 513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((mode == Offset) || (mode == NegOffset)); 523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf uint32_t vencoding = (encoding_ & (0xf << kRnShift)) | (offset >> 2); 533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (mode == Offset) { 543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vencoding |= 1 << 23; 553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return vencoding; 573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { 613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(Utils::IsAligned(data, 4)); 623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(Utils::IsAligned(length, 4)); 633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uword end = data + length; 643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf while (data < end) { 653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf *reinterpret_cast<int32_t*>(data) = Instr::kBreakPointInstruction; 663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf data += 4; 673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Emit(int32_t value) { 723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AssemblerBuffer::EnsureCapacity ensured(&buffer_); 733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Emit<int32_t>(value); 743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 7685342a763f5381892ae19933db7250b8d7447b8cKarl Schimpf#if 0 77745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf// Moved to ARM32::AssemblerARM32::emitType01() 783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitType01(Condition cond, 793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int type, 803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Opcode opcode, 813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int set_cc, 823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rn, 833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rd, 843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand o) { 853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rd != kNoRegister); 863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf type << kTypeShift | 893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<int32_t>(opcode) << kOpcodeShift | 903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf set_cc << kSShift | 913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<int32_t>(rn) << kRnShift | 923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<int32_t>(rd) << kRdShift | 933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf o.encoding(); 943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 97e559be77b93bdfa5b0877455f012219aa426f10fKarl Schimpf// Moved to ARM32::AssemblerARM32::emitType05() 983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitType5(Condition cond, int32_t offset, bool link) { 993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 1003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 1013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5 << kTypeShift | 1023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (link ? 1 : 0) << kLinkShift; 1033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(Assembler::EncodeBranchOffset(offset, encoding)); 1043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 1053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 106745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf// Moved to ARM32::AssemblerARM32::emitMemOp() 1073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitMemOp(Condition cond, 1083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bool load, 1093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bool byte, 1103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rd, 1113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Address ad) { 1123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rd != kNoRegister); 1133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 1143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B26 | (ad.kind() == Address::Immediate ? 0 : B25) | 1163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (load ? L : 0) | 1173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (byte ? B : 0) | 1183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rd) << kRdShift) | 1193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ad.encoding(); 1203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 1213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 1223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1231956788f4459e0fedf91c10e8c266ca72a5d5fa1Karl Schimpf// Moved to AssemblerARM32::emitMemOpEnc3(); 1243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitMemOpAddressMode3(Condition cond, 1253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t mode, 1263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rd, 1273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Address ad) { 1283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rd != kNoRegister); 1293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 1303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mode | 1323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rd) << kRdShift) | 1333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ad.encoding3(); 1343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 1353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 1363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1376cab56197153807395ff60d1d672b0098dd97a8aKarl Schimpf// Moved to ARM32::AssemblerARM32::emitMuliMemOp() 1383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitMultiMemOp(Condition cond, 1393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf BlockAddressMode am, 1403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bool load, 1413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register base, 1423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf RegList regs) { 1433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != kNoRegister); 1443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 1453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | 1473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf am | 1483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (load ? L : 0) | 1493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(base) << kRnShift) | 1503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf regs; 1513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 1523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 1536cab56197153807395ff60d1d672b0098dd97a8aKarl Schimpf#endif 1543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitShiftImmediate(Condition cond, 1563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Shift opcode, 1573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rd, 1583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rm, 1593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand o) { 1603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 1613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(o.type() == 1); 1623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 1633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<int32_t>(MOV) << kOpcodeShift | 1643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<int32_t>(rd) << kRdShift | 1653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf o.encoding() << kShiftImmShift | 1663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<int32_t>(opcode) << kShiftShift | 1673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<int32_t>(rm); 1683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 1693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 1703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitShiftRegister(Condition cond, 1733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Shift opcode, 1743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rd, 1753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rm, 1763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand o) { 1773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 1783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(o.type() == 0); 1793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 1803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<int32_t>(MOV) << kOpcodeShift | 1813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<int32_t>(rd) << kRdShift | 1823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf o.encoding() << kShiftRegisterShift | 1833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<int32_t>(opcode) << kShiftShift | 1843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B4 | 1853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<int32_t>(rm); 1863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 1873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 1883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 190c33f7bbd4160a88aa95f81876b54e90edf982ca3Karl Schimpf#if 0 191c33f7bbd4160a88aa95f81876b54e90edf982ca3Karl Schimpf// Moved to ARM32::AssemblerARM32::and_() 1923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::and_(Register rd, Register rn, Operand o, Condition cond) { 1933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), AND, 0, rn, rd, o); 1943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 1953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 19662d367bdc5f04368566e6e67f4f1b801a225b14dKarl Schimpf// Moved to ARM32::AssemberARM32::eor() 1973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::eor(Register rd, Register rn, Operand o, Condition cond) { 1983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), EOR, 0, rn, rd, o); 1993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 201745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf// Moved to ARM32::AssemberARM32::sub() 2023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::sub(Register rd, Register rn, Operand o, Condition cond) { 2033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), SUB, 0, rn, rd, o); 2043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 206dca86741c89dbcb3fa7b77e9124a5985f04ee2d7Karl Schimpf// Moved to ARM32::AssemberARM32::rsb() 2073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::rsb(Register rd, Register rn, Operand o, Condition cond) { 2083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), RSB, 0, rn, rd, o); 2093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 211dca86741c89dbcb3fa7b77e9124a5985f04ee2d7Karl Schimpf// Moved to ARM32::AssemberARM32::rsb() 2123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::rsbs(Register rd, Register rn, Operand o, Condition cond) { 2133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), RSB, 1, rn, rd, o); 2143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 216745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf// Moved to ARM32::AssemberARM32::add() 2173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::add(Register rd, Register rn, Operand o, Condition cond) { 2183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), ADD, 0, rn, rd, o); 2193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 221745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf// Moved to ARM32::AssemberARM32::add() 2223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::adds(Register rd, Register rn, Operand o, Condition cond) { 2233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), ADD, 1, rn, rd, o); 2243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 226745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf// Moved to ARM32::AssemberARM32::sub() 2273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::subs(Register rd, Register rn, Operand o, Condition cond) { 2283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), SUB, 1, rn, rd, o); 2293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 231db0988808f99ee4895ea80c3e5c1b812e3d09e5bKarl Schimpf// Moved to ARM32::AssemberARM32::adc() 2323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::adc(Register rd, Register rn, Operand o, Condition cond) { 2333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), ADC, 0, rn, rd, o); 2343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 236db0988808f99ee4895ea80c3e5c1b812e3d09e5bKarl Schimpf// Moved to ARM32::AssemberARM32::adc() 2373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::adcs(Register rd, Register rn, Operand o, Condition cond) { 2383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), ADC, 1, rn, rd, o); 2393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 240db0988808f99ee4895ea80c3e5c1b812e3d09e5bKarl Schimpf#endif 2413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::sbc(Register rd, Register rn, Operand o, Condition cond) { 2433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), SBC, 0, rn, rd, o); 2443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::sbcs(Register rd, Register rn, Operand o, Condition cond) { 2483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), SBC, 1, rn, rd, o); 2493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 251337ac9e775203b2449d7020931dc58f29d55cd44Karl Schimpf#if 0 252337ac9e775203b2449d7020931dc58f29d55cd44Karl Schimpf// Moved to ARM32::AssemblerARM32::rsc()f 2533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::rsc(Register rd, Register rn, Operand o, Condition cond) { 2543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), RSC, 0, rn, rd, o); 2553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 257b81b90150e980671bc51e72c928ed0bad75bcd6aKarl Schimpf// Moved to ARM32::AssemblerARM32::tst() 2583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::tst(Register rn, Operand o, Condition cond) { 2593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), TST, 1, rn, R0, o); 2603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 261b81b90150e980671bc51e72c928ed0bad75bcd6aKarl Schimpf#endif 2623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::teq(Register rn, Operand o, Condition cond) { 2643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), TEQ, 1, rn, R0, o); 2653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 267f8fc12f741cdbffaf82005d4f1324dc316d9d6dfKarl Schimpf#if 0 268f8fc12f741cdbffaf82005d4f1324dc316d9d6dfKarl Schimpf// Moved to ARM32::AssemblerARM32::cmp() 2693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::cmp(Register rn, Operand o, Condition cond) { 2703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), CMP, 1, rn, R0, o); 2713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2734c435d328c90e128543733b54e27bfca2195e54dKarl Schimpf// Moved to ARM32::AssemblerARM32::cmn() 2743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::cmn(Register rn, Operand o, Condition cond) { 2753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), CMN, 1, rn, R0, o); 2763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2789c08bee818e14fa266d7f13c829f6f4d2eb81485Karl Schimpf// Moved to ARM32::AssemberARM32::orr() 2793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::orr(Register rd, Register rn, Operand o, Condition cond) { 2803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), ORR, 0, rn, rd, o); 2813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2839c08bee818e14fa266d7f13c829f6f4d2eb81485Karl Schimpf// Moved to ARM32::AssemberARM32::orr() 2843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::orrs(Register rd, Register rn, Operand o, Condition cond) { 2853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), ORR, 1, rn, rd, o); 2863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 288697dc7966c9827f5cdac9f752351cb90e7bf00d5Karl Schimpf// Moved to ARM32::AssemblerARM32::mov() 28985342a763f5381892ae19933db7250b8d7447b8cKarl Schimpf// TODO(kschimpf) other forms of move. 2903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::mov(Register rd, Operand o, Condition cond) { 2913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), MOV, 0, R0, rd, o); 2923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 29385342a763f5381892ae19933db7250b8d7447b8cKarl Schimpf#endif 2943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::movs(Register rd, Operand o, Condition cond) { 2963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), MOV, 1, R0, rd, o); 2973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 3004f8805b70917bf0de9ba277a0af2d6f1d582be52Karl Schimpf#if 0 301e559be77b93bdfa5b0877455f012219aa426f10fKarl Schimpf// Moved to ARM32::AssemblerARM32::bic() 3023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::bic(Register rd, Register rn, Operand o, Condition cond) { 3033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), BIC, 0, rn, rd, o); 3043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 3053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 306e559be77b93bdfa5b0877455f012219aa426f10fKarl Schimpf// Moved to ARM32::AssemblerARM32::bic() 3073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::bics(Register rd, Register rn, Operand o, Condition cond) { 3083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), BIC, 1, rn, rd, o); 3093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 3103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 311e559be77b93bdfa5b0877455f012219aa426f10fKarl Schimpf// Moved to ARM32::AssemblerARM32::mvn() 3123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::mvn(Register rd, Operand o, Condition cond) { 3133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), MVN, 0, R0, rd, o); 3143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 3153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 316e559be77b93bdfa5b0877455f012219aa426f10fKarl Schimpf// Moved to ARM32::AssemblerARM32::mvn() 3173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::mvns(Register rd, Operand o, Condition cond) { 3183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(cond, o.type(), MVN, 1, R0, rd, o); 3193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 3203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32165f80d72389d036abaa3714ca18d95bf59ebb1faKarl Schimpf// Moved to ARM32::AssemblerARM32::clz() 3223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::clz(Register rd, Register rm, Condition cond) { 3233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rd != kNoRegister); 3243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rm != kNoRegister); 3253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 3263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rd != PC); 3273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rm != PC); 3283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 3293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B24 | B22 | B21 | (0xf << 16) | 3303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rd) << kRdShift) | 3313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (0xf << 8) | B4 | static_cast<int32_t>(rm); 3323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 3333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 3343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 335e559be77b93bdfa5b0877455f012219aa426f10fKarl Schimpf// Moved to ARM32::AssemblerARM32::movw() 3363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::movw(Register rd, uint16_t imm16, Condition cond) { 3373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 3383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 3393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B25 | B24 | ((imm16 >> 12) << 16) | 3403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); 3413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 3423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 3433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 3443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 345e559be77b93bdfa5b0877455f012219aa426f10fKarl Schimpf// Moved to ARM32::AssemblerARM32::movt() 3463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::movt(Register rd, uint16_t imm16, Condition cond) { 3473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 3483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 3493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B25 | B24 | B22 | ((imm16 >> 12) << 16) | 3503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); 3513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 3523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 3533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 354e559be77b93bdfa5b0877455f012219aa426f10fKarl Schimpf// Moved to ARM32::AssemblerARM32::emitMulOp() 3553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitMulOp(Condition cond, int32_t opcode, 3563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rd, Register rn, 3573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rm, Register rs) { 3583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rd != kNoRegister); 3593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rn != kNoRegister); 3603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rm != kNoRegister); 3613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rs != kNoRegister); 3623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 3633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = opcode | 3643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(cond) << kConditionShift) | 3653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rn) << kRnShift) | 3663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rd) << kRdShift) | 3673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rs) << kRsShift) | 3683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B7 | B4 | 3693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rm) << kRmShift); 3703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 3713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 3723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 373e559be77b93bdfa5b0877455f012219aa426f10fKarl Schimpf// Moved to ARM32::AssemblerARM32::mul() 3743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::mul(Register rd, Register rn, Register rm, Condition cond) { 3753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 3763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMulOp(cond, 0, R0, rd, rn, rm); 3773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 378396de5322ca78d9a2b313edec7f9d98ad66ad6b9Karl Schimpf#endif 3793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 3803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// Like mul, but sets condition flags. 3813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::muls(Register rd, Register rn, Register rm, Condition cond) { 3823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMulOp(cond, B20, R0, rd, rn, rm); 3833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 3843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 385080b65b5e73b17d39d1f08b84af3c075b3e46e77Karl Schimpf#if 0 386430e84471a54f6e5a1727054be28680e489cf28dKarl Schimpf// Moved to ARM32::AssemblerARM32::mla() 3873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::mla(Register rd, Register rn, 3883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rm, Register ra, Condition cond) { 3893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // rd <- ra + rn * rm. 3903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 3913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMulOp(cond, B21, ra, rd, rn, rm); 3923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 3933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 394a990f0c58921d886976e409e170f6c8ee40e9a23Karl Schimpf// Moved to ARM32::AssemblerARM32::mla() 3953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::mls(Register rd, Register rn, 3963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rm, Register ra, Condition cond) { 3973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // rd <- ra - rn * rm. 3983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (TargetCPUFeatures::arm_version() == ARMv7) { 3993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 4003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMulOp(cond, B22 | B21, ra, rd, rn, rm); 4013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 4023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mul(IP, rn, rm, cond); 4033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf sub(rd, ra, Operand(IP), cond); 4043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 4053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 406a990f0c58921d886976e409e170f6c8ee40e9a23Karl Schimpf#endif 4073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 4083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::smull(Register rd_lo, Register rd_hi, 4093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rn, Register rm, Condition cond) { 4103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 4113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMulOp(cond, B23 | B22, rd_lo, rd_hi, rn, rm); 4123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 4133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 414430e84471a54f6e5a1727054be28680e489cf28dKarl Schimpf#if 0 415430e84471a54f6e5a1727054be28680e489cf28dKarl Schimpf// Moved to ARM32::AssemblerARM32::umull() 4163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::umull(Register rd_lo, Register rd_hi, 4173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rn, Register rm, Condition cond) { 4183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 4193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm); 4203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 421430e84471a54f6e5a1727054be28680e489cf28dKarl Schimpf#endif 4223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 4233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::umlal(Register rd_lo, Register rd_hi, 4243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rn, Register rm, Condition cond) { 4253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 4263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMulOp(cond, B23 | B21, rd_lo, rd_hi, rn, rm); 4273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 4283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 4293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 4303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::umaal(Register rd_lo, Register rd_hi, 4313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rn, Register rm) { 4323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rd_lo != IP); 4333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rd_hi != IP); 4343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rn != IP); 4353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rm != IP); 4363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (TargetCPUFeatures::arm_version() != ARMv5TE) { 4373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 4383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMulOp(AL, B22, rd_lo, rd_hi, rn, rm); 4393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 4403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(IP, Operand(0)); 4413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf umlal(rd_lo, IP, rn, rm); 4423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf adds(rd_lo, rd_lo, Operand(rd_hi)); 4433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf adc(rd_hi, IP, Operand(0)); 4443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 4453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 4463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 4473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 448697dc7966c9827f5cdac9f752351cb90e7bf00d5Karl Schimpf#if 0 449697dc7966c9827f5cdac9f752351cb90e7bf00d5Karl Schimpf// Moved to ARM32::AssemblerARM32::emitDivOp() 4503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitDivOp(Condition cond, int32_t opcode, 4513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rd, Register rn, Register rm) { 4523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::integer_division_supported()); 4533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rd != kNoRegister); 4543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rn != kNoRegister); 4553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rm != kNoRegister); 4563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 4573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = opcode | 4583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(cond) << kConditionShift) | 4593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rn) << kDivRnShift) | 4603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rd) << kDivRdShift) | 461697dc7966c9827f5cdac9f752351cb90e7bf00d5Karl Schimpf // TODO(kschimpf): Why not also: B15 | B14 | B13 | B12? 4623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B26 | B25 | B24 | B20 | B4 | 4633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rm) << kDivRmShift); 4643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 4653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 4663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 467697dc7966c9827f5cdac9f752351cb90e7bf00d5Karl Schimpf// Moved to ARM32::AssemblerARM32::sdiv() 4683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) { 4693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitDivOp(cond, 0, rd, rn, rm); 4703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 4713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 4721c28550f76d2da45def3b4bf43732c8d30b8c9f8Karl Schimpf// Moved to ARM32::AssemblerARM32::udiv() 4733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) { 4743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitDivOp(cond, B21 , rd, rn, rm); 4753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 4763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 477745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf// Moved to ARM32::AssemblerARM32::ldr() 4783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::ldr(Register rd, Address ad, Condition cond) { 4793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMemOp(cond, true, false, rd, ad); 4803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 4813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 482745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf// Moved to ARM32::AssemblerARM32::str() 4833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::str(Register rd, Address ad, Condition cond) { 4843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMemOp(cond, false, false, rd, ad); 4853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 4863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 487745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf// Moved to ARM32::AssemblerARM32::ldr() 4883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::ldrb(Register rd, Address ad, Condition cond) { 4893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMemOp(cond, true, true, rd, ad); 4903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 4913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 492745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf// Moved to ARM32::AssemblerARM32::str() 4933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::strb(Register rd, Address ad, Condition cond) { 4943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMemOp(cond, false, true, rd, ad); 4953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 496745ad1d8d1c830e52eb3c80ff4b82fdfaf7173abKarl Schimpf#endif 4973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 4983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::ldrh(Register rd, Address ad, Condition cond) { 4993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad); 5003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 5013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::strh(Register rd, Address ad, Condition cond) { 5043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad); 5053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 5063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::ldrsb(Register rd, Address ad, Condition cond) { 5093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad); 5103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 5113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::ldrsh(Register rd, Address ad, Condition cond) { 5143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad); 5153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 5163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::ldrd(Register rd, Register rn, int32_t offset, Condition cond) { 5193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((rd % 2) == 0); 5203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (TargetCPUFeatures::arm_version() == ARMv5TE) { 5213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Register rd2 = static_cast<Register>(static_cast<int32_t>(rd) + 1); 5223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(rd, Address(rn, offset), cond); 5233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(rd2, Address(rn, offset + kWordSize), cond); 5243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 5253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, Address(rn, offset)); 5263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 5273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 5283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::strd(Register rd, Register rn, int32_t offset, Condition cond) { 5313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((rd % 2) == 0); 5323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (TargetCPUFeatures::arm_version() == ARMv5TE) { 5333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Register rd2 = static_cast<Register>(static_cast<int32_t>(rd) + 1); 5343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(rd, Address(rn, offset), cond); 5353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(rd2, Address(rn, offset + kWordSize), cond); 5363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 5373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, Address(rn, offset)); 5383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 5393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 5403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 541f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf#if 0 542f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf// Folded into ARM32::AssemblerARM32::popList(), since it is its only 543f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf// use (and doesn't implement ARM STM instruction). 5443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::ldm(BlockAddressMode am, Register base, RegList regs, 5453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 5463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(regs != 0); 5473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMultiMemOp(cond, am, true, base, regs); 5483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 5493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5506cab56197153807395ff60d1d672b0098dd97a8aKarl Schimpf// Folded into ARM32::AssemblerARM32::pushList(), since it is its only 5516cab56197153807395ff60d1d672b0098dd97a8aKarl Schimpf// use (and doesn't implement ARM STM instruction). 5523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::stm(BlockAddressMode am, Register base, RegList regs, 5533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 5543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(regs != 0); 5553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMultiMemOp(cond, am, false, base, regs); 5563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 5573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5584175d45e14cf1eb0af11e0458a873e601dc395deKarl Schimpf// Moved to ARM::AssemblerARM32::ldrex(); 5593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::ldrex(Register rt, Register rn, Condition cond) { 5603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE); 5613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rn != kNoRegister); 5623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != kNoRegister); 5633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 5643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 5653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B24 | 5663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B23 | 5673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf L | 5683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rn) << kLdExRnShift) | 5693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rt) << kLdExRtShift) | 5703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0; 5713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 5723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 5733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5744175d45e14cf1eb0af11e0458a873e601dc395deKarl Schimpf// Moved to ARM::AssemblerARM32::strex(); 5753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::strex(Register rd, Register rt, Register rn, Condition cond) { 5763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE); 5773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rn != kNoRegister); 5783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rd != kNoRegister); 5793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != kNoRegister); 5803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 5813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 5823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B24 | 5833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B23 | 5843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rn) << kStrExRnShift) | 5853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rd) << kStrExRdShift) | 5863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B11 | B10 | B9 | B8 | B7 | B4 | 5873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rt) << kStrExRtShift); 5883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 5893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 5904175d45e14cf1eb0af11e0458a873e601dc395deKarl Schimpf#endif 5913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 5923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::clrex() { 5933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::arm_version() != ARMv5TE); 5943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (kSpecialCondition << kConditionShift) | 5953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf; 5963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 5973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 5983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 59967574d83d05f5bde748843a73adcab6247736601Karl Schimpf#if 0 60067574d83d05f5bde748843a73adcab6247736601Karl Schimpf// Moved to ARM32::AssemblerARM32::nop(). 6013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::nop(Condition cond) { 6023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 6033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 6043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B25 | B24 | B21 | (0xf << 12); 6053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 6063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 6073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 6084ff90be3620f73ddb41d062848325b22a6a0ac0eKarl Schimpf// Moved to ARM32::AssemblerARM32::vmovsr(). 6093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmovsr(SRegister sn, Register rt, Condition cond) { 6103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 6113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(sn != kNoSRegister); 6123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != kNoRegister); 6133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != SP); 6143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != PC); 6153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 6163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 6173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B25 | 6183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sn) >> 1)*B16) | 6193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rt)*B12) | B11 | B9 | 6203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sn) & 1)*B7) | B4; 6213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 6223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 6233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 624e1b6574f23b67c92fe367128b6597d54c55e88fbKarl Schimpf// Moved to ARM32::AssemblerARM32::vmovrs(). 6253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmovrs(Register rt, SRegister sn, Condition cond) { 6263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 6273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(sn != kNoSRegister); 6283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != kNoRegister); 6293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != SP); 6303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != PC); 6313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 6323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 6333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B25 | B20 | 6343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sn) >> 1)*B16) | 6353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rt)*B12) | B11 | B9 | 6363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sn) & 1)*B7) | B4; 6373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 6383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 639e1b6574f23b67c92fe367128b6597d54c55e88fbKarl Schimpf#endif 6403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 6413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 6423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmovsrr(SRegister sm, Register rt, Register rt2, 6433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 6443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 6453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(sm != kNoSRegister); 6463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(sm != S31); 6473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != kNoRegister); 6483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != SP); 6493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != PC); 6503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt2 != kNoRegister); 6513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt2 != SP); 6523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt2 != PC); 6533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 6543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 6553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B22 | 6563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rt2)*B16) | 6573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rt)*B12) | B11 | B9 | 6583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sm) & 1)*B5) | B4 | 6593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(sm) >> 1); 6603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 6613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 6623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 6633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 6643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmovrrs(Register rt, Register rt2, SRegister sm, 6653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 6663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 6673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(sm != kNoSRegister); 6683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(sm != S31); 6693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != kNoRegister); 6703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != SP); 6713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != PC); 6723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt2 != kNoRegister); 6733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt2 != SP); 6743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt2 != PC); 6753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != rt2); 6763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 6773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 6783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B22 | B20 | 6793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rt2)*B16) | 6803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rt)*B12) | B11 | B9 | 6813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sm) & 1)*B5) | B4 | 6823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(sm) >> 1); 6833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 6843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 6853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 6866de32b2199915462a4216399ff0f3af31ec88015Karl Schimpf#if 0 6876de32b2199915462a4216399ff0f3af31ec88015Karl Schimpf// Moved to ARM32::AssemblerARM32::vmovdqir(). 6883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmovdr(DRegister dn, int i, Register rt, Condition cond) { 6893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 6903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((i == 0) || (i == 1)); 6913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != kNoRegister); 6923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != SP); 6933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != PC); 6943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(dn != kNoDRegister); 6953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 6963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 6973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B25 | 6983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (i*B21) | 6993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 7003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dn) >> 4)*B7) | 7013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dn) & 0xf)*B16) | B4; 7023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 7033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 7043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 705a880ac8fcb772331ae7e27712e4da797c6927caaKarl Schimpf// Moved to ARM32::AssemblerARM32::vmovdrr(). 7063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmovdrr(DRegister dm, Register rt, Register rt2, 7073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 7083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 7093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(dm != kNoDRegister); 7103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != kNoRegister); 7113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != SP); 7123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != PC); 7133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt2 != kNoRegister); 7143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt2 != SP); 7153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt2 != PC); 7163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 7173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 7183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B22 | 7193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rt2)*B16) | 7203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 7213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dm) >> 4)*B5) | B4 | 7223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(dm) & 0xf); 7233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 7243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 7253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 726a880ac8fcb772331ae7e27712e4da797c6927caaKarl Schimpf// Moved to ARM32::AssemblerARM32::vmovrrd(). 7273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmovrrd(Register rt, Register rt2, DRegister dm, 7283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 7293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 7303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(dm != kNoDRegister); 7313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != kNoRegister); 7323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != SP); 7333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != PC); 7343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt2 != kNoRegister); 7353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt2 != SP); 7363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt2 != PC); 7373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rt != rt2); 7383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 7393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 7403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B22 | B20 | 7413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rt2)*B16) | 7423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 7433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dm) >> 4)*B5) | B4 | 7443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(dm) & 0xf); 7453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 7463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 7473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 748e1d71380ff9de84268c3865a89d16519385cef4aKarl Schimpf// Moved to ARM32::AssemblerARM32::vldrs() 7493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vldrs(SRegister sd, Address ad, Condition cond) { 7503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 7513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(sd != kNoSRegister); 7523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 7533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 7543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B24 | B20 | 7553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sd) & 1)*B22) | 7563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sd) >> 1)*B12) | 7573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B11 | B9 | ad.vencoding(); 7583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 7593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 7603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 7614a55a602331f96c91be1697db4b27859ac58a270Karl Schimpf// Moved to Arm32::AssemblerARM32::vstrs() 7623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vstrs(SRegister sd, Address ad, Condition cond) { 7633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 7643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)) != PC); 7653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(sd != kNoSRegister); 7663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 7673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 7683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B24 | 7693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sd) & 1)*B22) | 7703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sd) >> 1)*B12) | 7713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B11 | B9 | ad.vencoding(); 7723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 7733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 7743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 7753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vldrd(DRegister dd, Address ad, Condition cond) { 7763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 7773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(dd != kNoDRegister); 7783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 7793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 7803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B24 | B20 | 7813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dd) >> 4)*B22) | 7823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dd) & 0xf)*B12) | 7833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B11 | B9 | B8 | ad.vencoding(); 7843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 7853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 786e1d71380ff9de84268c3865a89d16519385cef4aKarl Schimpf#endif 7873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 7883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vstrd(DRegister dd, Address ad, Condition cond) { 7893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 7903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)) != PC); 7913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(dd != kNoDRegister); 7923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 7933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 7943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B24 | 7953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dd) >> 4)*B22) | 7963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dd) & 0xf)*B12) | 7973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B11 | B9 | B8 | ad.vencoding(); 7983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 7993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 8003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 8013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitMultiVSMemOp(Condition cond, 8023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf BlockAddressMode am, 8033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bool load, 8043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register base, 8053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf SRegister start, 8063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf uint32_t count) { 8073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 8083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != kNoRegister); 8093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 8103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(start != kNoSRegister); 8113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(static_cast<int32_t>(start) + count <= kNumberOfSRegisters); 8123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 8133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 8143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B11 | B9 | 8153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf am | 8163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (load ? L : 0) | 8173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(base) << kRnShift) | 8183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(start) & 0x1) ? D : 0) | 8193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(start) >> 1) << 12) | 8203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf count; 8213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 8223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 8233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 8243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 8253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitMultiVDMemOp(Condition cond, 8263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf BlockAddressMode am, 8273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bool load, 8283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register base, 8293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf DRegister start, 8303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t count) { 8313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 8323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != kNoRegister); 8333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 8343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(start != kNoDRegister); 8353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(static_cast<int32_t>(start) + count <= kNumberOfDRegisters); 8363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int armv5te = TargetCPUFeatures::arm_version() == ARMv5TE ? 1 : 0; 8373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 8383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 8393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B11 | B9 | B8 | 8403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf am | 8413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (load ? L : 0) | 8423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(base) << kRnShift) | 8433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(start) & 0x10) ? D : 0) | 8443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(start) & 0xf) << 12) | 8453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (count << 1) | armv5te; 8463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 8473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 8483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 8493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 8503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vldms(BlockAddressMode am, Register base, 8513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf SRegister first, SRegister last, Condition cond) { 8523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((am == IA) || (am == IA_W) || (am == DB_W)); 8533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(last > first); 8543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMultiVSMemOp(cond, am, true, base, first, last - first + 1); 8553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 8563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 8573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 8583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vstms(BlockAddressMode am, Register base, 8593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf SRegister first, SRegister last, Condition cond) { 8603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((am == IA) || (am == IA_W) || (am == DB_W)); 8613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(last > first); 8623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMultiVSMemOp(cond, am, false, base, first, last - first + 1); 8633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 8643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 8653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 8663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vldmd(BlockAddressMode am, Register base, 8673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf DRegister first, intptr_t count, Condition cond) { 8683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((am == IA) || (am == IA_W) || (am == DB_W)); 8693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(count <= 16); 8703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(first + count <= kNumberOfDRegisters); 8713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMultiVDMemOp(cond, am, true, base, first, count); 8723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 8733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 8743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 8753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vstmd(BlockAddressMode am, Register base, 8763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf DRegister first, intptr_t count, Condition cond) { 8773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((am == IA) || (am == IA_W) || (am == DB_W)); 8783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(count <= 16); 8793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(first + count <= kNumberOfDRegisters); 8803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitMultiVDMemOp(cond, am, false, base, first, count); 8813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 8823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 8834acf11ac13716f5998b56cb65c1c72341276cc5fKarl Schimpf#if 0 8844acf11ac13716f5998b56cb65c1c72341276cc5fKarl Schimpf// Moved to ARM32::AssemblerARM32::emitVFPsss 8853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitVFPsss(Condition cond, int32_t opcode, 8863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf SRegister sd, SRegister sn, SRegister sm) { 8873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 8883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(sd != kNoSRegister); 8893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(sn != kNoSRegister); 8903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(sm != kNoSRegister); 8913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 8923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 8933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B25 | B11 | B9 | opcode | 8943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sd) & 1)*B22) | 8953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sn) >> 1)*B16) | 8963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sd) >> 1)*B12) | 8973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sn) & 1)*B7) | 8983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sm) & 1)*B5) | 8993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(sm) >> 1); 9003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 9013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 9023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 9034acf11ac13716f5998b56cb65c1c72341276cc5fKarl Schimpf// Moved to ARM32::AssemblerARM32::emitVFPddd 9043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitVFPddd(Condition cond, int32_t opcode, 9053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf DRegister dd, DRegister dn, DRegister dm) { 9063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 9073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(dd != kNoDRegister); 9083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(dn != kNoDRegister); 9093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(dm != kNoDRegister); 9103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 9113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 9123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B25 | B11 | B9 | B8 | opcode | 9133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dd) >> 4)*B22) | 9143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dn) & 0xf)*B16) | 9153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dd) & 0xf)*B12) | 9163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dn) >> 4)*B7) | 9173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dm) >> 4)*B5) | 9183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(dm) & 0xf); 9193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 9203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 9213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 9229aedc2e90f2220f7811ef8690a8b0fd59a4d7784Karl Schimpf// Moved to Arm32::AssemblerARM32::vmovss() 9233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) { 9243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm); 9253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 9263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 9279aedc2e90f2220f7811ef8690a8b0fd59a4d7784Karl Schimpf// Moved to Arm32::AssemblerARM32::vmovdd() 9283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) { 9293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm); 9303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 9313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 932c64448fbaf1dca1495a55e6c085555ca637e3e74Karl Schimpf// Moved to Arm32::AssemblerARM32::vmovs() 9333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfbool Assembler::vmovs(SRegister sd, float s_imm, Condition cond) { 9343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (TargetCPUFeatures::arm_version() != ARMv7) { 9353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return false; 9363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 9373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf uint32_t imm32 = bit_cast<uint32_t, float>(s_imm); 9383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (((imm32 & ((1 << 19) - 1)) == 0) && 9393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) || 9403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) { 9413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) | 9423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((imm32 >> 19) & ((1 << 6) -1)); 9433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf), 9443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf sd, S0, S0); 9453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return true; 9463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 9473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return false; 9483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 9493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 950c64448fbaf1dca1495a55e6c085555ca637e3e74Karl Schimpf// Moved to Arm32::AssemblerARM32::vmovd() 9513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfbool Assembler::vmovd(DRegister dd, double d_imm, Condition cond) { 9523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (TargetCPUFeatures::arm_version() != ARMv7) { 9533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return false; 9543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 9553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf uint64_t imm64 = bit_cast<uint64_t, double>(d_imm); 9563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (((imm64 & ((1LL << 48) - 1)) == 0) && 9573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) || 9583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) { 9593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) | 9603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((imm64 >> 48) & ((1 << 6) -1)); 9613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf), 9623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf dd, D0, D0); 9633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return true; 9643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 9653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return false; 9663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 9673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 9684acf11ac13716f5998b56cb65c1c72341276cc5fKarl Schimpf// Moved to Arm32::AssemblerARM32::vadds() 9693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vadds(SRegister sd, SRegister sn, SRegister sm, 9703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 9713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B21 | B20, sd, sn, sm); 9723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 9733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 9744acf11ac13716f5998b56cb65c1c72341276cc5fKarl Schimpf// Moved to Arm32::AssemblerARM32::vaddd() 9753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm, 9763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 9773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPddd(cond, B21 | B20, dd, dn, dm); 9783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 9793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 980bd8e28e3b02fc830c37a94acfdd9e5585a7a2ab2Karl Schimpf// Moved to Arm32::AssemblerARM32::vsubs() 9813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm, 9823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 9833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm); 9843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 9853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 986bd8e28e3b02fc830c37a94acfdd9e5585a7a2ab2Karl Schimpf// Moved to Arm32::AssemblerARM32::vsubd() 9873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm, 9883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 9893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm); 9903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 9913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 992bd8e28e3b02fc830c37a94acfdd9e5585a7a2ab2Karl Schimpf// Moved to Arm32::AssemblerARM32::vmuls() 9933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm, 9943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 9953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B21, sd, sn, sm); 9963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 9973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 998bd8e28e3b02fc830c37a94acfdd9e5585a7a2ab2Karl Schimpf// Moved to Arm32::AssemblerARM32::vmuld() 9993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm, 10003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 10013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPddd(cond, B21, dd, dn, dm); 10023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 10033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1004bd8e28e3b02fc830c37a94acfdd9e5585a7a2ab2Karl Schimpf// Moved to Arm32::AssemblerARM32::vmlas() 10053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm, 10063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 10073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, 0, sd, sn, sm); 10083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 10093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1010bd8e28e3b02fc830c37a94acfdd9e5585a7a2ab2Karl Schimpf// Moved to Arm32::AssemblerARM32::vmlad() 10113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm, 10123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 10133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPddd(cond, 0, dd, dn, dm); 10143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 10153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1016694cdbd8020f97334c24ad5cd39cf1d8b0b2868bKarl Schimpf// Moved to Arm32::AssemblerARM32::vmlss() 10173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm, 10183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 10193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B6, sd, sn, sm); 10203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 10213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1022694cdbd8020f97334c24ad5cd39cf1d8b0b2868bKarl Schimpf// Moved to Arm32::AssemblerARM32::vmlsd() 10233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm, 10243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 10253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPddd(cond, B6, dd, dn, dm); 10263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 10273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 10283dbe780686601ac6ed753b81c91ca1b6ec84bdebKarl Schimpf// Moved to Arm32::AssemblerARM32::vdivs() 10293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm, 10303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 10313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B23, sd, sn, sm); 10323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 10333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 10343dbe780686601ac6ed753b81c91ca1b6ec84bdebKarl Schimpf// Moved to Arm32::AssemblerARM32::vdivd() 10353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm, 10363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 10373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPddd(cond, B23, dd, dn, dm); 10383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 10393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1040bd4356d59ef318d8c82f3ef0c879dce147bb3146Karl Schimpf// Moved to Arm32::AssemblerARM32::vabss(). 10413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vabss(SRegister sd, SRegister sm, Condition cond) { 10423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm); 10433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 10443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1045bd4356d59ef318d8c82f3ef0c879dce147bb3146Karl Schimpf// Moved to Arm32::AssemblerARM32::vabsd(). 10463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) { 10473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm); 10483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 1049bd4356d59ef318d8c82f3ef0c879dce147bb3146Karl Schimpf#endif 10503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 10513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) { 10523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm); 10533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 10543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 10553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 10563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) { 10573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm); 10583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 10593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1060266c5a25bb8c07b691aa6396ccef6f8d37df9cd0Karl Schimpf#if 0 1061266c5a25bb8c07b691aa6396ccef6f8d37df9cd0Karl Schimpf// Moved to ARM32::AssemblerARM32::vsqrts(). 10623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) { 10633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm); 10643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 10653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1066266c5a25bb8c07b691aa6396ccef6f8d37df9cd0Karl Schimpf// Moved to ARM32::AssemblerARM32::vsqrtd(). 10673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) { 10683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm); 10693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 10703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 10716c7181c5d3f082cbc04b58dd4745253139ad51e0Karl Schimpf// Moved to ARM32::AssemblerARM32::emitVFPsd 10723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitVFPsd(Condition cond, int32_t opcode, 10733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf SRegister sd, DRegister dm) { 10743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 10753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(sd != kNoSRegister); 10763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(dm != kNoDRegister); 10773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 10783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 10793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B25 | B11 | B9 | opcode | 10803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sd) & 1)*B22) | 10813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sd) >> 1)*B12) | 10823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dm) >> 4)*B5) | 10833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(dm) & 0xf); 10843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 10853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 10863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 10876c7181c5d3f082cbc04b58dd4745253139ad51e0Karl Schimpf// Moved to ARM32::AssemblerARM32::emitVFPds 10883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitVFPds(Condition cond, int32_t opcode, 10893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf DRegister dd, SRegister sm) { 10903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 10913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(dd != kNoDRegister); 10923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(sm != kNoSRegister); 10933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 10943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 10953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B25 | B11 | B9 | opcode | 10963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dd) >> 4)*B22) | 10973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dd) & 0xf)*B12) | 10983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(sm) & 1)*B5) | 10993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(sm) >> 1); 11003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 11013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 11036c7181c5d3f082cbc04b58dd4745253139ad51e0Karl Schimpf// Moved to ARM32::AssemblerARM32::vcvtsd(). 11043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) { 11053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm); 11063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 11086c7181c5d3f082cbc04b58dd4745253139ad51e0Karl Schimpf// Moved to ARM32::AssemblerARM32::vcvtds(). 11093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) { 11103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm); 11113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 111394cc3e6190b3b91d1ac6c4e894391d48228f8e97Karl Schimpf// Moved to ARM32::AssemblerARM32::vcvtis() 11143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) { 11153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm); 11163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 111794cc3e6190b3b91d1ac6c4e894391d48228f8e97Karl Schimpf#endif 11183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 11193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) { 11203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm); 11213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1123ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf#if 0 1124ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf// Moved to ARM32::AssemblerARM32::vcvtsi() 11253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) { 11263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm); 11273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1129ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf// Moved to ARM32::AssemblerARM32::vcvtdi() 11303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) { 11313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm); 11323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1134ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf// Moved to ARM32::AssemblerARM32::vcvtus(). 11353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) { 11363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm); 11373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1139ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf// Moved to ARM32::AssemblerARM32::vcvtud(). 11403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) { 11413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm); 11423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1144ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf// Moved to ARM32::AssemblerARM32::vcvtsu() 11453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) { 11463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm); 11473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1149ab389f2285132ad8f4ad12cdf1e44f3ac5aa0403Karl Schimpf// Moved to ARM32::AssemblerARM32::vcvtdu() 11503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) { 11513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm); 11523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1154cd5e07ec935e179d4d087379afb480c3897d8316Karl Schimpf// Moved to ARM23::AssemblerARM32::vcmps(). 11553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) { 11563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm); 11573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1159cd5e07ec935e179d4d087379afb480c3897d8316Karl Schimpf// Moved to ARM23::AssemblerARM32::vcmpd(). 11603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) { 11613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm); 11623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1164cd5e07ec935e179d4d087379afb480c3897d8316Karl Schimpf// Moved to ARM23::AssemblerARM32::vcmpsz(). 11653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcmpsz(SRegister sd, Condition cond) { 11663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0); 11673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1169cd5e07ec935e179d4d087379afb480c3897d8316Karl Schimpf// Moved to ARM23::AssemblerARM32::vcmpdz(). 11703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcmpdz(DRegister dd, Condition cond) { 11713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0); 11723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1174ee7182759bc8e9acc9a8622e73ac315c4d2dd601Karl Schimpf// APSR_nzcv version moved to ARM32::AssemblerARM32::vmrsAPSR_nzcv() 11753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmrs(Register rd, Condition cond) { 11763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 11773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 11783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 11793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 | 11803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rd)*B12) | 11813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B11 | B9 | B4; 11823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 11833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 1184ee7182759bc8e9acc9a8622e73ac315c4d2dd601Karl Schimpf#endif 11853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 11863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmstat(Condition cond) { 11873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmrs(APSR, cond); 11883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 11893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 11903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 11913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfstatic inline int ShiftOfOperandSize(OperandSize size) { 11923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf switch (size) { 11933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kByte: 11943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kUnsignedByte: 11953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return 0; 11963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kHalfword: 11973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kUnsignedHalfword: 11983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return 1; 11993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kWord: 12003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kUnsignedWord: 12013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return 2; 12023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kWordPair: 12033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return 3; 12043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kSWord: 12053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kDWord: 12063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return 0; 12073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf default: 12083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf UNREACHABLE(); 12093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 12103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 12113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 12123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf UNREACHABLE(); 12133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return -1; 12143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 12153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 12162c0764e2da74e61b1ef1316980972e5177512a74Karl Schimpf#if 0 12172c0764e2da74e61b1ef1316980972e5177512a74Karl Schimpf// Moved to ARM32::AssemblerARM32::emitSIMDqqq() 12183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitSIMDqqq(int32_t opcode, OperandSize size, 12193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf QRegister qd, QRegister qn, QRegister qm) { 12203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::neon_supported()); 12213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int sz = ShiftOfOperandSize(size); 12223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = 12233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(kSpecialCondition) << kConditionShift) | 12243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B25 | B6 | 12253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf opcode | ((sz & 0x3) * B20) | 12263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(qd * 2) >> 4)*B22) | 12273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(qn * 2) & 0xf)*B16) | 12283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(qd * 2) & 0xf)*B12) | 12293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(qn * 2) >> 4)*B7) | 12303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(qm * 2) >> 4)*B5) | 12313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(qm * 2) & 0xf); 12323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 12333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 12342c0764e2da74e61b1ef1316980972e5177512a74Karl Schimpf#endif 12353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 12363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitSIMDddd(int32_t opcode, OperandSize size, 12373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf DRegister dd, DRegister dn, DRegister dm) { 12383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::neon_supported()); 12393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int sz = ShiftOfOperandSize(size); 12403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = 12413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(kSpecialCondition) << kConditionShift) | 12423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B25 | 12433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf opcode | ((sz & 0x3) * B20) | 12443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dd) >> 4)*B22) | 12453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dn) & 0xf)*B16) | 12463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dd) & 0xf)*B12) | 12473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dn) >> 4)*B7) | 12483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((static_cast<int32_t>(dm) >> 4)*B5) | 12493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(dm) & 0xf); 12503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 12513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 12523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 12533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 12543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmovq(QRegister qd, QRegister qm) { 12553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B21 | B8 | B4, kByte, qd, qm, qm); 12563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 12573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 12582c0764e2da74e61b1ef1316980972e5177512a74Karl Schimpf#if 0 12592c0764e2da74e61b1ef1316980972e5177512a74Karl Schimpf// Moved to ARM32::AssemblerARM32::vaddqi(). 12603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vaddqi(OperandSize sz, 12613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf QRegister qd, QRegister qn, QRegister qm) { 12623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B11, sz, qd, qn, qm); 12633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 12643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 12652c0764e2da74e61b1ef1316980972e5177512a74Karl Schimpf// Moved to ARM32::AssemblerARM32::vaddqf(). 12663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vaddqs(QRegister qd, QRegister qn, QRegister qm) { 12673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B11 | B10 | B8, kSWord, qd, qn, qm); 12683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 12692c0764e2da74e61b1ef1316980972e5177512a74Karl Schimpf#endif 12703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 12713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vsubqi(OperandSize sz, 12723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf QRegister qd, QRegister qn, QRegister qm) { 12733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B24 | B11, sz, qd, qn, qm); 12743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 12753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 12763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 12773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vsubqs(QRegister qd, QRegister qn, QRegister qm) { 12783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B21 | B11 | B10 | B8, kSWord, qd, qn, qm); 12793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 12803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1281341158aaa16449090a09dad48c337449d3b4687aKarl Schimpf#if 0 1282341158aaa16449090a09dad48c337449d3b4687aKarl Schimpf// Moved to ARM32::AssemblerARM32::vmulqi(). 12833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmulqi(OperandSize sz, 12843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf QRegister qd, QRegister qn, QRegister qm) { 12853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B11 | B8 | B4, sz, qd, qn, qm); 12863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 12873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1288341158aaa16449090a09dad48c337449d3b4687aKarl Schimpf// Moved to ARM32::AssemblerARM32::vmulqf(). 12893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmulqs(QRegister qd, QRegister qn, QRegister qm) { 12903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B24 | B11 | B10 | B8 | B4, kSWord, qd, qn, qm); 12913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 12923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 129315e77d4698df65dfce5072b59df18500ff56daa3John Porto// Moved to ARM32::AssemblerARM32::vshlqi(). 12943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vshlqi(OperandSize sz, 12953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf QRegister qd, QRegister qm, QRegister qn) { 12963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B25 | B10, sz, qd, qn, qm); 12973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 12983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 12993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 130015e77d4698df65dfce5072b59df18500ff56daa3John Porto// Moved to ARM32::AssemblerARM32::vshlqu(). 13013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vshlqu(OperandSize sz, 13023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf QRegister qd, QRegister qm, QRegister qn) { 13033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B25 | B24 | B10, sz, qd, qn, qm); 13043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 13053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1306625dfb384b3993329861d27e22689d4cc1ae1e4bKarl Schimpf// Moved to ARM32::AssemblerARM32::veorq() 13073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::veorq(QRegister qd, QRegister qn, QRegister qm) { 13083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B24 | B8 | B4, kByte, qd, qn, qm); 13093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 13103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1311e295575d6c1ff80d4466aa1c72e8197a66a1ff5aKarl Schimpf// Moved to ARM32::AssemblerARM32::vorrq() 13123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vorrq(QRegister qd, QRegister qn, QRegister qm) { 13133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B21 | B8 | B4, kByte, qd, qn, qm); 13143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 1315e295575d6c1ff80d4466aa1c72e8197a66a1ff5aKarl Schimpf#endif 13163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vornq(QRegister qd, QRegister qn, QRegister qm) { 13183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B21 | B20 | B8 | B4, kByte, qd, qn, qm); 13193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 13203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1321fd7975f14884a851379335a07c831fd6f33770f8Karl Schimpf#if 0 1322fd7975f14884a851379335a07c831fd6f33770f8Karl Schimpf// Moved to ARM32::AssemblerARM32::vandq() 13233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vandq(QRegister qd, QRegister qn, QRegister qm) { 13243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B8 | B4, kByte, qd, qn, qm); 13253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 13263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmvnq(QRegister qd, QRegister qm) { 13283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B25 | B24 | B23 | B10 | B8 | B7, kWordPair, qd, Q0, qm); 13293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 1330a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto#endif 13313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vminqs(QRegister qd, QRegister qn, QRegister qm) { 13343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B21 | B11 | B10 | B9 | B8, kSWord, qd, qn, qm); 13353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 13363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vmaxqs(QRegister qd, QRegister qn, QRegister qm) { 13393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B11 | B10 | B9 | B8, kSWord, qd, qn, qm); 13403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 13413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1342425e06b05945520e3182e4ccf2bb3cb4db7f8690Karl Schimpf#if 0 1343425e06b05945520e3182e4ccf2bb3cb4db7f8690Karl Schimpf// Moved to Arm32::AssemblerARM32::vabsq(). 13443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vabsqs(QRegister qd, QRegister qm) { 13453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B16 | B10 | B9 | B8, kSWord, 13463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf qd, Q0, qm); 13473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 13483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 134915e77d4698df65dfce5072b59df18500ff56daa3John Porto// Moved to Arm32::AssemblerARM32::vnegqs(). 13503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vnegqs(QRegister qd, QRegister qm) { 13513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B16 | B10 | B9 | B8 | B7, kSWord, 13523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf qd, Q0, qm); 13533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 135415e77d4698df65dfce5072b59df18500ff56daa3John Porto#endif 13553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vrecpeqs(QRegister qd, QRegister qm) { 13583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B17 | B16 | B10 | B8, kSWord, 13593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf qd, Q0, qm); 13603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 13613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vrecpsqs(QRegister qd, QRegister qn, QRegister qm) { 13643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B11 | B10 | B9 | B8 | B4, kSWord, qd, qn, qm); 13653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 13663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vrsqrteqs(QRegister qd, QRegister qm) { 13693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B17 | B16 | B10 | B8 | B7, 13703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf kSWord, qd, Q0, qm); 13713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 13723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vrsqrtsqs(QRegister qd, QRegister qn, QRegister qm) { 13753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B21 | B11 | B10 | B9 | B8 | B4, kSWord, qd, qn, qm); 13763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 13773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vdup(OperandSize sz, QRegister qd, DRegister dm, int idx) { 13803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((sz != kDWord) && (sz != kSWord) && (sz != kWordPair)); 13813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int code = 0; 13823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 13833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf switch (sz) { 13843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kByte: 13853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kUnsignedByte: { 13863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((idx >= 0) && (idx < 8)); 13873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf code = 1 | (idx << 1); 13883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 13893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 13903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kHalfword: 13913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kUnsignedHalfword: { 13923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((idx >= 0) && (idx < 4)); 13933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf code = 2 | (idx << 2); 13943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 13953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 13963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kWord: 13973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kUnsignedWord: { 13983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((idx >= 0) && (idx < 2)); 13993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf code = 4 | (idx << 3); 14003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 14013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 14023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf default: { 14033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 14043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 14053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 14063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 14073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDddd(B24 | B23 | B11 | B10 | B6, kWordPair, 14083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<DRegister>(qd * 2), 14093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<DRegister>(code & 0xf), 14103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf dm); 14113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 14123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 14133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 14143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vtbl(DRegister dd, DRegister dn, int len, DRegister dm) { 14153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((len >= 1) && (len <= 4)); 14163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDddd(B24 | B23 | B11 | ((len - 1) * B8), kWordPair, dd, dn, dm); 14173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 14183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 14193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 14203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vzipqw(QRegister qd, QRegister qm) { 14213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B24 | B23 | B21 | B20 | B19 | B17 | B8 | B7, kByte, qd, Q0, qm); 14223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 14233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 14243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1425a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto#if 0 1426a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto// Moved to Arm32::AssemblerARM32::vceqqi(). 14273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vceqqi(OperandSize sz, 14283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf QRegister qd, QRegister qn, QRegister qm) { 14293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B24 | B11 | B4, sz, qd, qn, qm); 14303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 14313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1432a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto// Moved to Arm32::AssemblerARM32::vceqqi(). 14333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vceqqs(QRegister qd, QRegister qn, QRegister qm) { 14343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B11 | B10 | B9, kSWord, qd, qn, qm); 14353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 14363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1437a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto// Moved to Arm32::AssemblerARM32::vcgeqi(). 14383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcgeqi(OperandSize sz, 14393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf QRegister qd, QRegister qn, QRegister qm) { 14403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B9 | B8 | B4, sz, qd, qn, qm); 14413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 14423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1443a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto// Moved to Arm32::AssemblerARM32::vcugeqi(). 14443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcugeqi(OperandSize sz, 14453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf QRegister qd, QRegister qn, QRegister qm) { 14463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B24 | B9 | B8 | B4, sz, qd, qn, qm); 14473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 14483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1449a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto// Moved to Arm32::AssemblerARM32::vcgeqs(). 14503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcgeqs(QRegister qd, QRegister qn, QRegister qm) { 14513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B24 | B11 | B10 | B9, kSWord, qd, qn, qm); 14523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 14533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1454a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto// Moved to Arm32::AssemblerARM32::vcgtqi(). 14553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcgtqi(OperandSize sz, 14563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf QRegister qd, QRegister qn, QRegister qm) { 14573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B9 | B8, sz, qd, qn, qm); 14583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 14593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1460a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto// Moved to Arm32::AssemblerARM32::vcugtqi(). 14613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcugtqi(OperandSize sz, 14623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf QRegister qd, QRegister qn, QRegister qm) { 14633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B24 | B9 | B8, sz, qd, qn, qm); 14643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 14653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1466a4d100ab21814f39591684c59e4c4e113fa0f1f4John Porto// Moved to Arm32::AssemblerARM32::vcgtqs(). 14673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::vcgtqs(QRegister qd, QRegister qn, QRegister qm) { 14683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitSIMDqqq(B24 | B21 | B11 | B10 | B9, kSWord, qd, qn, qm); 14693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 14703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1471174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf// Moved to ARM32::AssemblerARM32::bkpt() 14723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::bkpt(uint16_t imm16) { 14733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(BkptEncoding(imm16)); 14743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 1475c5abdc1301260c79f60d60ec1117e8044312da30Karl Schimpf#endif 14763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 14773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 14783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::b(Label* label, Condition cond) { 14793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitBranch(cond, label, false); 14803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 14813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 14823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1483174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf#if 0 1484174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf// Moved to ARM32::AssemblerARM32::bl() 14853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::bl(Label* label, Condition cond) { 14863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitBranch(cond, label, true); 14873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 14883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1489174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf// Moved to ARM32::AssemblerARM32::bx() 14903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::bx(Register rm, Condition cond) { 14913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rm != kNoRegister); 14923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 14933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 14943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B24 | B21 | (0xfff << 8) | B4 | 14953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rm) << kRmShift); 14963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 14973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 14983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1499174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf// Moved to ARM32::AssemblerARM32::blx() 15003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::blx(Register rm, Condition cond) { 15013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rm != kNoRegister); 15023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cond != kNoCondition); 15033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 15043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf B24 | B21 | (0xfff << 8) | B5 | B4 | 15053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (static_cast<int32_t>(rm) << kRmShift); 15063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(encoding); 15073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 1508174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf#endif 15093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::MarkExceptionHandler(Label* label) { 15123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType01(AL, 1, TST, 1, PC, R0, Operand(0)); 15133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label l; 15143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&l); 15153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitBranch(AL, label, false); 15163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Bind(&l); 15173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 15183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Drop(intptr_t stack_elements) { 15213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(stack_elements >= 0); 15223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (stack_elements > 0) { 15233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(SP, SP, stack_elements * kWordSize); 15243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 15253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 15263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfintptr_t Assembler::FindImmediate(int32_t imm) { 15293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return object_pool_wrapper_.FindImmediate(imm); 15303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 15313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// Uses a code sequence that can easily be decoded. 15343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadWordFromPoolOffset(Register rd, 15353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset, 15363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register pp, 15373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 15383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((pp != PP) || constant_pool_allowed()); 15393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rd != pp); 15403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset_mask = 0; 15413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) { 15423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(rd, Address(pp, offset), cond); 15433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 15443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset_hi = offset & ~offset_mask; // signed 15453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf uint32_t offset_lo = offset & offset_mask; // unsigned 15463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Inline a simplified version of AddImmediate(rd, pp, offset_hi). 15473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand o; 15483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Operand::CanHold(offset_hi, &o)) { 15493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf add(rd, pp, o, cond); 15503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 15513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(rd, offset_hi, cond); 15523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf add(rd, pp, Operand(rd), cond); 15533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 15543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(rd, Address(rd, offset_lo), cond); 15553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 15563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 15573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::CheckCodePointer() { 15593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#ifdef DEBUG 15603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label cid_ok, instructions_ok; 15613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Push(R0); 15623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Push(IP); 15633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf CompareClassId(CODE_REG, kCodeCid, R0); 15643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&cid_ok, EQ); 15653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bkpt(0); 15663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Bind(&cid_ok); 15673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const intptr_t offset = CodeSize() + Instr::kPCReadOffset + 15693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Instructions::HeaderSize() - kHeapObjectTag; 15703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(R0, Operand(PC)); 15713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(R0, R0, -offset); 15723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(IP, FieldAddress(CODE_REG, Code::saved_instructions_offset())); 15733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf cmp(R0, Operand(IP)); 15743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&instructions_ok, EQ); 15753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bkpt(1); 15763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Bind(&instructions_ok); 15773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Pop(IP); 15783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Pop(R0); 15793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#endif 15803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 15813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::RestoreCodePointer() { 15843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(CODE_REG, Address(FP, kPcMarkerSlotFromFp * kWordSize)); 15853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf CheckCodePointer(); 15863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 15873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadPoolPointer(Register reg) { 15903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Load new pool pointer. 15913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf CheckCodePointer(); 15923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(reg, FieldAddress(CODE_REG, Code::object_pool_offset())); 15933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf set_constant_pool_allowed(reg == PP); 15943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 15953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 15973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadIsolate(Register rd) { 15983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(rd, Address(THR, Thread::isolate_offset())); 15993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 16003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfbool Assembler::CanLoadFromObjectPool(const Object& object) const { 16033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(!Thread::CanLoadFromThread(object)); 16043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (!constant_pool_allowed()) { 16053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return false; 16063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 16073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(object.IsNotTemporaryScopedHandle()); 16093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(object.IsOld()); 16103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return true; 16113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 16123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadObjectHelper(Register rd, 16153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Object& object, 16163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond, 16173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bool is_unique, 16183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register pp) { 16193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Load common VM constants from the thread. This works also in places where 16203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // no constant pool is set up (e.g. intrinsic code). 16213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Thread::CanLoadFromThread(object)) { 16223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Load common VM constants from the thread. This works also in places where 16233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // no constant pool is set up (e.g. intrinsic code). 16243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(rd, Address(THR, Thread::OffsetFromThread(object)), cond); 16253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else if (object.IsSmi()) { 16263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Relocation doesn't apply to Smis. 16273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond); 16283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else if (CanLoadFromObjectPool(object)) { 16293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Make sure that class CallPattern is able to decode this load from the 16303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // object pool. 16313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t offset = ObjectPool::element_offset( 16323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf is_unique ? object_pool_wrapper_.AddObject(object) 16333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf : object_pool_wrapper_.FindObject(object)); 16343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, pp, cond); 16353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 16363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(FLAG_allow_absolute_addresses); 16373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(object.IsOld()); 16383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Make sure that class CallPattern is able to decode this load immediate. 16393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t object_raw = reinterpret_cast<int32_t>(object.raw()); 16403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(rd, object_raw, cond); 16413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 16423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 16433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadObject(Register rd, const Object& object, Condition cond) { 16463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadObjectHelper(rd, object, cond, /* is_unique = */ false, PP); 16473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 16483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadUniqueObject(Register rd, 16513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Object& object, 16523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 16533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadObjectHelper(rd, object, cond, /* is_unique = */ true, PP); 16543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 16553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadFunctionFromCalleePool(Register dst, 16583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Function& function, 16593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register new_pp) { 16603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t offset = 16613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ObjectPool::element_offset(object_pool_wrapper_.FindObject(function)); 16623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadWordFromPoolOffset(dst, offset - kHeapObjectTag, new_pp, AL); 16633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 16643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadNativeEntry(Register rd, 16673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const ExternalLabel* label, 16683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Patchability patchable, 16693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 16703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t offset = ObjectPool::element_offset( 16713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf object_pool_wrapper_.FindNativeEntry(label, patchable)); 16723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, PP, cond); 16733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 16743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::PushObject(const Object& object) { 16773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadObject(IP, object); 16783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Push(IP); 16793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 16803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::CompareObject(Register rn, const Object& object) { 16833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rn != IP); 16843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (object.IsSmi()) { 16853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf CompareImmediate(rn, reinterpret_cast<int32_t>(object.raw())); 16863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 16873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadObject(IP, object); 16883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf cmp(rn, Operand(IP)); 16893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 16903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 16913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 16933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// Preserves object and value registers. 16943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::StoreIntoObjectFilterNoSmi(Register object, 16953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register value, 16963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label* no_update) { 16973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) && 16983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (kOldObjectAlignmentOffset == 0)); 16993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Write-barrier triggers if the value is in the new space (has bit set) and 17013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // the object is in the old space (has bit cleared). 17023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // To check that, we compute value & ~object and skip the write barrier 17033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // if the bit is not set. We can't destroy the object. 17043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bic(IP, value, Operand(object)); 17053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tst(IP, Operand(kNewObjectAlignmentOffset)); 17063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(no_update, EQ); 17073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 17083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// Preserves object and value registers. 17113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::StoreIntoObjectFilter(Register object, 17123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register value, 17133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label* no_update) { 17143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // For the value we are only interested in the new/old bit and the tag bit. 17153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // And the new bit with the tag bit. The resulting bit will be 0 for a Smi. 17163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf and_(IP, value, Operand(value, LSL, kObjectAlignmentLog2 - 1)); 17173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // And the result with the negated space bit of the object. 17183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bic(IP, IP, Operand(object)); 17193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tst(IP, Operand(kNewObjectAlignmentOffset)); 17203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(no_update, EQ); 17213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 17223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl SchimpfOperand Assembler::GetVerifiedMemoryShadow() { 17253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand offset; 17263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (!Operand::CanHold(VerifiedMemory::offset(), &offset)) { 17273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf FATAL1("Offset 0x%" Px " not representable", VerifiedMemory::offset()); 17283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 17293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return offset; 17303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 17313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::WriteShadowedField(Register base, 17343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t offset, 17353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register value, 17363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 17373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (VerifiedMemory::enabled()) { 17383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != value); 17393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand shadow(GetVerifiedMemoryShadow()); 17403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf add(base, base, shadow, cond); 17413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(value, Address(base, offset), cond); 17423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf sub(base, base, shadow, cond); 17433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 17443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(value, Address(base, offset), cond); 17453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 17463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::WriteShadowedFieldPair(Register base, 17493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t offset, 17503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register value_even, 17513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register value_odd, 17523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 17533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(value_odd == value_even + 1); 17543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (VerifiedMemory::enabled()) { 17553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != value_even); 17563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != value_odd); 17573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand shadow(GetVerifiedMemoryShadow()); 17583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf add(base, base, shadow, cond); 17593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf strd(value_even, base, offset, cond); 17603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf sub(base, base, shadow, cond); 17613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 17623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf strd(value_even, base, offset, cond); 17633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 17643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl SchimpfRegister UseRegister(Register reg, RegList* used) { 17673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(reg != SP); 17683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(reg != PC); 17693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((*used & (1 << reg)) == 0); 17703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf *used |= (1 << reg); 17713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return reg; 17723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 17733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl SchimpfRegister AllocateRegister(RegList* used) { 17763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const RegList free = ~*used; 17773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return (free == 0) ? 17783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf kNoRegister : 17793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf UseRegister(static_cast<Register>(Utils::CountTrailingZeros(free)), used); 17803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 17813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 17833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::VerifiedWrite(const Address& address, 17843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register new_value, 17853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf FieldContent old_content) { 17863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#if defined(DEBUG) 17873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(address.mode() == Address::Offset || 17883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf address.mode() == Address::NegOffset); 17893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Allocate temporary registers (and check for register collisions). 17903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf RegList used = 0; 17913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf UseRegister(new_value, &used); 17923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register base = UseRegister(address.rn(), &used); 17933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (address.rm() != kNoRegister) { 17943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf UseRegister(address.rm(), &used); 17953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 17963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register old_value = AllocateRegister(&used); 17973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register temp = AllocateRegister(&used); 17983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf PushList(used); 17993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(old_value, address); 18003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // First check that 'old_value' contains 'old_content'. 18013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Smi test. 18023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tst(old_value, Operand(kHeapObjectTag)); 18033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label ok; 18043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf switch (old_content) { 18053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kOnlySmi: 18063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&ok, EQ); // Smi is OK. 18073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Stop("Expected smi."); 18083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 18093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kHeapObjectOrSmi: 18103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&ok, EQ); // Smi is OK. 18113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Non-smi case: Verify object pointer is word-aligned when untagged. 18123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf COMPILE_ASSERT(kHeapObjectTag == 1); 18133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tst(old_value, Operand((kWordSize - 1) - kHeapObjectTag)); 18143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&ok, EQ); 18153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Stop("Expected heap object or Smi"); 18163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 18173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kEmptyOrSmiOrNull: 18183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&ok, EQ); // Smi is OK. 18193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Non-smi case: Check for the special zap word or null. 18203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Note: Cannot use CompareImmediate, since IP may be in use. 18213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(temp, Heap::kZap32Bits); 18223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf cmp(old_value, Operand(temp)); 18233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&ok, EQ); 18243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadObject(temp, Object::null_object()); 18253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf cmp(old_value, Operand(temp)); 18263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&ok, EQ); 18273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Stop("Expected zapped, Smi or null"); 18283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 18293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf default: 18303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf UNREACHABLE(); 18313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 18323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Bind(&ok); 18333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (VerifiedMemory::enabled()) { 18343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand shadow_offset(GetVerifiedMemoryShadow()); 18353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Adjust the address to shadow. 18363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf add(base, base, shadow_offset); 18373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(temp, address); 18383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf cmp(old_value, Operand(temp)); 18393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label match; 18403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&match, EQ); 18413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Stop("Write barrier verification failed"); 18423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Bind(&match); 18433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Write new value in shadow. 18443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(new_value, address); 18453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Restore original address. 18463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf sub(base, base, shadow_offset); 18473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 18483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(new_value, address); 18493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf PopList(used); 18503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#else 18513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(new_value, address); 18523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#endif // DEBUG 18533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 18543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 18553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 18563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::StoreIntoObject(Register object, 18573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Address& dest, 18583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register value, 18593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bool can_value_be_smi) { 18603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(object != value); 18613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf VerifiedWrite(dest, value, kHeapObjectOrSmi); 18623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label done; 18633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (can_value_be_smi) { 18643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreIntoObjectFilter(object, value, &done); 18653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 18663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreIntoObjectFilterNoSmi(object, value, &done); 18673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 18683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // A store buffer update is required. 18693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf RegList regs = (1 << CODE_REG) | (1 << LR); 18703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (value != R0) { 18713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf regs |= (1 << R0); // Preserve R0. 18723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 18733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf PushList(regs); 18743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (object != R0) { 18753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(R0, Operand(object)); 18763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 18773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset())); 18783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(LR, Address(THR, Thread::update_store_buffer_entry_point_offset())); 18793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf blx(LR); 18803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf PopList(regs); 18813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Bind(&done); 18823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 18833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 18843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 18853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::StoreIntoObjectOffset(Register object, 18863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset, 18873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register value, 18883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bool can_value_be_smi) { 18893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t ignored = 0; 18903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) { 18913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreIntoObject( 18923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf object, FieldAddress(object, offset), value, can_value_be_smi); 18933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 18943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(IP, object, offset - kHeapObjectTag); 18953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreIntoObject(object, Address(IP), value, can_value_be_smi); 18963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 18973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 18983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 18993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 19003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::StoreIntoObjectNoBarrier(Register object, 19013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Address& dest, 19023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register value, 19033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf FieldContent old_content) { 19043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf VerifiedWrite(dest, value, old_content); 19053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#if defined(DEBUG) 19063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label done; 19073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreIntoObjectFilter(object, value, &done); 19083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Stop("Store buffer update is required"); 19093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Bind(&done); 19103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#endif // defined(DEBUG) 19113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // No store buffer update. 19123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 19133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 19143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 19153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::StoreIntoObjectNoBarrierOffset(Register object, 19163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset, 19173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register value, 19183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf FieldContent old_content) { 19193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t ignored = 0; 19203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) { 19213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value, 19223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf old_content); 19233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 19243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(IP, object, offset - kHeapObjectTag); 19253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreIntoObjectNoBarrier(object, Address(IP), value, old_content); 19263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 19273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 19283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 19293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 19303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::StoreIntoObjectNoBarrier(Register object, 19313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Address& dest, 19323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Object& value, 19333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf FieldContent old_content) { 19343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(value.IsSmi() || value.InVMHeap() || 19353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (value.IsOld() && value.IsNotTemporaryScopedHandle())); 19363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // No store buffer update. 19373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadObject(IP, value); 19383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf VerifiedWrite(dest, IP, old_content); 19393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 19403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 19413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 19423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::StoreIntoObjectNoBarrierOffset(Register object, 19433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset, 19443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Object& value, 19453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf FieldContent old_content) { 19463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t ignored = 0; 19473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) { 19483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value, 19493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf old_content); 19503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 19513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(IP, object, offset - kHeapObjectTag); 19523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreIntoObjectNoBarrier(object, Address(IP), value, old_content); 19533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 19543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 19553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 19563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 19573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::InitializeFieldsNoBarrier(Register object, 19583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register begin, 19593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register end, 19603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register value_even, 19613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register value_odd) { 19623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(value_odd == value_even + 1); 19633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label init_loop; 19643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Bind(&init_loop); 19653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(begin, 2 * kWordSize); 19663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf cmp(begin, Operand(end)); 19673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf WriteShadowedFieldPair(begin, -2 * kWordSize, value_even, value_odd, LS); 19683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&init_loop, CC); 19693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf WriteShadowedField(begin, -2 * kWordSize, value_even, HI); 19703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#if defined(DEBUG) 19713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label done; 19723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreIntoObjectFilter(object, value_even, &done); 19733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreIntoObjectFilter(object, value_odd, &done); 19743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Stop("Store buffer update is required"); 19753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Bind(&done); 19763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#endif // defined(DEBUG) 19773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // No store buffer update. 19783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 19793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 19803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 19813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::InitializeFieldsNoBarrierUnrolled(Register object, 19823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register base, 19833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t begin_offset, 19843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t end_offset, 19853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register value_even, 19863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register value_odd) { 19873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(value_odd == value_even + 1); 19883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t current_offset = begin_offset; 19893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf while (current_offset + kWordSize < end_offset) { 19903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf WriteShadowedFieldPair(base, current_offset, value_even, value_odd); 19913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf current_offset += 2*kWordSize; 19923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 19933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf while (current_offset < end_offset) { 19943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf WriteShadowedField(base, current_offset, value_even); 19953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf current_offset += kWordSize; 19963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 19973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#if defined(DEBUG) 19983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label done; 19993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreIntoObjectFilter(object, value_even, &done); 20003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreIntoObjectFilter(object, value_odd, &done); 20013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Stop("Store buffer update is required"); 20023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Bind(&done); 20033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#endif // defined(DEBUG) 20043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // No store buffer update. 20053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 20063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::StoreIntoSmiField(const Address& dest, Register value) { 20093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#if defined(DEBUG) 20103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label done; 20113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tst(value, Operand(kHeapObjectTag)); 20123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&done, EQ); 20133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Stop("New value must be Smi."); 20143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Bind(&done); 20153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#endif // defined(DEBUG) 20163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf VerifiedWrite(dest, value, kOnlySmi); 20173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 20183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadClassId(Register result, Register object, Condition cond) { 20213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(RawObject::kClassIdTagPos == 16); 20223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(RawObject::kClassIdTagSize == 16); 20233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const intptr_t class_id_offset = Object::tags_offset() + 20243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf RawObject::kClassIdTagPos / kBitsPerByte; 20253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldrh(result, FieldAddress(object, class_id_offset), cond); 20263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 20273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadClassById(Register result, Register class_id) { 20303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(result != class_id); 20313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadIsolate(result); 20323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const intptr_t offset = 20333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Isolate::class_table_offset() + ClassTable::table_offset(); 20343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadFromOffset(kWord, result, result, offset); 20353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(result, Address(result, class_id, LSL, 2)); 20363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 20373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadClass(Register result, Register object, Register scratch) { 20403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(scratch != result); 20413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadClassId(scratch, object); 20423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadClassById(result, scratch); 20433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 20443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::CompareClassId(Register object, 20473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t class_id, 20483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register scratch) { 20493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadClassId(scratch, object); 20503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf CompareImmediate(scratch, class_id); 20513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 20523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadClassIdMayBeSmi(Register result, Register object) { 20553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tst(object, Operand(kSmiTagMask)); 20563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadClassId(result, object, NE); 20573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(result, kSmiCid, EQ); 20583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 20593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadTaggedClassIdMayBeSmi(Register result, Register object) { 20623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadClassIdMayBeSmi(result, object); 20633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf SmiTag(result); 20643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 20653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::ComputeRange(Register result, 20683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register value, 20693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register scratch, 20703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label* not_mint) { 20713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Register hi = TMP; 20723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Register lo = scratch; 20733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label done; 20753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(result, Operand(value, LSR, kBitsPerWord - 1)); 20763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tst(value, Operand(kSmiTagMask)); 20773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&done, EQ); 20783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf CompareClassId(value, kMintCid, result); 20793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(not_mint, NE); 20803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(hi, FieldAddress(value, Mint::value_offset() + kWordSize)); 20813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(lo, FieldAddress(value, Mint::value_offset())); 20823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf rsb(result, hi, Operand(ICData::kInt32RangeBit)); 20833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf cmp(hi, Operand(lo, ASR, kBitsPerWord - 1)); 20843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&done, EQ); 20853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(result, ICData::kUint32RangeBit); // Uint32 20863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tst(hi, Operand(hi)); 20873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(result, ICData::kInt64RangeBit, NE); // Int64 20883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Bind(&done); 20893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 20903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 20923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::UpdateRangeFeedback(Register value, 20933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t index, 20943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register ic_data, 20953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register scratch1, 20963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register scratch2, 20973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label* miss) { 20983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(ICData::IsValidRangeFeedbackIndex(index)); 20993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ComputeRange(scratch1, value, scratch2, miss); 21003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(scratch2, FieldAddress(ic_data, ICData::state_bits_offset())); 21013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf orr(scratch2, 21023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf scratch2, 21033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand(scratch1, LSL, ICData::RangeFeedbackShift(index))); 21043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(scratch2, FieldAddress(ic_data, ICData::state_bits_offset())); 21053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 21063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2107137e62bd843313d4b8697621989e0e6f5c2e7f81Karl Schimpf#if 0 2108e559be77b93bdfa5b0877455f012219aa426f10fKarl Schimpf// Moved to ::canEncodeBranchoffset() in IceAssemblerARM32.cpp. 21093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfstatic bool CanEncodeBranchOffset(int32_t offset) { 21103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(Utils::IsAligned(offset, 4)); 2111137e62bd843313d4b8697621989e0e6f5c2e7f81Karl Schimpf // Note: This check doesn't take advantage of the fact that offset>>2 2112137e62bd843313d4b8697621989e0e6f5c2e7f81Karl Schimpf // is stored (allowing two more bits in address space). 21133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset); 21143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 21153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2116e559be77b93bdfa5b0877455f012219aa426f10fKarl Schimpf// Moved to ARM32::AssemblerARM32::encodeBranchOffset() 21173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfint32_t Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) { 21183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // The offset is off by 8 due to the way the ARM CPUs read PC. 21193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset -= Instr::kPCReadOffset; 21203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 21213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (!CanEncodeBranchOffset(offset)) { 21223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(!use_far_branches()); 21233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Thread::Current()->long_jump_base()->Jump( 21243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 1, Object::branch_offset_error()); 21253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 21263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 21273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Properly preserve only the bits supported in the instruction. 21283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset >>= 2; 21293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset &= kBranchOffsetMask; 21303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return (inst & ~kBranchOffsetMask) | offset; 21313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 21323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2133e559be77b93bdfa5b0877455f012219aa426f10fKarl Schimpf// Moved to AssemberARM32::decodeBranchOffset() 21343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfint Assembler::DecodeBranchOffset(int32_t inst) { 21353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Sign-extend, left-shift by 2, then add 8. 21363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return ((((inst & kBranchOffsetMask) << 8) >> 6) + Instr::kPCReadOffset); 21373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2138137e62bd843313d4b8697621989e0e6f5c2e7f81Karl Schimpf#endif 21393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 21403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfstatic int32_t DecodeARMv7LoadImmediate(int32_t movt, int32_t movw) { 21413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset = 0; 21423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset |= (movt & 0xf0000) << 12; 21433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset |= (movt & 0xfff) << 16; 21443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset |= (movw & 0xf0000) >> 4; 21453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset |= movw & 0xfff; 21463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return offset; 21473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 21483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 21493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 21503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfstatic int32_t DecodeARMv6LoadImmediate(int32_t mov, int32_t or1, 21513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t or2, int32_t or3) { 21523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset = 0; 21533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset |= (mov & 0xff) << 24; 21543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset |= (or1 & 0xff) << 16; 21553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset |= (or2 & 0xff) << 8; 21563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset |= (or3 & 0xff); 21573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return offset; 21583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 21593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 21603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 21613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfclass PatchFarBranch : public AssemblerFixup { 21623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf public: 21633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf PatchFarBranch() {} 21643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 21653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf void Process(const MemoryRegion& region, intptr_t position) { 21663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const ARMVersion version = TargetCPUFeatures::arm_version(); 21673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if ((version == ARMv5TE) || (version == ARMv6)) { 21683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ProcessARMv6(region, position); 21693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 21703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(version == ARMv7); 21713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ProcessARMv7(region, position); 21723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 21733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 21743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 21753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf private: 21763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf void ProcessARMv6(const MemoryRegion& region, intptr_t position) { 21773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t mov = region.Load<int32_t>(position); 21783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t or1 = region.Load<int32_t>(position + 1*Instr::kInstrSize); 21793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t or2 = region.Load<int32_t>(position + 2*Instr::kInstrSize); 21803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t or3 = region.Load<int32_t>(position + 3*Instr::kInstrSize); 21813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t bx = region.Load<int32_t>(position + 4*Instr::kInstrSize); 21823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 21833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (((mov & 0xffffff00) == 0xe3a0c400) && // mov IP, (byte3 rot 4) 21843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((or1 & 0xffffff00) == 0xe38cc800) && // orr IP, IP, (byte2 rot 8) 21853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((or2 & 0xffffff00) == 0xe38ccc00) && // orr IP, IP, (byte1 rot 12) 21863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((or3 & 0xffffff00) == 0xe38cc000)) { // orr IP, IP, byte0 21873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t offset = DecodeARMv6LoadImmediate(mov, or1, or2, or3); 21883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t dest = region.start() + offset; 21893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t dest0 = (dest & 0x000000ff); 21903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t dest1 = (dest & 0x0000ff00) >> 8; 21913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t dest2 = (dest & 0x00ff0000) >> 16; 21923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t dest3 = (dest & 0xff000000) >> 24; 21933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t patched_mov = 0xe3a0c400 | dest3; 21943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t patched_or1 = 0xe38cc800 | dest2; 21953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t patched_or2 = 0xe38ccc00 | dest1; 21963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t patched_or3 = 0xe38cc000 | dest0; 21973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 21983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf region.Store<int32_t>(position + 0 * Instr::kInstrSize, patched_mov); 21993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf region.Store<int32_t>(position + 1 * Instr::kInstrSize, patched_or1); 22003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf region.Store<int32_t>(position + 2 * Instr::kInstrSize, patched_or2); 22013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf region.Store<int32_t>(position + 3 * Instr::kInstrSize, patched_or3); 22023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return; 22033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 22043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // If the offset loading instructions aren't there, we must have replaced 22063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // the far branch with a near one, and so these instructions 22073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // should be NOPs. 22083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((or1 == Instr::kNopInstruction) && 22093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (or2 == Instr::kNopInstruction) && 22103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (or3 == Instr::kNopInstruction) && 22113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (bx == Instr::kNopInstruction)); 22123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 22133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf void ProcessARMv7(const MemoryRegion& region, intptr_t position) { 22163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t movw = region.Load<int32_t>(position); 22173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t movt = region.Load<int32_t>(position + Instr::kInstrSize); 22183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t bx = region.Load<int32_t>(position + 2 * Instr::kInstrSize); 22193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (((movt & 0xfff0f000) == 0xe340c000) && // movt IP, high 22213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ((movw & 0xfff0f000) == 0xe300c000)) { // movw IP, low 22223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t offset = DecodeARMv7LoadImmediate(movt, movw); 22233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t dest = region.start() + offset; 22243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uint16_t dest_high = Utils::High16Bits(dest); 22253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uint16_t dest_low = Utils::Low16Bits(dest); 22263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t patched_movt = 22273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 0xe340c000 | ((dest_high >> 12) << 16) | (dest_high & 0xfff); 22283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t patched_movw = 22293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 0xe300c000 | ((dest_low >> 12) << 16) | (dest_low & 0xfff); 22303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf region.Store<int32_t>(position, patched_movw); 22323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf region.Store<int32_t>(position + Instr::kInstrSize, patched_movt); 22333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return; 22343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 22353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // If the offset loading instructions aren't there, we must have replaced 22373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // the far branch with a near one, and so these instructions 22383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // should be NOPs. 22393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((movt == Instr::kNopInstruction) && 22403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (bx == Instr::kNopInstruction)); 22413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 22423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf virtual bool IsPointerOffset() const { return false; } 22443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf}; 22453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitFarBranch(Condition cond, int32_t offset, bool link) { 22483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.EmitFixup(new PatchFarBranch()); 22493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadPatchableImmediate(IP, offset); 22503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (link) { 22513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf blx(IP, cond); 22523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 22533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bx(IP, cond); 22543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 22553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 22563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EmitBranch(Condition cond, Label* label, bool link) { 22593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (label->IsBound()) { 22603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t dest = label->Position() - buffer_.Size(); 22613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (use_far_branches() && !CanEncodeBranchOffset(dest)) { 22623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitFarBranch(cond, label->Position(), link); 22633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 22643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType5(cond, dest, link); 22653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 22663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 22673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const intptr_t position = buffer_.Size(); 22683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (use_far_branches()) { 22693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t dest = label->position_; 22703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitFarBranch(cond, dest, link); 22713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 22723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Use the offset field of the branch instruction for linking the sites. 22733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EmitType5(cond, label->position_, link); 22743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 22753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf label->LinkTo(position); 22763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 22773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 22783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::BindARMv6(Label* label) { 22813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(!label->IsBound()); 22823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t bound_pc = buffer_.Size(); 22833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf while (label->IsLinked()) { 22843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t position = label->Position(); 22853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t dest = bound_pc - position; 22863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (use_far_branches() && !CanEncodeBranchOffset(dest)) { 22873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Far branches are enabled and we can't encode the branch offset. 22883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Grab instructions that load the offset. 22903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t mov = 22913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Load<int32_t>(position); 22923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t or1 = 22933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Load<int32_t>(position + 1 * Instr::kInstrSize); 22943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t or2 = 22953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Load<int32_t>(position + 2 * Instr::kInstrSize); 22963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t or3 = 22973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Load<int32_t>(position + 3 * Instr::kInstrSize); 22983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 22993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Change from relative to the branch to relative to the assembler 23003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // buffer. 23013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf dest = buffer_.Size(); 23023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t dest0 = (dest & 0x000000ff); 23033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t dest1 = (dest & 0x0000ff00) >> 8; 23043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t dest2 = (dest & 0x00ff0000) >> 16; 23053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t dest3 = (dest & 0xff000000) >> 24; 23063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t patched_mov = 0xe3a0c400 | dest3; 23073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t patched_or1 = 0xe38cc800 | dest2; 23083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t patched_or2 = 0xe38ccc00 | dest1; 23093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t patched_or3 = 0xe38cc000 | dest0; 23103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 23113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Rewrite the instructions. 23123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position + 0 * Instr::kInstrSize, patched_mov); 23133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position + 1 * Instr::kInstrSize, patched_or1); 23143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position + 2 * Instr::kInstrSize, patched_or2); 23153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position + 3 * Instr::kInstrSize, patched_or3); 23163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf label->position_ = DecodeARMv6LoadImmediate(mov, or1, or2, or3); 23173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else if (use_far_branches() && CanEncodeBranchOffset(dest)) { 23183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Grab instructions that load the offset, and the branch. 23193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t mov = 23203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Load<int32_t>(position); 23213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t or1 = 23223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Load<int32_t>(position + 1 * Instr::kInstrSize); 23233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t or2 = 23243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Load<int32_t>(position + 2 * Instr::kInstrSize); 23253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t or3 = 23263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Load<int32_t>(position + 3 * Instr::kInstrSize); 23273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t branch = 23283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Load<int32_t>(position + 4 * Instr::kInstrSize); 23293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 23303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Grab the branch condition, and encode the link bit. 23313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t cond = branch & 0xf0000000; 23323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t link = (branch & 0x20) << 19; 23333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 23343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Encode the branch and the offset. 23353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t new_branch = cond | link | 0x0a000000; 23363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t encoded = EncodeBranchOffset(dest, new_branch); 23373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 23383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Write the encoded branch instruction followed by two nops. 23393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position, encoded); 23403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position + 1 * Instr::kInstrSize, 23413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Instr::kNopInstruction); 23423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position + 2 * Instr::kInstrSize, 23433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Instr::kNopInstruction); 23443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position + 3 * Instr::kInstrSize, 23453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Instr::kNopInstruction); 23463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position + 4 * Instr::kInstrSize, 23473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Instr::kNopInstruction); 23483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 23493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf label->position_ = DecodeARMv6LoadImmediate(mov, or1, or2, or3); 23503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 23513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t next = buffer_.Load<int32_t>(position); 23523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoded = Assembler::EncodeBranchOffset(dest, next); 23533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position, encoded); 23543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf label->position_ = Assembler::DecodeBranchOffset(next); 23553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 23563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 23573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf label->BindTo(bound_pc); 23583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 23593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2360c5abdc1301260c79f60d60ec1117e8044312da30Karl Schimpf#if 0 2361174531ec83bf9d51b2dc669b3f73f1fb637fbcceKarl Schimpf// Moved to ARM32::AssemblerARM32::bind(Label* Label) 2362c5abdc1301260c79f60d60ec1117e8044312da30Karl Schimpf// Note: Most of this code isn't needed because instruction selection has 2363c5abdc1301260c79f60d60ec1117e8044312da30Karl Schimpf// already been handler 23643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::BindARMv7(Label* label) { 23653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(!label->IsBound()); 23663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t bound_pc = buffer_.Size(); 23673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf while (label->IsLinked()) { 23683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t position = label->Position(); 23693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t dest = bound_pc - position; 23703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (use_far_branches() && !CanEncodeBranchOffset(dest)) { 23713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Far branches are enabled and we can't encode the branch offset. 23723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 23733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Grab instructions that load the offset. 23743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t movw = 23753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Load<int32_t>(position + 0 * Instr::kInstrSize); 23763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t movt = 23773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Load<int32_t>(position + 1 * Instr::kInstrSize); 23783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 23793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Change from relative to the branch to relative to the assembler 23803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // buffer. 23813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf dest = buffer_.Size(); 23823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uint16_t dest_high = Utils::High16Bits(dest); 23833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uint16_t dest_low = Utils::Low16Bits(dest); 23843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t patched_movt = 23853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 0xe340c000 | ((dest_high >> 12) << 16) | (dest_high & 0xfff); 23863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t patched_movw = 23873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 0xe300c000 | ((dest_low >> 12) << 16) | (dest_low & 0xfff); 23883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 23893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Rewrite the instructions. 23903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position + 0 * Instr::kInstrSize, patched_movw); 23913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position + 1 * Instr::kInstrSize, patched_movt); 23923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf label->position_ = DecodeARMv7LoadImmediate(movt, movw); 23933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else if (use_far_branches() && CanEncodeBranchOffset(dest)) { 23943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Far branches are enabled, but we can encode the branch offset. 23953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 23963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Grab instructions that load the offset, and the branch. 23973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t movw = 23983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Load<int32_t>(position + 0 * Instr::kInstrSize); 23993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t movt = 24003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Load<int32_t>(position + 1 * Instr::kInstrSize); 24013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t branch = 24023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Load<int32_t>(position + 2 * Instr::kInstrSize); 24033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 24043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Grab the branch condition, and encode the link bit. 24053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t cond = branch & 0xf0000000; 24063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t link = (branch & 0x20) << 19; 24073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 24083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Encode the branch and the offset. 24093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t new_branch = cond | link | 0x0a000000; 24103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t encoded = EncodeBranchOffset(dest, new_branch); 24113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 24123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Write the encoded branch instruction followed by two nops. 24133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position + 0 * Instr::kInstrSize, 24143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf encoded); 24153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position + 1 * Instr::kInstrSize, 24163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Instr::kNopInstruction); 24173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position + 2 * Instr::kInstrSize, 24183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Instr::kNopInstruction); 24193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 24203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf label->position_ = DecodeARMv7LoadImmediate(movt, movw); 24213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 24223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t next = buffer_.Load<int32_t>(position); 24233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t encoded = Assembler::EncodeBranchOffset(dest, next); 24243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf buffer_.Store<int32_t>(position, encoded); 24253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf label->position_ = Assembler::DecodeBranchOffset(next); 24263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 24273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 24283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf label->BindTo(bound_pc); 24293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2430c5abdc1301260c79f60d60ec1117e8044312da30Karl Schimpf#endif 24313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 24323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 24333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Bind(Label* label) { 24343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const ARMVersion version = TargetCPUFeatures::arm_version(); 24353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if ((version == ARMv5TE) || (version == ARMv6)) { 24363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf BindARMv6(label); 24373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 24383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(version == ARMv7); 24393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf BindARMv7(label); 24403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 24413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 24423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 24433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 24443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl SchimpfOperandSize Address::OperandSizeFor(intptr_t cid) { 24453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf switch (cid) { 24463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kArrayCid: 24473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kImmutableArrayCid: 24483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kWord; 24493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kOneByteStringCid: 24503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kExternalOneByteStringCid: 24513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kByte; 24523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTwoByteStringCid: 24533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kExternalTwoByteStringCid: 24543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kHalfword; 24553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataInt8ArrayCid: 24563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kByte; 24573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataUint8ArrayCid: 24583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataUint8ClampedArrayCid: 24593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kExternalTypedDataUint8ArrayCid: 24603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kExternalTypedDataUint8ClampedArrayCid: 24613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kUnsignedByte; 24623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataInt16ArrayCid: 24633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kHalfword; 24643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataUint16ArrayCid: 24653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kUnsignedHalfword; 24663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataInt32ArrayCid: 24673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kWord; 24683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataUint32ArrayCid: 24693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kUnsignedWord; 24703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataInt64ArrayCid: 24713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataUint64ArrayCid: 24723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf UNREACHABLE(); 24733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kByte; 24743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataFloat32ArrayCid: 24753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kSWord; 24763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataFloat64ArrayCid: 24773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kDWord; 24783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataFloat32x4ArrayCid: 24793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataInt32x4ArrayCid: 24803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataFloat64x2ArrayCid: 24813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kRegList; 24823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kTypedDataInt8ArrayViewCid: 24833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf UNREACHABLE(); 24843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kByte; 24853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf default: 24863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf UNREACHABLE(); 24873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return kByte; 24883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 24893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 24903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 24913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 24923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfbool Address::CanHoldLoadOffset(OperandSize size, 24933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset, 24943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t* offset_mask) { 24953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf switch (size) { 24963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kByte: 24973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kHalfword: 24983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kUnsignedHalfword: 24993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kWordPair: { 25003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf *offset_mask = 0xff; 25013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return Utils::IsAbsoluteUint(8, offset); // Addressing mode 3. 25023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 25033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kUnsignedByte: 25043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kWord: 25053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kUnsignedWord: { 25063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf *offset_mask = 0xfff; 25073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return Utils::IsAbsoluteUint(12, offset); // Addressing mode 2. 25083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 25093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kSWord: 25103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kDWord: { 25113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf *offset_mask = 0x3fc; // Multiple of 4. 25123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // VFP addressing mode. 25133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return (Utils::IsAbsoluteUint(10, offset) && Utils::IsAligned(offset, 4)); 25143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 25153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kRegList: { 25163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf *offset_mask = 0x0; 25173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return offset == 0; 25183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 25193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf default: { 25203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf UNREACHABLE(); 25213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return false; 25223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 25233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 25243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 25253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 25263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 25273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfbool Address::CanHoldStoreOffset(OperandSize size, 25283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset, 25293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t* offset_mask) { 25303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf switch (size) { 25313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kHalfword: 25323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kUnsignedHalfword: 25333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kWordPair: { 25343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf *offset_mask = 0xff; 25353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return Utils::IsAbsoluteUint(8, offset); // Addressing mode 3. 25363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 25373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kByte: 25383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kUnsignedByte: 25393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kWord: 25403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kUnsignedWord: { 25413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf *offset_mask = 0xfff; 25423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return Utils::IsAbsoluteUint(12, offset); // Addressing mode 2. 25433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 25443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kSWord: 25453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kDWord: { 25463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf *offset_mask = 0x3fc; // Multiple of 4. 25473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // VFP addressing mode. 25483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return (Utils::IsAbsoluteUint(10, offset) && Utils::IsAligned(offset, 4)); 25493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 25503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kRegList: { 25513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf *offset_mask = 0x0; 25523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return offset == 0; 25533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 25543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf default: { 25553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf UNREACHABLE(); 25563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return false; 25573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 25583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 25593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 25603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 25613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 25623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfbool Address::CanHoldImmediateOffset( 25633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bool is_load, intptr_t cid, int64_t offset) { 25643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset_mask = 0; 25653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (is_load) { 25663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return CanHoldLoadOffset(OperandSizeFor(cid), offset, &offset_mask); 25673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 25683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return CanHoldStoreOffset(OperandSizeFor(cid), offset, &offset_mask); 25693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 25703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 25713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 25726cab56197153807395ff60d1d672b0098dd97a8aKarl Schimpf#if 0 2573f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf// Moved to ARM32::AssemblerARM32::push(). 25743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Push(Register rd, Condition cond) { 25753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(rd, Address(SP, -kWordSize, Address::PreIndex), cond); 25763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 25773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2578f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf// Moved to ARM32::AssemblerARM32::pop(). 25793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Pop(Register rd, Condition cond) { 25803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(rd, Address(SP, kWordSize, Address::PostIndex), cond); 25813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 25823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2583f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf// Moved to ARM32::AssemblerARM32::pushList(). 25843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::PushList(RegList regs, Condition cond) { 25853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf stm(DB_W, SP, regs, cond); 25863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 25873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2588f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf// Moved to ARM32::AssemblerARM32::popList(). 25893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::PopList(RegList regs, Condition cond) { 25903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldm(IA_W, SP, regs, cond); 25913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 2592f66a85b205fc2985c130eebd95a03999394dad0eKarl Schimpf#endif 25933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 25943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::MoveRegister(Register rd, Register rm, Condition cond) { 25953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (rd != rm) { 25963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(rd, Operand(rm), cond); 25973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 25983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 25993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2600f4d0a7a5819541ecb44ec7dafe151114981cdb88Karl Schimpf#if 0 2601f4d0a7a5819541ecb44ec7dafe151114981cdb88Karl Schimpf// Moved to ARM32::AssemblerARM32::lsl() 26023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Lsl(Register rd, Register rm, const Operand& shift_imm, 26033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 26043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(shift_imm.type() == 1); 26053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(shift_imm.encoding() != 0); // Do not use Lsl if no shift is wanted. 26063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(rd, Operand(rm, LSL, shift_imm.encoding()), cond); 26073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 26083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 2609f4d0a7a5819541ecb44ec7dafe151114981cdb88Karl Schimpf// Moved to ARM32::AssemblerARM32::lsl() 26103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Lsl(Register rd, Register rm, Register rs, Condition cond) { 26113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(rd, Operand(rm, LSL, rs), cond); 26123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 26133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26144ddce702d86894de5d7e60ed0178df86ed2e7dd1Karl Schimpf// Moved to ARM32::AssemblerARM32::lsr() 26153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Lsr(Register rd, Register rm, const Operand& shift_imm, 26163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 26173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(shift_imm.type() == 1); 26183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf uint32_t shift = shift_imm.encoding(); 26193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(shift != 0); // Do not use Lsr if no shift is wanted. 26203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (shift == 32) { 26213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf shift = 0; // Comply to UAL syntax. 26223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 26233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(rd, Operand(rm, LSR, shift), cond); 26243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 26253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26264ddce702d86894de5d7e60ed0178df86ed2e7dd1Karl Schimpf// Moved to ARM32::AssemblerARM32::lsr() 26273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Lsr(Register rd, Register rm, Register rs, Condition cond) { 26283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(rd, Operand(rm, LSR, rs), cond); 26293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 26303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26313ac9a49be518ff47e4ad0f6390268e232740cef5Karl Schimpf// Moved to ARM32::AssemblerARM32::asr() 26323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Asr(Register rd, Register rm, const Operand& shift_imm, 26333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 26343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(shift_imm.type() == 1); 26353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf uint32_t shift = shift_imm.encoding(); 26363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(shift != 0); // Do not use Asr if no shift is wanted. 26373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (shift == 32) { 26383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf shift = 0; // Comply to UAL syntax. 26393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 26403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(rd, Operand(rm, ASR, shift), cond); 26413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 26423ac9a49be518ff47e4ad0f6390268e232740cef5Karl Schimpf#endif 26433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Asrs(Register rd, Register rm, const Operand& shift_imm, 26453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 26463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(shift_imm.type() == 1); 26473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf uint32_t shift = shift_imm.encoding(); 26483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(shift != 0); // Do not use Asr if no shift is wanted. 26493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (shift == 32) { 26503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf shift = 0; // Comply to UAL syntax. 26513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 26523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf movs(rd, Operand(rm, ASR, shift), cond); 26533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 26543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26553ac9a49be518ff47e4ad0f6390268e232740cef5Karl Schimpf#if 0 26563ac9a49be518ff47e4ad0f6390268e232740cef5Karl Schimpf// Moved to ARM32::AssemblerARM32::asr() 26573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Asr(Register rd, Register rm, Register rs, Condition cond) { 26583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(rd, Operand(rm, ASR, rs), cond); 26593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 26603ac9a49be518ff47e4ad0f6390268e232740cef5Karl Schimpf#endif 26613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Ror(Register rd, Register rm, const Operand& shift_imm, 26633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 26643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(shift_imm.type() == 1); 26653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(shift_imm.encoding() != 0); // Use Rrx instruction. 26663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(rd, Operand(rm, ROR, shift_imm.encoding()), cond); 26673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 26683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Ror(Register rd, Register rm, Register rs, Condition cond) { 26713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(rd, Operand(rm, ROR, rs), cond); 26723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 26733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Rrx(Register rd, Register rm, Condition cond) { 26763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(rd, Operand(rm, ROR, 0), cond); 26773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 26783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::SignFill(Register rd, Register rm, Condition cond) { 26813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Asr(rd, rm, Operand(31), cond); 26823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 26833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Vreciprocalqs(QRegister qd, QRegister qm) { 26863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(qm != QTMP); 26873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(qd != QTMP); 26883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Reciprocal estimate. 26903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vrecpeqs(qd, qm); 26913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // 2 Newton-Raphson steps. 26923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vrecpsqs(QTMP, qm, qd); 26933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmulqs(qd, qd, QTMP); 26943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vrecpsqs(QTMP, qm, qd); 26953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmulqs(qd, qd, QTMP); 26963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 26973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 26993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::VreciprocalSqrtqs(QRegister qd, QRegister qm) { 27003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(qm != QTMP); 27013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(qd != QTMP); 27023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Reciprocal square root estimate. 27043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vrsqrteqs(qd, qm); 27053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. 27063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // First step. 27073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmulqs(QTMP, qd, qd); // QTMP <- xn^2 27083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vrsqrtsqs(QTMP, qm, QTMP); // QTMP <- (3 - Q1*QTMP) / 2. 27093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmulqs(qd, qd, QTMP); // xn+1 <- xn * QTMP 27103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Second step. 27113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmulqs(QTMP, qd, qd); 27123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vrsqrtsqs(QTMP, qm, QTMP); 27133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmulqs(qd, qd, QTMP); 27143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 27153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Vsqrtqs(QRegister qd, QRegister qm, QRegister temp) { 27183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(temp != QTMP); 27193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(qm != QTMP); 27203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(qd != QTMP); 27213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (temp != kNoQRegister) { 27233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmovq(temp, qm); 27243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf qm = temp; 27253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 27263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf VreciprocalSqrtqs(qd, qm); 27283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmovq(qm, qd); 27293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Vreciprocalqs(qd, qm); 27303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 27313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Vdivqs(QRegister qd, QRegister qn, QRegister qm) { 27343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(qd != QTMP); 27353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(qn != QTMP); 27363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(qm != QTMP); 27373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Vreciprocalqs(qd, qm); 27393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmulqs(qd, qn, qd); 27403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 27413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Branch(const StubEntry& stub_entry, 27443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Patchability patchable, 27453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register pp, 27463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 27473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Code& target_code = Code::Handle(stub_entry.code()); 27483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t offset = ObjectPool::element_offset( 27493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf object_pool_wrapper_.FindObject(target_code, patchable)); 27503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, pp, cond); 27513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(IP, FieldAddress(CODE_REG, Code::entry_point_offset()), cond); 27523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bx(IP, cond); 27533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 27543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::BranchLink(const Code& target, Patchability patchable) { 27573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Make sure that class CallPattern is able to patch the label referred 27583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // to by this code sequence. 27593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // For added code robustness, use 'blx lr' in a patchable sequence and 27603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). 27613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t offset = ObjectPool::element_offset( 27623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf object_pool_wrapper_.FindObject(target, patchable)); 27633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, PP, AL); 27643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(LR, FieldAddress(CODE_REG, Code::entry_point_offset())); 27653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf blx(LR); // Use blx instruction so that the return branch prediction works. 27663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 27673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::BranchLink(const StubEntry& stub_entry, 27703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Patchability patchable) { 27713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Code& code = Code::Handle(stub_entry.code()); 27723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf BranchLink(code, patchable); 27733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 27743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::BranchLinkPatchable(const Code& target) { 27773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf BranchLink(target, kPatchable); 27783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 27793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::BranchLink(const ExternalLabel* label) { 27823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(LR, label->address()); // Target address is never patched. 27833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf blx(LR); // Use blx instruction so that the return branch prediction works. 27843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 27853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::BranchLinkPatchable(const StubEntry& stub_entry) { 27883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf BranchLinkPatchable(Code::Handle(stub_entry.code())); 27893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 27903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::BranchLinkOffset(Register base, int32_t offset) { 27933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != PC); 27943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != IP); 27953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadFromOffset(kWord, IP, base, offset); 27963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf blx(IP); // Use blx instruction so that the return branch prediction works. 27973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 27983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 27993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 28003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadPatchableImmediate( 28013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rd, int32_t value, Condition cond) { 28023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const ARMVersion version = TargetCPUFeatures::arm_version(); 28033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if ((version == ARMv5TE) || (version == ARMv6)) { 28043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // This sequence is patched in a few places, and should remain fixed. 28053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uint32_t byte0 = (value & 0x000000ff); 28063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uint32_t byte1 = (value & 0x0000ff00) >> 8; 28073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uint32_t byte2 = (value & 0x00ff0000) >> 16; 28083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uint32_t byte3 = (value & 0xff000000) >> 24; 28093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(rd, Operand(4, byte3), cond); 28103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf orr(rd, rd, Operand(8, byte2), cond); 28113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf orr(rd, rd, Operand(12, byte1), cond); 28123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf orr(rd, rd, Operand(byte0), cond); 28133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 28143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(version == ARMv7); 28153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uint16_t value_low = Utils::Low16Bits(value); 28163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uint16_t value_high = Utils::High16Bits(value); 28173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf movw(rd, value_low, cond); 28183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf movt(rd, value_high, cond); 28193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 28203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 28213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 28223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 28233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadDecodableImmediate( 28243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register rd, int32_t value, Condition cond) { 28253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const ARMVersion version = TargetCPUFeatures::arm_version(); 28263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if ((version == ARMv5TE) || (version == ARMv6)) { 28273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (constant_pool_allowed()) { 28283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int32_t offset = Array::element_offset(FindImmediate(value)); 28293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, PP, cond); 28303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 28313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadPatchableImmediate(rd, value, cond); 28323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 28333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 28343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(version == ARMv7); 28353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf movw(rd, Utils::Low16Bits(value), cond); 28363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uint16_t value_high = Utils::High16Bits(value); 28373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (value_high != 0) { 28383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf movt(rd, value_high, cond); 28393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 28403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 28413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 28423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 28433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 28443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) { 28453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand o; 28463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Operand::CanHold(value, &o)) { 28473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(rd, o, cond); 28483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else if (Operand::CanHold(~value, &o)) { 28493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mvn(rd, o, cond); 28503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 28513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadDecodableImmediate(rd, value, cond); 28523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 28533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 28543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 28553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 28563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadSImmediate(SRegister sd, float value, Condition cond) { 28573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (!vmovs(sd, value, cond)) { 28583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const DRegister dd = static_cast<DRegister>(sd >> 1); 28593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int index = sd & 1; 28603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(IP, bit_cast<int32_t, float>(value), cond); 28613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmovdr(dd, index, IP, cond); 28623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 28633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 28643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 28653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 28663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadDImmediate(DRegister dd, 28673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf double value, 28683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register scratch, 28693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 28703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(scratch != PC); 28713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(scratch != IP); 28723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (!vmovd(dd, value, cond)) { 28733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // A scratch register and IP are needed to load an arbitrary double. 28743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(scratch != kNoRegister); 28753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int64_t imm64 = bit_cast<int64_t, double>(value); 28763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(IP, Utils::Low32Bits(imm64), cond); 28773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(scratch, Utils::High32Bits(imm64), cond); 28783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmovdrr(dd, IP, scratch, cond); 28793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 28803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 28813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 28823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 28833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadFromOffset(OperandSize size, 28843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register reg, 28853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register base, 28863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset, 28873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 28883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset_mask = 0; 28893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (!Address::CanHoldLoadOffset(size, offset, &offset_mask)) { 28903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != IP); 28913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(IP, base, offset & ~offset_mask, cond); 28923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf base = IP; 28933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset = offset & offset_mask; 28943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 28953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf switch (size) { 28963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kByte: 28973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldrsb(reg, Address(base, offset), cond); 28983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 28993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kUnsignedByte: 29003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldrb(reg, Address(base, offset), cond); 29013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 29023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kHalfword: 29033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldrsh(reg, Address(base, offset), cond); 29043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 29053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kUnsignedHalfword: 29063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldrh(reg, Address(base, offset), cond); 29073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 29083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kWord: 29093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(reg, Address(base, offset), cond); 29103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 29113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kWordPair: 29123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldrd(reg, base, offset, cond); 29133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 29143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf default: 29153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf UNREACHABLE(); 29163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 29173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 29183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 29193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 29203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::StoreToOffset(OperandSize size, 29213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register reg, 29223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register base, 29233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset, 29243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 29253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset_mask = 0; 29263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (!Address::CanHoldStoreOffset(size, offset, &offset_mask)) { 29273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(reg != IP); 29283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != IP); 29293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(IP, base, offset & ~offset_mask, cond); 29303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf base = IP; 29313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset = offset & offset_mask; 29323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 29333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf switch (size) { 29343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kByte: 29353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf strb(reg, Address(base, offset), cond); 29363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 29373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kHalfword: 29383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf strh(reg, Address(base, offset), cond); 29393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 29403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kWord: 29413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(reg, Address(base, offset), cond); 29423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 29433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf case kWordPair: 29443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf strd(reg, base, offset, cond); 29453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf break; 29463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf default: 29473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf UNREACHABLE(); 29483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 29493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 29503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 29513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 29523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadSFromOffset(SRegister reg, 29533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register base, 29543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset, 29553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 29563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset_mask = 0; 29573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (!Address::CanHoldLoadOffset(kSWord, offset, &offset_mask)) { 29583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != IP); 29593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(IP, base, offset & ~offset_mask, cond); 29603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf base = IP; 29613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset = offset & offset_mask; 29623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 29633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vldrs(reg, Address(base, offset), cond); 29643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 29653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 29663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 29673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::StoreSToOffset(SRegister reg, 29683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register base, 29693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset, 29703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 29713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset_mask = 0; 29723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (!Address::CanHoldStoreOffset(kSWord, offset, &offset_mask)) { 29733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != IP); 29743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(IP, base, offset & ~offset_mask, cond); 29753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf base = IP; 29763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset = offset & offset_mask; 29773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 29783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vstrs(reg, Address(base, offset), cond); 29793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 29803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 29813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 29823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadDFromOffset(DRegister reg, 29833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register base, 29843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset, 29853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 29863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset_mask = 0; 29873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (!Address::CanHoldLoadOffset(kDWord, offset, &offset_mask)) { 29883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != IP); 29893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(IP, base, offset & ~offset_mask, cond); 29903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf base = IP; 29913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset = offset & offset_mask; 29923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 29933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vldrd(reg, Address(base, offset), cond); 29943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 29953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 29963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 29973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::StoreDToOffset(DRegister reg, 29983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register base, 29993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset, 30003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 30013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset_mask = 0; 30023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (!Address::CanHoldStoreOffset(kDWord, offset, &offset_mask)) { 30033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != IP); 30043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(IP, base, offset & ~offset_mask, cond); 30053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf base = IP; 30063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset = offset & offset_mask; 30073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 30083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vstrd(reg, Address(base, offset), cond); 30093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 30103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 30113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 30123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadMultipleDFromOffset(DRegister first, 30133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t count, 30143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register base, 30153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset) { 30163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != IP); 30173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(IP, base, offset); 30183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vldmd(IA, IP, first, count); 30193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 30203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 30213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::StoreMultipleDToOffset(DRegister first, 30223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t count, 30233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register base, 30243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset) { 30253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(base != IP); 30263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(IP, base, offset); 30273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vstmd(IA, IP, first, count); 30283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 30293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 30303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 30313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::CopyDoubleField( 30323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register dst, Register src, Register tmp1, Register tmp2, DRegister dtmp) { 30333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (TargetCPUFeatures::vfp_supported()) { 30343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadDFromOffset(dtmp, src, Double::value_offset() - kHeapObjectTag); 30353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreDToOffset(dtmp, dst, Double::value_offset() - kHeapObjectTag); 30363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 30373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadFromOffset(kWord, tmp1, src, 30383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Double::value_offset() - kHeapObjectTag); 30393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadFromOffset(kWord, tmp2, src, 30403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Double::value_offset() + kWordSize - kHeapObjectTag); 30413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreToOffset(kWord, tmp1, dst, 30423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Double::value_offset() - kHeapObjectTag); 30433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreToOffset(kWord, tmp2, dst, 30443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Double::value_offset() + kWordSize - kHeapObjectTag); 30453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 30463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 30473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 30483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 30493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::CopyFloat32x4Field( 30503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register dst, Register src, Register tmp1, Register tmp2, DRegister dtmp) { 30513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (TargetCPUFeatures::neon_supported()) { 30523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadMultipleDFromOffset(dtmp, 2, src, 30533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Float32x4::value_offset() - kHeapObjectTag); 30543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreMultipleDToOffset(dtmp, 2, dst, 30553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Float32x4::value_offset() - kHeapObjectTag); 30563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 30573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadFromOffset(kWord, tmp1, src, 30583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float32x4::value_offset() + 0 * kWordSize) - kHeapObjectTag); 30593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadFromOffset(kWord, tmp2, src, 30603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float32x4::value_offset() + 1 * kWordSize) - kHeapObjectTag); 30613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreToOffset(kWord, tmp1, dst, 30623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float32x4::value_offset() + 0 * kWordSize) - kHeapObjectTag); 30633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreToOffset(kWord, tmp2, dst, 30643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float32x4::value_offset() + 1 * kWordSize) - kHeapObjectTag); 30653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 30663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadFromOffset(kWord, tmp1, src, 30673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float32x4::value_offset() + 2 * kWordSize) - kHeapObjectTag); 30683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadFromOffset(kWord, tmp2, src, 30693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float32x4::value_offset() + 3 * kWordSize) - kHeapObjectTag); 30703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreToOffset(kWord, tmp1, dst, 30713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float32x4::value_offset() + 2 * kWordSize) - kHeapObjectTag); 30723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreToOffset(kWord, tmp2, dst, 30733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float32x4::value_offset() + 3 * kWordSize) - kHeapObjectTag); 30743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 30753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 30763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 30773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 30783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::CopyFloat64x2Field( 30793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register dst, Register src, Register tmp1, Register tmp2, DRegister dtmp) { 30803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (TargetCPUFeatures::neon_supported()) { 30813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadMultipleDFromOffset(dtmp, 2, src, 30823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Float64x2::value_offset() - kHeapObjectTag); 30833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreMultipleDToOffset(dtmp, 2, dst, 30843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Float64x2::value_offset() - kHeapObjectTag); 30853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 30863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadFromOffset(kWord, tmp1, src, 30873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float64x2::value_offset() + 0 * kWordSize) - kHeapObjectTag); 30883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadFromOffset(kWord, tmp2, src, 30893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float64x2::value_offset() + 1 * kWordSize) - kHeapObjectTag); 30903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreToOffset(kWord, tmp1, dst, 30913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float64x2::value_offset() + 0 * kWordSize) - kHeapObjectTag); 30923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreToOffset(kWord, tmp2, dst, 30933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float64x2::value_offset() + 1 * kWordSize) - kHeapObjectTag); 30943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 30953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadFromOffset(kWord, tmp1, src, 30963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float64x2::value_offset() + 2 * kWordSize) - kHeapObjectTag); 30973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadFromOffset(kWord, tmp2, src, 30983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float64x2::value_offset() + 3 * kWordSize) - kHeapObjectTag); 30993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreToOffset(kWord, tmp1, dst, 31003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float64x2::value_offset() + 2 * kWordSize) - kHeapObjectTag); 31013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf StoreToOffset(kWord, tmp2, dst, 31023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (Float64x2::value_offset() + 3 * kWordSize) - kHeapObjectTag); 31033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 31043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 31053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 31063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 31073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::AddImmediate(Register rd, int32_t value, Condition cond) { 31083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(rd, rd, value, cond); 31093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 31103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 31113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 31123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::AddImmediate(Register rd, Register rn, int32_t value, 31133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 31143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (value == 0) { 31153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (rd != rn) { 31163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mov(rd, Operand(rn), cond); 31173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 31183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return; 31193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 31203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // We prefer to select the shorter code sequence rather than selecting add for 31213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // positive values and sub for negatives ones, which would slightly improve 31223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // the readability of generated code for some constants. 31233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand o; 31243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Operand::CanHold(value, &o)) { 31253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf add(rd, rn, o, cond); 31263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else if (Operand::CanHold(-value, &o)) { 31273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf sub(rd, rn, o, cond); 31283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 31293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rn != IP); 31303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Operand::CanHold(~value, &o)) { 31313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mvn(IP, o, cond); 31323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf add(rd, rn, Operand(IP), cond); 31333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else if (Operand::CanHold(~(-value), &o)) { 31343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mvn(IP, o, cond); 31353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf sub(rd, rn, Operand(IP), cond); 31363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 31373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadDecodableImmediate(IP, value, cond); 31383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf add(rd, rn, Operand(IP), cond); 31393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 31403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 31413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 31423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 31433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 31443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::AddImmediateSetFlags(Register rd, Register rn, int32_t value, 31453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 31463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand o; 31473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Operand::CanHold(value, &o)) { 31483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Handles value == kMinInt32. 31493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf adds(rd, rn, o, cond); 31503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else if (Operand::CanHold(-value, &o)) { 31513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 31523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf subs(rd, rn, o, cond); 31533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 31543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rn != IP); 31553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Operand::CanHold(~value, &o)) { 31563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mvn(IP, o, cond); 31573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf adds(rd, rn, Operand(IP), cond); 31583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else if (Operand::CanHold(~(-value), &o)) { 31593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 31603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mvn(IP, o, cond); 31613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf subs(rd, rn, Operand(IP), cond); 31623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 31633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadDecodableImmediate(IP, value, cond); 31643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf adds(rd, rn, Operand(IP), cond); 31653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 31663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 31673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 31683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 31693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 31703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::SubImmediateSetFlags(Register rd, Register rn, int32_t value, 31713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 31723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand o; 31733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Operand::CanHold(value, &o)) { 31743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Handles value == kMinInt32. 31753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf subs(rd, rn, o, cond); 31763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else if (Operand::CanHold(-value, &o)) { 31773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 31783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf adds(rd, rn, o, cond); 31793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 31803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rn != IP); 31813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Operand::CanHold(~value, &o)) { 31823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mvn(IP, o, cond); 31833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf subs(rd, rn, Operand(IP), cond); 31843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else if (Operand::CanHold(~(-value), &o)) { 31853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(value != kMinInt32); // Would cause erroneous overflow detection. 31863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf mvn(IP, o, cond); 31873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf adds(rd, rn, Operand(IP), cond); 31883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 31893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadDecodableImmediate(IP, value, cond); 31903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf subs(rd, rn, Operand(IP), cond); 31913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 31923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 31933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 31943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 31953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 31963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::AndImmediate(Register rd, Register rs, int32_t imm, 31973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Condition cond) { 31983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand o; 31993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Operand::CanHold(imm, &o)) { 32003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf and_(rd, rs, Operand(o), cond); 32013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 32023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(TMP, imm, cond); 32033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf and_(rd, rs, Operand(TMP), cond); 32043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 32053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 32063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::CompareImmediate(Register rn, int32_t value, Condition cond) { 32093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand o; 32103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Operand::CanHold(value, &o)) { 32113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf cmp(rn, o, cond); 32123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 32133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(rn != IP); 32143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(IP, value, cond); 32153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf cmp(rn, Operand(IP), cond); 32163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 32173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 32183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::TestImmediate(Register rn, int32_t imm, Condition cond) { 32213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Operand o; 32223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Operand::CanHold(imm, &o)) { 32233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tst(rn, o, cond); 32243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 32253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(IP, imm); 32263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tst(rn, Operand(IP), cond); 32273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 32283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 32293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::IntegerDivide(Register result, Register left, Register right, 32313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf DRegister tmpl, DRegister tmpr) { 32323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(tmpl != tmpr); 32333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (TargetCPUFeatures::integer_division_supported()) { 32343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf sdiv(result, left, right); 32353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 32363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(TargetCPUFeatures::vfp_supported()); 32373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf SRegister stmpl = static_cast<SRegister>(2 * tmpl); 32383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf SRegister stmpr = static_cast<SRegister>(2 * tmpr); 32393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmovsr(stmpl, left); 32403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vcvtdi(tmpl, stmpl); // left is in tmpl. 32413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmovsr(stmpr, right); 32423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vcvtdi(tmpr, stmpr); // right is in tmpr. 32433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vdivd(tmpr, tmpl, tmpr); 32443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vcvtid(stmpr, tmpr); 32453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vmovrs(result, stmpr); 32463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 32473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 32483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfstatic int NumRegsBelowFP(RegList regs) { 32513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int count = 0; 32523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf for (int i = 0; i < FP; i++) { 32533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if ((regs & (1 << i)) != 0) { 32543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf count++; 32553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 32563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 32573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return count; 32583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 32593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EnterFrame(RegList regs, intptr_t frame_size) { 32623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (prologue_offset_ == -1) { 32633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf prologue_offset_ = CodeSize(); 32643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 32653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf PushList(regs); 32663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if ((regs & (1 << FP)) != 0) { 32673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Set FP to the saved previous FP. 32683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf add(FP, SP, Operand(4 * NumRegsBelowFP(regs))); 32693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 32703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(SP, -frame_size); 32713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 32723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LeaveFrame(RegList regs) { 32753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((regs & (1 << PC)) == 0); // Must not pop PC. 32763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if ((regs & (1 << FP)) != 0) { 32773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Use FP to set SP. 32783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf sub(SP, FP, Operand(4 * NumRegsBelowFP(regs))); 32793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 32803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf PopList(regs); 32813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 32823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Ret() { 32853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bx(LR); 32863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 32873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { 32903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Reserve space for arguments and align frame before entering 32913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // the C++ world. 32923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(SP, -frame_space); 32933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (OS::ActivationFrameAlignment() > 1) { 32943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bic(SP, SP, Operand(OS::ActivationFrameAlignment() - 1)); 32953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 32963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 32973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 32993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { 33003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Preserve volatile CPU registers and PP. 33013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EnterFrame(kDartVolatileCpuRegs | (1 << PP) | (1 << FP), 0); 33023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf COMPILE_ASSERT((kDartVolatileCpuRegs & (1 << PP)) == 0); 33033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Preserve all volatile FPU registers. 33053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (TargetCPUFeatures::vfp_supported()) { 33063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf DRegister firstv = EvenDRegisterOf(kDartFirstVolatileFpuReg); 33073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf DRegister lastv = OddDRegisterOf(kDartLastVolatileFpuReg); 33083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if ((lastv - firstv + 1) >= 16) { 33093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf DRegister mid = static_cast<DRegister>(firstv + 16); 33103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vstmd(DB_W, SP, mid, lastv - mid + 1); 33113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vstmd(DB_W, SP, firstv, 16); 33123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 33133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vstmd(DB_W, SP, firstv, lastv - firstv + 1); 33143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 33153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 33163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadPoolPointer(); 33183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ReserveAlignedFrameSpace(frame_space); 33203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 33213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LeaveCallRuntimeFrame() { 33243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // SP might have been modified to reserve space for arguments 33253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // and ensure proper alignment of the stack frame. 33263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // We need to restore it before restoring registers. 33273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const intptr_t kPushedFpuRegisterSize = 33283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf TargetCPUFeatures::vfp_supported() ? 33293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf kDartVolatileFpuRegCount * kFpuRegisterSize : 0; 33303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf COMPILE_ASSERT(PP < FP); 33323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf COMPILE_ASSERT((kDartVolatileCpuRegs & (1 << PP)) == 0); 33333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // kVolatileCpuRegCount +1 for PP, -1 because even though LR is volatile, 33343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // it is pushed ahead of FP. 33353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const intptr_t kPushedRegistersSize = 33363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf kDartVolatileCpuRegCount * kWordSize + kPushedFpuRegisterSize; 33373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(SP, FP, -kPushedRegistersSize); 33383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Restore all volatile FPU registers. 33403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (TargetCPUFeatures::vfp_supported()) { 33413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf DRegister firstv = EvenDRegisterOf(kDartFirstVolatileFpuReg); 33423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf DRegister lastv = OddDRegisterOf(kDartLastVolatileFpuReg); 33433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if ((lastv - firstv + 1) >= 16) { 33443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf DRegister mid = static_cast<DRegister>(firstv + 16); 33453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vldmd(IA_W, SP, firstv, 16); 33463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vldmd(IA_W, SP, mid, lastv - mid + 1); 33473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 33483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf vldmd(IA_W, SP, firstv, lastv - firstv + 1); 33493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 33503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 33513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Restore volatile CPU registers. 33533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LeaveFrame(kDartVolatileCpuRegs | (1 << PP) | (1 << FP)); 33543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 33553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::CallRuntime(const RuntimeEntry& entry, 33583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t argument_count) { 33593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf entry.Call(this, argument_count); 33603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 33613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EnterDartFrame(intptr_t frame_size) { 33643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(!constant_pool_allowed()); 33653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Registers are pushed in descending order: R9 | R10 | R11 | R14. 33673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EnterFrame((1 << PP) | (1 << CODE_REG) | (1 << FP) | (1 << LR), 0); 33683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Setup pool pointer for this dart function. 33703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadPoolPointer(); 33713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Reserve space for locals. 33733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(SP, -frame_size); 33743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 33753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// On entry to a function compiled for OSR, the caller's frame pointer, the 33783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// stack locals, and any copied parameters are already in place. The frame 33793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// pointer is already set up. The PC marker is not correct for the 33803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// optimized function and there may be extra space for spill slots to 33813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf// allocate. We must also set up the pool pointer for the function. 33823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EnterOsrFrame(intptr_t extra_size) { 33833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(!constant_pool_allowed()); 33843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Comment("EnterOsrFrame"); 33853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf RestoreCodePointer(); 33863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadPoolPointer(); 33873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(SP, -extra_size); 33893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 33903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 33923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LeaveDartFrame(RestorePP restore_pp) { 33933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (restore_pp == kRestoreCallerPP) { 33943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(PP, Address(FP, kSavedCallerPpSlotFromFp * kWordSize)); 33953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf set_constant_pool_allowed(false); 33963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 33973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Drop(2); // Drop saved PP, PC marker. 33983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LeaveFrame((1 << FP) | (1 << LR)); 33993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 34003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 34013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 34023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::EnterStubFrame() { 34033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf EnterDartFrame(0); 34043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 34053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 34063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 34073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LeaveStubFrame() { 34083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LeaveDartFrame(); 34093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 34103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 34113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 34123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::LoadAllocationStatsAddress(Register dest, 34133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t cid, 34143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bool inline_isolate) { 34153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(dest != kNoRegister); 34163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(dest != TMP); 34173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cid > 0); 34183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const intptr_t class_offset = ClassTable::ClassOffsetFor(cid); 34193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (inline_isolate) { 34203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(FLAG_allow_absolute_addresses); 34213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ClassTable* class_table = Isolate::Current()->class_table(); 34223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); 34233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (cid < kNumPredefinedCids) { 34243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(dest, reinterpret_cast<uword>(*table_ptr) + class_offset); 34253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 34263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(dest, reinterpret_cast<uword>(table_ptr)); 34273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(dest, Address(dest, 0)); 34283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(dest, class_offset); 34293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 34303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 34313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadIsolate(dest); 34323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t table_offset = 34333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); 34343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(dest, Address(dest, table_offset)); 34353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(dest, class_offset); 34363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 34373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 34383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 34393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 34403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::MaybeTraceAllocation(intptr_t cid, 34413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register temp_reg, 34423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label* trace, 34433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bool inline_isolate) { 34443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadAllocationStatsAddress(temp_reg, cid, inline_isolate); 34453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uword state_offset = ClassHeapStats::state_offset(); 34463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(temp_reg, Address(temp_reg, state_offset)); 34473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tst(temp_reg, Operand(ClassHeapStats::TraceAllocationMask())); 34483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(trace, NE); 34493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 34503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 34513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 34523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::IncrementAllocationStats(Register stats_addr_reg, 34533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t cid, 34543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Heap::Space space) { 34553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(stats_addr_reg != kNoRegister); 34563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(stats_addr_reg != TMP); 34573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cid > 0); 34583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uword count_field_offset = (space == Heap::kNew) ? 34593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ClassHeapStats::allocated_since_gc_new_space_offset() : 34603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ClassHeapStats::allocated_since_gc_old_space_offset(); 34613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Address& count_address = Address(stats_addr_reg, count_field_offset); 34623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(TMP, count_address); 34633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(TMP, 1); 34643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(TMP, count_address); 34653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 34663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 34673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 34683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::IncrementAllocationStatsWithSize(Register stats_addr_reg, 34693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register size_reg, 34703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Heap::Space space) { 34713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(stats_addr_reg != kNoRegister); 34723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(stats_addr_reg != TMP); 34733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uword count_field_offset = (space == Heap::kNew) ? 34743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ClassHeapStats::allocated_since_gc_new_space_offset() : 34753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ClassHeapStats::allocated_since_gc_old_space_offset(); 34763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const uword size_field_offset = (space == Heap::kNew) ? 34773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ClassHeapStats::allocated_size_since_gc_new_space_offset() : 34783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ClassHeapStats::allocated_size_since_gc_old_space_offset(); 34793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Address& count_address = Address(stats_addr_reg, count_field_offset); 34803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Address& size_address = Address(stats_addr_reg, size_field_offset); 34813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(TMP, count_address); 34823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(TMP, 1); 34833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(TMP, count_address); 34843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(TMP, size_address); 34853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf add(TMP, TMP, Operand(size_reg)); 34863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(TMP, size_address); 34873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 34883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 34893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 34903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::TryAllocate(const Class& cls, 34913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label* failure, 34923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register instance_reg, 34933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register temp_reg) { 34943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(failure != NULL); 34953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (FLAG_inline_alloc) { 34963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(instance_reg != temp_reg); 34973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(temp_reg != IP); 34983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const intptr_t instance_size = cls.instance_size(); 34993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(instance_size != 0); 35003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // If this allocation is traced, program will jump to failure path 35013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // (i.e. the allocation stub) which will allocate the object and trace the 35023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // allocation call site. 35033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf MaybeTraceAllocation(cls.id(), temp_reg, failure, 35043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf /* inline_isolate = */ false); 35053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Heap::Space space = Heap::SpaceForAllocation(cls.id()); 35063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(temp_reg, Address(THR, Thread::heap_offset())); 35073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(instance_reg, Address(temp_reg, Heap::TopOffset(space))); 35083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // TODO(koda): Protect against unsigned overflow here. 35093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediateSetFlags(instance_reg, instance_reg, instance_size); 35103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // instance_reg: potential next object start. 35123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(IP, Address(temp_reg, Heap::EndOffset(space))); 35133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf cmp(IP, Operand(instance_reg)); 35143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // fail if heap end unsigned less than or equal to instance_reg. 35153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(failure, LS); 35163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Successfully allocated the object, now update top to point to 35183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // next object start and store the class in the class field of object. 35193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(instance_reg, Address(temp_reg, Heap::TopOffset(space))); 35203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadAllocationStatsAddress(temp_reg, cls.id(), 35223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf /* inline_isolate = */ false); 35233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(instance_size >= kHeapObjectTag); 35253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(instance_reg, -instance_size + kHeapObjectTag); 35263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf uword tags = 0; 35283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tags = RawObject::SizeTag::update(instance_size, tags); 35293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(cls.id() != kIllegalCid); 35303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tags = RawObject::ClassIdTag::update(cls.id(), tags); 35313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(IP, tags); 35323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(IP, FieldAddress(instance_reg, Object::tags_offset())); 35333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf IncrementAllocationStats(temp_reg, cls.id(), space); 35353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 35363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(failure); 35373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 35383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 35393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::TryAllocateArray(intptr_t cid, 35423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t instance_size, 35433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label* failure, 35443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register instance, 35453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register end_address, 35463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register temp1, 35473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register temp2) { 35483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (FLAG_inline_alloc) { 35493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // If this allocation is traced, program will jump to failure path 35503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // (i.e. the allocation stub) which will allocate the object and trace the 35513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // allocation call site. 35523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf MaybeTraceAllocation(cid, temp1, failure, /* inline_isolate = */ false); 35533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Heap::Space space = Heap::SpaceForAllocation(cid); 35543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(temp1, Address(THR, Thread::heap_offset())); 35553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Potential new object start. 35563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(instance, Address(temp1, Heap::TopOffset(space))); 35573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediateSetFlags(end_address, instance, instance_size); 35583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(failure, CS); // Branch if unsigned overflow. 35593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Check if the allocation fits into the remaining space. 35613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // instance: potential new object start. 35623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // end_address: potential next object start. 35633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ldr(temp2, Address(temp1, Heap::EndOffset(space))); 35643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf cmp(end_address, Operand(temp2)); 35653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(failure, CS); 35663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadAllocationStatsAddress(temp2, cid, /* inline_isolate = */ false); 35683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Successfully allocated the object(s), now update top to point to 35703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // next object start and initialize the object. 35713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(end_address, Address(temp1, Heap::TopOffset(space))); 35723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf add(instance, instance, Operand(kHeapObjectTag)); 35733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Initialize the tags. 35753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // instance: new object start as a tagged pointer. 35763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf uword tags = 0; 35773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tags = RawObject::ClassIdTag::update(cid, tags); 35783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf tags = RawObject::SizeTag::update(instance_size, tags); 35793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(temp1, tags); 35803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf str(temp1, FieldAddress(instance, Array::tags_offset())); // Store tags. 35813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(temp1, instance_size); 35833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf IncrementAllocationStatsWithSize(temp2, temp1, space); 35843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 35853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(failure); 35863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 35873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 35883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 35903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfvoid Assembler::Stop(const char* message) { 35913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (FLAG_print_stop_message) { 35923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf PushList((1 << R0) | (1 << IP) | (1 << LR)); // Preserve R0, IP, LR. 35933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf LoadImmediate(R0, reinterpret_cast<int32_t>(message)); 35943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // PrintStopMessage() preserves all registers. 35953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf BranchLink(&StubCode::PrintStopMessage_entry()->label()); 35963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf PopList((1 << R0) | (1 << IP) | (1 << LR)); // Restore R0, IP, LR. 35973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 35983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Emit the message address before the svc instruction, so that we can 35993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // 'unstop' and continue execution in the simulator or jump to the next 36003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // instruction in gdb. 36013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Label stop; 36023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf b(&stop); 36033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Emit(reinterpret_cast<int32_t>(message)); 36043e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Bind(&stop); 36053e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bkpt(Instr::kStopMessageCode); 36063e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 36073e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 36083e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 36093e53dc99c9f61fc1f65e85735220f0b03d2487caKarl SchimpfAddress Assembler::ElementAddressForIntIndex(bool is_load, 36103e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bool is_external, 36113e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t cid, 36123e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t index_scale, 36133e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register array, 36143e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t index, 36153e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register temp) { 36163e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int64_t offset_base = 36173e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag)); 36183e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const int64_t offset = offset_base + 36193e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf static_cast<int64_t>(index) * index_scale; 36203e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(Utils::IsInt(32, offset)); 36213e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 36223e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (Address::CanHoldImmediateOffset(is_load, cid, offset)) { 36233e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return Address(array, static_cast<int32_t>(offset)); 36243e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 36253e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(Address::CanHoldImmediateOffset(is_load, cid, offset - offset_base)); 36263e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(temp, array, static_cast<int32_t>(offset_base)); 36273e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return Address(temp, static_cast<int32_t>(offset - offset_base)); 36283e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 36293e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 36303e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 36313e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 36323e53dc99c9f61fc1f65e85735220f0b03d2487caKarl SchimpfAddress Assembler::ElementAddressForRegIndex(bool is_load, 36333e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf bool is_external, 36343e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t cid, 36353e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf intptr_t index_scale, 36363e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register array, 36373e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf Register index) { 36383e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf // Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays. 36393e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift; 36403e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset = 36413e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag); 36423e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const OperandSize size = Address::OperandSizeFor(cid); 36433e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(array != IP); 36443e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(index != IP); 36453e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf const Register base = is_load ? IP : index; 36463e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if ((offset != 0) || 36473e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (size == kSWord) || (size == kDWord) || (size == kRegList)) { 36483e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (shift < 0) { 36493e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(shift == -1); 36503e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf add(base, array, Operand(index, ASR, 1)); 36513e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 36523e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf add(base, array, Operand(index, LSL, shift)); 36533e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 36543e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 36553e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if (shift < 0) { 36563e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT(shift == -1); 36573e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return Address(array, index, ASR, 1); 36583e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } else { 36593e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return Address(array, index, LSL, shift); 36603e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 36613e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 36623e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf int32_t offset_mask = 0; 36633e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf if ((is_load && !Address::CanHoldLoadOffset(size, 36643e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset, 36653e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf &offset_mask)) || 36663e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf (!is_load && !Address::CanHoldStoreOffset(size, 36673e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset, 36683e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf &offset_mask))) { 36693e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf AddImmediate(base, offset & ~offset_mask); 36703e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf offset = offset & offset_mask; 36713e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf } 36723e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return Address(base, offset); 36733e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 36743e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 36753e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 36763e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfstatic const char* cpu_reg_names[kNumberOfCpuRegisters] = { 36773e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 36783e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf "r8", "ctx", "pp", "fp", "ip", "sp", "lr", "pc", 36793e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf}; 36803e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 36813e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 36823e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfconst char* Assembler::RegisterName(Register reg) { 36833e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters)); 36843e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return cpu_reg_names[reg]; 36853e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 36863e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 36873e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 36883e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfstatic const char* fpu_reg_names[kNumberOfFpuRegisters] = { 36893e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", 36903e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#if defined(VFPv3_D32) 36913e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", 36923e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#endif 36933e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf}; 36943e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 36953e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 36963e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpfconst char* Assembler::FpuRegisterName(FpuRegister reg) { 36973e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); 36983e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf return fpu_reg_names[reg]; 36993e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} 37003e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 37013e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf} // namespace dart 37023e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf 37033e53dc99c9f61fc1f65e85735220f0b03d2487caKarl Schimpf#endif // defined TARGET_ARCH_ARM 3704