1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_MIPS_MACRO_ASSEMBLER_MIPS_H_ 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_MIPS_MACRO_ASSEMBLER_MIPS_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/assembler.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/globals.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips64/assembler-mips64.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Give alias names to registers for calling conventions. 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kReturnRegister0 = {Register::kCode_v0}; 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kReturnRegister1 = {Register::kCode_v1}; 18109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochconst Register kReturnRegister2 = {Register::kCode_a0}; 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kJSFunctionRegister = {Register::kCode_a1}; 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kContextRegister = {Register::kCpRegister}; 21bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochconst Register kAllocateSizeRegister = {Register::kCode_a0}; 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kInterpreterAccumulatorRegister = {Register::kCode_v0}; 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kInterpreterBytecodeOffsetRegister = {Register::kCode_t0}; 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kInterpreterBytecodeArrayRegister = {Register::kCode_t1}; 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kInterpreterDispatchTableRegister = {Register::kCode_t2}; 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kJavaScriptCallArgCountRegister = {Register::kCode_a0}; 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kJavaScriptCallNewTargetRegister = {Register::kCode_a3}; 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kRuntimeCallFunctionRegister = {Register::kCode_a1}; 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Register kRuntimeCallArgCountRegister = {Register::kCode_a0}; 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Forward declaration. 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass JumpTarget; 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Reserved Register Usage Summary. 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Registers t8, t9, and at are reserved for use by the MacroAssembler. 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The programmer should know that the MacroAssembler may clobber these three, 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// but won't touch other registers except in special cases. 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Per the MIPS ABI, register t9 must be used for indirect function call 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// via 'jalr t9' or 'jr t9' instructions. This is relied upon by gcc when 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// trying to update gp register for position-independent-code. Whenever 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// MIPS generated code calls C code, it must be via t9 register. 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Flags used for LeaveExitFrame function. 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum LeaveExitFrameMode { 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EMIT_RETURN = true, 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NO_EMIT_RETURN = false 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Flags used for AllocateHeapNumber 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum TaggingMode { 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Tag the result. 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TAG_RESULT, 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't tag 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DONT_TAG_RESULT 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Flags used for the ObjectToDoubleFPURegister function. 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum ObjectToDoubleFlags { 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No special flags. 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NO_OBJECT_TO_DOUBLE_FLAGS = 0, 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Object is known to be a non smi. 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OBJECT_NOT_SMI = 1 << 0, 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't load NaNs or infinities, branch to the non number case instead. 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AVOID_NANS_AND_INFINITIES = 1 << 1 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Allow programmer to use Branch Delay Slot of Branches, Jumps, Calls. 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum BranchDelaySlot { 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE_DELAY_SLOT, 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PROTECT 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Flags used for the li macro-assembler function. 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum LiFlags { 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the constant value can be represented in just 16 bits, then 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // optimize the li to use a single instruction, rather than lui/ori/dsll 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // sequence. 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OPTIMIZE_SIZE = 0, 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Always use 6 instructions (lui/ori/dsll sequence), even if the constant 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // could be loaded with just one, so that this value is patchable later. 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CONSTANT_SIZE = 1, 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For address loads only 4 instruction are required. Used to mark 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // constant load that will be used as address without relocation 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // information. It ensures predictable code size, so specific sites 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in code are patchable. 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ADDRESS_LOAD = 2 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET }; 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK }; 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum PointersToHereCheck { 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kPointersToHereMaybeInteresting, 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kPointersToHereAreAlwaysInteresting 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum RAStatus { kRAHasNotBeenSaved, kRAHasBeenSaved }; 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister GetRegisterThatIsNotOneOf(Register reg1, 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg2 = no_reg, 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg3 = no_reg, 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg4 = no_reg, 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg5 = no_reg, 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg6 = no_reg); 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg, 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg4 = no_reg, Register reg5 = no_reg, 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg6 = no_reg, Register reg7 = no_reg, 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg8 = no_reg, Register reg9 = no_reg, 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg10 = no_reg); 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ----------------------------------------------------------------------------- 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Static helper functions. 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if defined(V8_TARGET_LITTLE_ENDIAN) 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define SmiWordOffset(offset) (offset + kPointerSize / 2) 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define SmiWordOffset(offset) offset 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochinline MemOperand ContextMemOperand(Register context, int index) { 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MemOperand(context, Context::SlotOffset(index)); 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochinline MemOperand NativeContextMemOperand() { 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ContextMemOperand(cp, Context::NATIVE_CONTEXT_INDEX); 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Generate a MemOperand for loading a field from an object. 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline MemOperand FieldMemOperand(Register object, int offset) { 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MemOperand(object, offset - kHeapObjectTag); 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline MemOperand UntagSmiMemOperand(Register rm, int offset) { 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Assumes that Smis are shifted by 32 bits. 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kSmiShift == 32); 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MemOperand(rm, SmiWordOffset(offset)); 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline MemOperand UntagSmiFieldMemOperand(Register rm, int offset) { 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return UntagSmiMemOperand(rm, offset - kHeapObjectTag); 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Generate a MemOperand for storing arguments 5..N on the stack 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// when calling CallCFunction(). 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(plind): Currently ONLY used for O32. Should be fixed for 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// n64, and used in RegExp code, and other places 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// with more than 8 arguments. 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline MemOperand CFunctionArgumentOperand(int index) { 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(index > kCArgSlotCount); 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Argument 5 takes the slot just past the four Arg-slots. 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset = (index - 5) * kPointerSize + kCArgsSlotsSize; 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MemOperand(sp, offset); 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// MacroAssembler implements a collection of frequently used macros. 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MacroAssembler: public Assembler { 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MacroAssembler(Isolate* isolate, void* buffer, int size, 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeObjectRequired create_code_object); 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Arguments macros. 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define COND_TYPED_ARGS Condition cond, Register r1, const Operand& r2 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define COND_ARGS cond, r1, r2 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cases when relocation is not needed. 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DECLARE_NORELOC_PROTOTYPE(Name, target_type) \ 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Name(target_type target, BranchDelaySlot bd = PROTECT); \ 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void Name(BranchDelaySlot bd, target_type target) { \ 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Name(target, bd); \ 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Name(target_type target, \ 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch COND_TYPED_ARGS, \ 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchDelaySlot bd = PROTECT); \ 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void Name(BranchDelaySlot bd, \ 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target_type target, \ 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch COND_TYPED_ARGS) { \ 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Name(target, COND_ARGS, bd); \ 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DECLARE_BRANCH_PROTOTYPES(Name) \ 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DECLARE_NORELOC_PROTOTYPE(Name, Label*) \ 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DECLARE_NORELOC_PROTOTYPE(Name, int32_t) 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DECLARE_BRANCH_PROTOTYPES(Branch) 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DECLARE_BRANCH_PROTOTYPES(BranchAndLink) 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DECLARE_BRANCH_PROTOTYPES(BranchShort) 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DECLARE_BRANCH_PROTOTYPES 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef COND_TYPED_ARGS 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef COND_ARGS 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Jump, Call, and Ret pseudo instructions implementing inter-working. 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define COND_ARGS Condition cond = al, Register rs = zero_reg, \ 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Jump(Register target, COND_ARGS); 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Jump(intptr_t target, RelocInfo::Mode rmode, COND_ARGS); 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Jump(Address target, RelocInfo::Mode rmode, COND_ARGS); 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Jump(Handle<Code> code, RelocInfo::Mode rmode, COND_ARGS); 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static int CallSize(Register target, COND_ARGS); 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Call(Register target, COND_ARGS); 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static int CallSize(Address target, RelocInfo::Mode rmode, COND_ARGS); 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Call(Address target, RelocInfo::Mode rmode, COND_ARGS); 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int CallSize(Handle<Code> code, 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode = RelocInfo::CODE_TARGET, 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId ast_id = TypeFeedbackId::None(), 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch COND_ARGS); 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Call(Handle<Code> code, 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode = RelocInfo::CODE_TARGET, 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId ast_id = TypeFeedbackId::None(), 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch COND_ARGS); 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Ret(COND_ARGS); 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void Ret(BranchDelaySlot bd, Condition cond = al, 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rs = zero_reg, const Operand& rt = Operand(zero_reg)) { 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Ret(cond, rs, rt, bd); 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsNear(Label* L, Condition cond, int rs_reg); 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Branch(Label* L, 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond, 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rs, 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex index, 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchDelaySlot bdslot = PROTECT); 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // GetLabelFunction must be lambda '[](size_t index) -> Label*' or a 240109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // functor/function with 'Label *func(size_t index)' declaration. 241109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch template <typename Func> 242109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void GenerateSwitchTable(Register index, size_t case_count, 243109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Func GetLabelFunction); 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef COND_ARGS 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 246f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Emit code that loads |parameter_index|'th parameter from the stack to 247f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // the register according to the CallInterfaceDescriptor definition. 248f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // |sp_to_caller_sp_offset_in_words| specifies the number of words pushed 249f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // below the caller's sp. 250f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch template <class Descriptor> 251f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void LoadParameterFromStack( 252f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Register reg, typename Descriptor::ParameterIndices parameter_index, 253f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int sp_to_ra_offset_in_words = 0) { 254f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(Descriptor::kPassLastArgsOnStack); 255f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch UNIMPLEMENTED(); 256f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 257f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit code to discard a non-negative number of pointer-sized elements 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // from the stack, clobbering only the sp register. 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Drop(int count, 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond = cc_always, 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg = no_reg, 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& op = Operand(no_reg)); 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Trivial case of DropAndRet that utilizes the delay slot and only emits 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2 instructions. 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DropAndRet(int drop); 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DropAndRet(int drop, 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond, 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg, 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& op); 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Swap two registers. If the scratch register is omitted then a slightly 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // less efficient form using xor instead of mov is emitted. 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Swap(Register reg1, Register reg2, Register scratch = no_reg); 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Call(Label* target); 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline void Move(Register dst, Handle<Object> handle) { li(dst, handle); } 2813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline void Move(Register dst, Smi* smi) { li(dst, Operand(smi)); } 282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void Move(Register dst, Register src) { 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mov(dst, src); 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline void Move_d(FPURegister dst, FPURegister src) { 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mov_d(dst, src); 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline void Move_s(FPURegister dst, FPURegister src) { 2963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (!dst.is(src)) { 2973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch mov_s(dst, src); 2983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 2993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 3003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 3013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline void Move(FPURegister dst, FPURegister src) { Move_d(dst, src); } 3023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void Move(Register dst_low, Register dst_high, FPURegister src) { 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mfc1(dst_low, src); 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mfhc1(dst_high, src); 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline void Move(Register dst, FPURegister src) { dmfc1(dst, src); } 3093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 3103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline void Move(FPURegister dst, Register src) { dmtc1(src, dst); } 3113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void FmoveHigh(Register dst_high, FPURegister src) { 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mfhc1(dst_high, src); 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void FmoveHigh(FPURegister dst, Register src_high) { 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mthc1(src_high, dst); 318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void FmoveLow(Register dst_low, FPURegister src) { 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mfc1(dst_low, src); 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void FmoveLow(FPURegister dst, Register src_low); 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void Move(FPURegister dst, Register src_low, Register src_high) { 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mtc1(src_low, dst); 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mthc1(src_high, dst); 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Move(FPURegister dst, float imm); 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Move(FPURegister dst, double imm); 333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Conditional move. 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Movz(Register rd, Register rs, Register rt); 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Movn(Register rd, Register rs, Register rt); 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Movt(Register rd, Register rs, uint16_t cc = 0); 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Movf(Register rd, Register rs, uint16_t cc = 0); 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Min, Max macros. 3413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // On pre-r6 these functions may modify at and t8 registers. 3423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void MinNaNCheck_d(FPURegister dst, FPURegister src1, FPURegister src2, 3433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label* nan = nullptr); 3443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void MaxNaNCheck_d(FPURegister dst, FPURegister src1, FPURegister src2, 3453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label* nan = nullptr); 3463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void MinNaNCheck_s(FPURegister dst, FPURegister src1, FPURegister src2, 3473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label* nan = nullptr); 3483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void MaxNaNCheck_s(FPURegister dst, FPURegister src1, FPURegister src2, 3493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label* nan = nullptr); 3503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Clz(Register rd, Register rs); 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Jump unconditionally to given label. 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We NEED a nop in the branch delay slot, as it used by v8, for example in 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // CodeGenerator::ProcessDeferred(). 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Currently the branch delay slot is filled by the MacroAssembler. 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use rather b(Label) for code generation. 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void jmp(Label* L) { 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Branch(L); 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Load(Register dst, const MemOperand& src, Representation r); 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Store(Register src, const MemOperand& dst, Representation r); 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PushRoot(Heap::RootListIndex index) { 366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadRoot(at, index); 367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(at); 368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compare the object in a register to a value and jump if they are equal. 371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void JumpIfRoot(Register with, Heap::RootListIndex index, Label* if_equal) { 372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadRoot(at, index); 373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Branch(if_equal, eq, with, Operand(at)); 374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compare the object in a register to a value and jump if they are not equal. 377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void JumpIfNotRoot(Register with, Heap::RootListIndex index, 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* if_not_equal) { 379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadRoot(at, index); 380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Branch(if_not_equal, ne, with, Operand(at)); 381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load an object from the root table. 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LoadRoot(Register destination, 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex index); 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LoadRoot(Register destination, 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex index, 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond, Register src1, const Operand& src2); 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Store an object to the root table. 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void StoreRoot(Register source, 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex index); 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void StoreRoot(Register source, 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex index, 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond, Register src1, const Operand& src2); 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // --------------------------------------------------------------------------- 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // GC Support 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IncrementalMarkingRecordWriteHelper(Register object, 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register address); 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum RememberedSetFinalAction { 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kReturnAtEnd, 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kFallThroughAtEnd 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Record in the remembered set the fact that we have a pointer to new space 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // at the address pointed to by the addr register. Only works if addr is not 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in new space. 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RememberedSetHelper(Register object, // Used for debug code. 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register addr, 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_fp, 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberedSetFinalAction and_then); 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CheckPageFlag(Register object, 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int mask, 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cc, 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* condition_met); 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if object is in new space. Jumps if the object is not in new space. 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The register scratch can be object itself, but it will be clobbered. 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfNotInNewSpace(Register object, 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* branch) { 430109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch InNewSpace(object, scratch, eq, branch); 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if object is in new space. Jumps if the object is in new space. 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The register scratch can be object itself, but scratch will be clobbered. 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfInNewSpace(Register object, 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* branch) { 438109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch InNewSpace(object, scratch, ne, branch); 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if an object has a given incremental marking color. 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void HasColor(Register object, 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch0, 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* has_color, 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int first_bit, 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int second_bit); 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfBlack(Register object, 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch0, 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_black); 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Checks the color of an object. If the object is white we jump to the 455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // incremental marker. 456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void JumpIfWhite(Register value, Register scratch1, Register scratch2, 457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch3, Label* value_is_white); 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Notify the garbage collector that we wrote a pointer into an object. 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // |object| is the object being stored into, |value| is the object being 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // stored. value and scratch registers are clobbered by the operation. 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The offset is the offset from the start of the object, not the offset from 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the tagged HeapObject pointer. For use with FieldOperand(reg, off). 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordWriteField( 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset, 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RAStatus ra_status, 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_fp, 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check = INLINE_SMI_CHECK, 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value = 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kPointersToHereMaybeInteresting); 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // As above, but the offset has the tag presubtracted. For use with 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // MemOperand(reg, off). 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void RecordWriteContextSlot( 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register context, 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset, 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RAStatus ra_status, 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_fp, 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check = INLINE_SMI_CHECK, 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value = 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kPointersToHereMaybeInteresting) { 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWriteField(context, 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset + kHeapObjectTag, 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value, 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch, 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ra_status, 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch save_fp, 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch remembered_set_action, 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch smi_check, 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pointers_to_here_check_for_value); 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 500109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Notify the garbage collector that we wrote a code entry into a 501109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // JSFunction. Only scratch is clobbered by the operation. 502109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void RecordWriteCodeEntryField(Register js_function, Register code_entry, 503109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Register scratch); 504109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordWriteForMap( 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register map, 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RAStatus ra_status, 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_fp); 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For a given |object| notify the garbage collector that the slot |address| 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // has been written. |value| is the object being stored. The value and 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // address registers are clobbered by the operation. 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordWrite( 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register address, 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RAStatus ra_status, 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_fp, 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check = INLINE_SMI_CHECK, 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value = 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kPointersToHereMaybeInteresting); 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // --------------------------------------------------------------------------- 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Inline caching support. 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GetNumberHash(Register reg0, Register scratch); 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void MarkCode(NopMarkerTypes type) { 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch nop(type); 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if the given instruction is a 'type' marker. 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // i.e. check if it is a sll zero_reg, zero_reg, <type> (referenced as 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // nop(type)). These instructions are generated to mark special location in 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the code, like some special IC code. 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline bool IsMarkedCode(Instr instr, int type) { 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER)); 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return IsNop(instr, type); 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static inline int GetCodeMarker(Instr instr) { 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t opcode = ((instr & kOpcodeMask)); 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t rt = ((instr & kRtFieldMask) >> kRtShift); 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t rs = ((instr & kRsFieldMask) >> kRsShift); 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t sa = ((instr & kSaFieldMask) >> kSaShift); 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return <n> if we have a sll zero_reg, zero_reg, n 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // else return -1. 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool sllzz = (opcode == SLL && 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rt == static_cast<uint32_t>(ToNumber(zero_reg)) && 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rs == static_cast<uint32_t>(ToNumber(zero_reg))); 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int type = 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (sllzz && FIRST_IC_MARKER <= sa && sa < LAST_CODE_MARKER) ? sa : -1; 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((type == -1) || 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER))); 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return type; 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // --------------------------------------------------------------------------- 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocation support. 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate an object in new space or old space. The object_size is 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // specified either in bytes or in words if the allocation flag SIZE_IN_WORDS 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is passed. If the space is exhausted control continues at the gc_required 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // label. The allocated object is returned in result. If the flag 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // tag_allocated_object is true the result is tagged as as a heap object. 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // All registers are clobbered also when control continues at the gc_required 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // label. 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Allocate(int object_size, 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags); 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Allocate(Register object_size, Register result, Register result_end, 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch, Label* gc_required, AllocationFlags flags); 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 586bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // FastAllocate is right now only used for folded allocations. It just 587bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // increments the top pointer without checking against limit. This can only 588bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // be done if it was proved earlier that the allocation will succeed. 589bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void FastAllocate(int object_size, Register result, Register scratch1, 590bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Register scratch2, AllocationFlags flags); 591bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 592bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void FastAllocate(Register object_size, Register result, Register result_new, 593bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Register scratch, AllocationFlags flags); 594bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AllocateTwoByteString(Register result, 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register length, 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch3, 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required); 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AllocateOneByteString(Register result, Register length, 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Register scratch2, 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch3, Label* gc_required); 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AllocateTwoByteConsString(Register result, 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register length, 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required); 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AllocateOneByteConsString(Register result, Register length, 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Register scratch2, 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required); 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AllocateTwoByteSlicedString(Register result, 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register length, 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required); 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AllocateOneByteSlicedString(Register result, Register length, 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Register scratch2, 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required); 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocates a heap number or jumps to the gc_required label if the young 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // space is full and a scavenge is needed. All registers are clobbered also 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // when control continues at the gc_required label. 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AllocateHeapNumber(Register result, 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register heap_number_map, 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MutableMode mode = IMMUTABLE); 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AllocateHeapNumberWithValue(Register result, 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister value, 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required); 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate and initialize a JSValue wrapper with the specified {constructor} 638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // and {value}. 639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void AllocateJSValue(Register result, Register constructor, Register value, 640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch1, Register scratch2, 641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* gc_required); 642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // --------------------------------------------------------------------------- 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Instruction macros. 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DEFINE_INSTRUCTION(instr) \ 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instr(Register rd, Register rs, const Operand& rt); \ 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instr(Register rd, Register rs, Register rt) { \ 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr(rd, rs, Operand(rt)); \ 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instr(Register rs, Register rt, int32_t j) { \ 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr(rs, rt, Operand(j)); \ 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DEFINE_INSTRUCTION2(instr) \ 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instr(Register rs, const Operand& rt); \ 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instr(Register rs, Register rt) { \ 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr(rs, Operand(rt)); \ 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } \ 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void instr(Register rs, int32_t j) { \ 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr(rs, Operand(j)); \ 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Addu); 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Daddu); 666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DEFINE_INSTRUCTION(Div); 667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DEFINE_INSTRUCTION(Divu); 668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DEFINE_INSTRUCTION(Ddivu); 669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DEFINE_INSTRUCTION(Mod); 670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DEFINE_INSTRUCTION(Modu); 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Ddiv); 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Subu); 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Dsubu); 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Dmod); 675958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DEFINE_INSTRUCTION(Dmodu); 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Mul); 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Mulh); 678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DEFINE_INSTRUCTION(Mulhu); 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Dmul); 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Dmulh); 681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION2(Mult); 682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION2(Dmult); 683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION2(Multu); 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION2(Dmultu); 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION2(Div); 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION2(Ddiv); 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION2(Divu); 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION2(Ddivu); 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(And); 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Or); 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Xor); 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Nor); 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION2(Neg); 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Slt); 697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Sltu); 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // MIPS32 R2 instruction macro. 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Ror); 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_INSTRUCTION(Dror); 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DEFINE_INSTRUCTION 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DEFINE_INSTRUCTION2 705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DEFINE_INSTRUCTION3 706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Load Scaled Address instructions. Parameter sa (shift argument) must be 7083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // between [1, 31] (inclusive). On pre-r6 architectures the scratch register 7093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // may be clobbered. 710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Lsa(Register rd, Register rs, Register rt, uint8_t sa, 711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch = at); 712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Dlsa(Register rd, Register rs, Register rt, uint8_t sa, 713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch = at); 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Pref(int32_t hint, const MemOperand& rs); 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // --------------------------------------------------------------------------- 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pseudo-instructions. 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 72113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Change endianness 722f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ByteSwapSigned(Register dest, Register src, int operand_size); 723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void ByteSwapUnsigned(Register dest, Register src, int operand_size); 72413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void mov(Register rd, Register rt) { or_(rd, rt, zero_reg); } 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 727bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void Ulh(Register rd, const MemOperand& rs); 728bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void Ulhu(Register rd, const MemOperand& rs); 729bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void Ush(Register rd, const MemOperand& rs, Register scratch); 730bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Ulw(Register rd, const MemOperand& rs); 732bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void Ulwu(Register rd, const MemOperand& rs); 733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Usw(Register rd, const MemOperand& rs); 734bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 735bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void Uld(Register rd, const MemOperand& rs); 736bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void Usd(Register rd, const MemOperand& rs); 737bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 738bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void Ulwc1(FPURegister fd, const MemOperand& rs, Register scratch); 739bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void Uswc1(FPURegister fd, const MemOperand& rs, Register scratch); 740bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 741bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void Uldc1(FPURegister fd, const MemOperand& rs, Register scratch); 742bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void Usdc1(FPURegister fd, const MemOperand& rs, Register scratch); 743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void LoadWordPair(Register rd, const MemOperand& rs, Register scratch = at); 745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void StoreWordPair(Register rd, const MemOperand& rs, Register scratch = at); 746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load int32 in the rd register. 748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void li(Register rd, Operand j, LiFlags mode = OPTIMIZE_SIZE); 749109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inline bool LiLower32BitHelper(Register rd, Operand j); 750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void li(Register rd, int64_t j, LiFlags mode = OPTIMIZE_SIZE) { 751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch li(rd, Operand(j), mode); 752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void li(Register dst, Handle<Object> value, LiFlags mode = OPTIMIZE_SIZE); 754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push multiple registers on the stack. 756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Registers are saved in numerical order, with higher numbered registers 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // saved in higher memory addresses. 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MultiPush(RegList regs); 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MultiPushReversed(RegList regs); 760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MultiPushFPU(RegList regs); 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MultiPushReversedFPU(RegList regs); 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void push(Register src) { 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Daddu(sp, sp, Operand(-kPointerSize)); 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sd(src, MemOperand(sp, 0)); 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Push(Register src) { push(src); } 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push a handle. 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Push(Handle<Object> handle); 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Push(Smi* smi) { Push(Handle<Smi>(smi, isolate())); } 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push two registers. Pushes leftmost register first (to highest address). 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Push(Register src1, Register src2) { 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Dsubu(sp, sp, Operand(2 * kPointerSize)); 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sd(src1, MemOperand(sp, 1 * kPointerSize)); 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sd(src2, MemOperand(sp, 0 * kPointerSize)); 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push three registers. Pushes leftmost register first (to highest address). 782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Push(Register src1, Register src2, Register src3) { 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Dsubu(sp, sp, Operand(3 * kPointerSize)); 784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sd(src1, MemOperand(sp, 2 * kPointerSize)); 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sd(src2, MemOperand(sp, 1 * kPointerSize)); 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sd(src3, MemOperand(sp, 0 * kPointerSize)); 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push four registers. Pushes leftmost register first (to highest address). 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Push(Register src1, Register src2, Register src3, Register src4) { 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Dsubu(sp, sp, Operand(4 * kPointerSize)); 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sd(src1, MemOperand(sp, 3 * kPointerSize)); 793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sd(src2, MemOperand(sp, 2 * kPointerSize)); 794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sd(src3, MemOperand(sp, 1 * kPointerSize)); 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sd(src4, MemOperand(sp, 0 * kPointerSize)); 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Push five registers. Pushes leftmost register first (to highest address). 799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Push(Register src1, Register src2, Register src3, Register src4, 800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register src5) { 801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Dsubu(sp, sp, Operand(5 * kPointerSize)); 802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sd(src1, MemOperand(sp, 4 * kPointerSize)); 803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sd(src2, MemOperand(sp, 3 * kPointerSize)); 804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sd(src3, MemOperand(sp, 2 * kPointerSize)); 805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sd(src4, MemOperand(sp, 1 * kPointerSize)); 806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sd(src5, MemOperand(sp, 0 * kPointerSize)); 807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Push(Register src, Condition cond, Register tst1, Register tst2) { 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Since we don't have conditional execution we use a Branch. 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Branch(3, cond, tst1, Operand(tst2)); 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Dsubu(sp, sp, Operand(kPointerSize)); 813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sd(src, MemOperand(sp, 0)); 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PushRegisterAsTwoSmis(Register src, Register scratch = at); 817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PopRegisterAsTwoSmis(Register dst, Register scratch = at); 818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pops multiple values from the stack and load them in the 820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // registers specified in regs. Pop order is the opposite as in MultiPush. 821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MultiPop(RegList regs); 822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MultiPopReversed(RegList regs); 823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MultiPopFPU(RegList regs); 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MultiPopReversedFPU(RegList regs); 826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pop(Register dst) { 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ld(dst, MemOperand(sp, 0)); 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Daddu(sp, sp, Operand(kPointerSize)); 830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Pop(Register dst) { pop(dst); } 832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pop two registers. Pops rightmost register first (from lower address). 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Pop(Register src1, Register src2) { 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(src2)); 836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ld(src2, MemOperand(sp, 0 * kPointerSize)); 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ld(src1, MemOperand(sp, 1 * kPointerSize)); 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Daddu(sp, sp, 2 * kPointerSize); 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pop three registers. Pops rightmost register first (from lower address). 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Pop(Register src1, Register src2, Register src3) { 843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ld(src3, MemOperand(sp, 0 * kPointerSize)); 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ld(src2, MemOperand(sp, 1 * kPointerSize)); 845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ld(src1, MemOperand(sp, 2 * kPointerSize)); 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Daddu(sp, sp, 3 * kPointerSize); 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Pop(uint32_t count = 1) { 850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Daddu(sp, sp, Operand(count * kPointerSize)); 851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Push a fixed frame, consisting of ra, fp. 8543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void PushCommonFrame(Register marker_reg = no_reg); 8553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 8563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Push a standard frame, consisting of ra, fp, context and JS function. 8573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void PushStandardFrame(Register function_reg); 8583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 8593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void PopCommonFrame(Register marker_reg = no_reg); 8603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Push and pop the registers that can hold pointers, as defined by the 862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // RegList constant kSafepointSavedRegisters. 863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PushSafepointRegisters(); 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PopSafepointRegisters(); 865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Store value in register src in the safepoint stack slot for 866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // register dst. 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void StoreToSafepointRegisterSlot(Register src, Register dst); 868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the value of the src register from its safepoint stack slot 869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // into register dst. 870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LoadFromSafepointRegisterSlot(Register dst, Register src); 871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // MIPS64 R2 instruction macro. 873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Ins(Register rt, Register rs, uint16_t pos, uint16_t size); 874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Dins(Register rt, Register rs, uint16_t pos, uint16_t size); 875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Ext(Register rt, Register rs, uint16_t pos, uint16_t size); 876c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 877c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void ExtractBits(Register rt, Register rs, uint16_t pos, uint16_t size); 878c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 879958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Dext(Register rt, Register rs, uint16_t pos, uint16_t size); 880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Dextm(Register rt, Register rs, uint16_t pos, uint16_t size); 881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Dextu(Register rt, Register rs, uint16_t pos, uint16_t size); 882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void Neg_s(FPURegister fd, FPURegister fs); 883f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void Neg_d(FPURegister fd, FPURegister fs); 884f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 885f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // MIPS64 R6 instruction macros. 886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void Bovc(Register rt, Register rs, Label* L); 887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void Bnvc(Register rt, Register rs, Label* L); 888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // --------------------------------------------------------------------------- 890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // FPU macros. These do not handle special cases like NaN or +- inf. 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert unsigned word to double. 893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Cvt_d_uw(FPURegister fd, FPURegister fs); 894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Cvt_d_uw(FPURegister fd, Register rs); 895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Convert unsigned long to double. 897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Cvt_d_ul(FPURegister fd, FPURegister fs); 898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Cvt_d_ul(FPURegister fd, Register rs); 899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 900109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Convert unsigned word to float. 901109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void Cvt_s_uw(FPURegister fd, FPURegister fs); 902109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void Cvt_s_uw(FPURegister fd, Register rs); 903109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Convert unsigned long to float. 905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Cvt_s_ul(FPURegister fd, FPURegister fs); 906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Cvt_s_ul(FPURegister fd, Register rs); 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert double to unsigned long. 909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Trunc_l_ud(FPURegister fd, FPURegister fs, FPURegister scratch); 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Trunc_l_d(FPURegister fd, FPURegister fs); 912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Round_l_d(FPURegister fd, FPURegister fs); 913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Floor_l_d(FPURegister fd, FPURegister fs); 914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Ceil_l_d(FPURegister fd, FPURegister fs); 915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert double to unsigned word. 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Trunc_uw_d(FPURegister fd, FPURegister fs, FPURegister scratch); 918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Trunc_uw_d(FPURegister fd, Register rs, FPURegister scratch); 919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 920109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Convert single to unsigned word. 921109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void Trunc_uw_s(FPURegister fd, FPURegister fs, FPURegister scratch); 922109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void Trunc_uw_s(FPURegister fd, Register rs, FPURegister scratch); 923109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Convert double to unsigned long. 925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Trunc_ul_d(FPURegister fd, FPURegister fs, FPURegister scratch, 926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register result = no_reg); 927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Trunc_ul_d(FPURegister fd, Register rs, FPURegister scratch, 928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register result = no_reg); 929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Convert single to unsigned long. 931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Trunc_ul_s(FPURegister fd, FPURegister fs, FPURegister scratch, 932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register result = no_reg); 933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Trunc_ul_s(FPURegister fd, Register rs, FPURegister scratch, 934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register result = no_reg); 935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Trunc_w_d(FPURegister fd, FPURegister fs); 937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Round_w_d(FPURegister fd, FPURegister fs); 938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Floor_w_d(FPURegister fd, FPURegister fs); 939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Ceil_w_d(FPURegister fd, FPURegister fs); 940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 94113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Preserve value of a NaN operand 94213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void SubNanPreservePayloadAndSign_s(FPURegister fd, FPURegister fs, 94313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FPURegister ft); 94413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void SubNanPreservePayloadAndSign_d(FPURegister fd, FPURegister fs, 94513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FPURegister ft); 94613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Madd_d(FPURegister fd, 948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister fr, 949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister fs, 950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister ft, 951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister scratch); 952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Wrapper functions for the different cmp/branch types. 954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void BranchF32(Label* target, Label* nan, Condition cc, 955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister cmp1, FPURegister cmp2, 956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchDelaySlot bd = PROTECT) { 957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchFCommon(S, target, nan, cc, cmp1, cmp2, bd); 958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void BranchF64(Label* target, Label* nan, Condition cc, 961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister cmp1, FPURegister cmp2, 962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchDelaySlot bd = PROTECT) { 963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchFCommon(D, target, nan, cc, cmp1, cmp2, bd); 964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Alternate (inline) version for better readability with USE_DELAY_SLOT. 967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void BranchF64(BranchDelaySlot bd, Label* target, Label* nan, 968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Condition cc, FPURegister cmp1, FPURegister cmp2) { 969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchF64(target, nan, cc, cmp1, cmp2, bd); 970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void BranchF32(BranchDelaySlot bd, Label* target, Label* nan, 973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Condition cc, FPURegister cmp1, FPURegister cmp2) { 974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchF32(target, nan, cc, cmp1, cmp2, bd); 975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Alias functions for backward compatibility. 978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void BranchF(Label* target, Label* nan, Condition cc, FPURegister cmp1, 979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister cmp2, BranchDelaySlot bd = PROTECT) { 980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchF64(target, nan, cc, cmp1, cmp2, bd); 981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void BranchF(BranchDelaySlot bd, Label* target, Label* nan, 984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Condition cc, FPURegister cmp1, FPURegister cmp2) { 985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchF64(bd, target, nan, cc, cmp1, cmp2); 986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Truncates a double using a specific rounding mode, and writes the value 989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to the result register. 990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The except_flag will contain any exceptions caused by the instruction. 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If check_inexact is kDontCheckForInexactConversion, then the inexact 992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // exception is masked. 993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitFPUTruncate(FPURoundingMode rounding_mode, 994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoubleRegister double_input, 996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoubleRegister double_scratch, 998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register except_flag, 999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckForInexactConversion check_inexact 1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch = kDontCheckForInexactConversion); 1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Performs a truncating conversion of a floating point number as used by 1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the JS bitwise operations. See ECMA-262 9.5: ToInt32. Goes to 'done' if it 1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // succeeds, otherwise falls through if result is saturated. On return 1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 'result' either holds answer, or is clobbered on fall through. 1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Only public for the test code in test-code-stubs-arm.cc. 1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TryInlineTruncateDoubleToI(Register result, 1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoubleRegister input, 1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* done); 1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Performs a truncating conversion of a floating point number as used by 1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the JS bitwise operations. See ECMA-262 9.5: ToInt32. 1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Exits with 'result' holding the answer. 1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TruncateDoubleToI(Register result, DoubleRegister double_input); 1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Performs a truncating conversion of a heap number as used by 1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the JS bitwise operations. See ECMA-262 9.5: ToInt32. 'result' and 'input' 1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // must be different registers. Exits with 'result' holding the answer. 1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TruncateHeapNumberToI(Register result, Register object); 1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Converts the smi or heap number in object to an int32 using the rules 1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for ToInt32 as described in ECMAScript 9.5.: the value is truncated 1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and brought into the range -2^31 .. +2^31 - 1. 'result' and 'input' must be 1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // different registers. 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TruncateNumberToI(Register object, 1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register heap_number_map, 1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_int32); 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Loads the number from object into dst register. 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If |object| is neither smi nor heap number, |not_number| is jumped to 1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // with |object| still intact. 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LoadNumber(Register object, 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister dst, 1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register heap_number_map, 1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_number); 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Loads the number from object into double_dst in the double format. 1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Control will jump to not_int32 if the value cannot be exactly represented 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // by a 32-bit integer. 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Floating point value in the 32-bit integer range that are not exact integer 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // won't be loaded. 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LoadNumberAsInt32Double(Register object, 1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoubleRegister double_dst, 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register heap_number_map, 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister double_scratch, 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_int32); 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Loads the number from object into dst as a 32-bit integer. 1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Control will jump to not_int32 if the object cannot be exactly represented 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // by a 32-bit integer. 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Floating point value in the 32-bit integer range that are not exact integer 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // won't be converted. 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LoadNumberAsInt32(Register object, 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register heap_number_map, 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister double_scratch0, 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister double_scratch1, 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_int32); 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Enter exit frame. 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // argc - argument count to be dropped by LeaveExitFrame. 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // save_doubles - saves FPU registers on stack, currently disabled. 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // stack_space - extra stack space. 1072f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void EnterExitFrame(bool save_doubles, int stack_space = 0, 1073f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch StackFrame::Type frame_type = StackFrame::EXIT); 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Leave the current exit frame. 1076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void LeaveExitFrame(bool save_doubles, Register arg_count, 1077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool restore_context, bool do_return = NO_EMIT_RETURN, 1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool argument_count_is_length = false); 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get the actual activation frame alignment for target environment. 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static int ActivationFrameAlignment(); 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure the stack is aligned. Only emits code in debug mode. 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AssertStackIsAligned(); 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LoadContext(Register dst, int context_chain_length); 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Load the global object from the current context. 1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void LoadGlobalObject(Register dst) { 1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadNativeContextSlot(Context::EXTENSION_INDEX, dst); 1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Load the global proxy from the current context. 1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void LoadGlobalProxy(Register dst) { 1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadNativeContextSlot(Context::GLOBAL_PROXY_INDEX, dst); 1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Conditionally load the cached Array transitioned map of type 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // transitioned_kind from the native context if the map in register 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // map_in_out is the cached Array map in the native context of 1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // expected_kind. 1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LoadTransitionedArrayMapConditional( 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind expected_kind, 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind transitioned_kind, 1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register map_in_out, 1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* no_map_match); 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void LoadNativeContextSlot(int index, Register dst); 1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the initial map from the global function. The registers 1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // function and map can be the same, function is then overwritten. 1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LoadGlobalFunctionInitialMap(Register function, 1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register map, 1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch); 1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InitializeRootRegister() { 1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference roots_array_start = 1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::roots_array_start(isolate()); 1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch li(kRootRegister, Operand(roots_array_start)); 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ------------------------------------------------------------------------- 1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JavaScript invokes. 1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Removes current frame and its arguments from the stack preserving 11273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // the arguments and a return address pushed to the stack for the next call. 11283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Both |callee_args_count| and |caller_args_count_reg| do not include 11293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // receiver. |callee_args_count| is not modified, |caller_args_count_reg| 11303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // is trashed. 11313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void PrepareForTailCall(const ParameterCount& callee_args_count, 11323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register caller_args_count_reg, Register scratch0, 11333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch1); 11343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Invoke the JavaScript function code by either calling or jumping. 1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void InvokeFunctionCode(Register function, Register new_target, 1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, InvokeFlag flag, 1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper); 1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void FloodFunctionIfStepping(Register fun, Register new_target, 1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual); 1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Invoke the JavaScript function in the given register. Changes the 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // current context to the context in the function before invoking. 1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InvokeFunction(Register function, 1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register new_target, 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ParameterCount& actual, 1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InvokeFlag flag, 1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CallWrapper& call_wrapper); 1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InvokeFunction(Register function, 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ParameterCount& expected, 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ParameterCount& actual, 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InvokeFlag flag, 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CallWrapper& call_wrapper); 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InvokeFunction(Handle<JSFunction> function, 1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ParameterCount& expected, 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ParameterCount& actual, 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InvokeFlag flag, 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CallWrapper& call_wrapper); 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IsObjectJSStringType(Register object, 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* fail); 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IsObjectNameType(Register object, 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* fail); 1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ------------------------------------------------------------------------- 1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Debugger Support. 1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DebugBreak(); 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ------------------------------------------------------------------------- 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Exception handling. 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Push a new stack handler and link into stack handler chain. 1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PushStackHandler(); 1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unlink the stack handler on top of the stack from the stack handler chain. 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Must preserve the result register. 1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PopStackHandler(); 1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Initialize fields with filler values. Fields starting at |current_address| 1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // not including |end_address| are overwritten with the value in |filler|. At 1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the end the loop, |current_address| takes the value of |end_address|. 1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void InitializeFieldsWithFiller(Register current_address, 1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register end_address, Register filler); 1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ------------------------------------------------------------------------- 1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Support functions. 1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Machine code version of Map::GetConstructor(). 1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // |temp| holds |result|'s map when done, and |temp2| its instance type. 1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void GetMapConstructor(Register result, Register map, Register temp, 1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register temp2); 1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Try to get function prototype of a function and puts the value in 1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the result register. Checks that the function really is a 1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // function and jumps to the miss label if the fast checks fail. The 1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // function register will be untouched; the other registers may be 1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // clobbered. 1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void TryGetFunctionPrototype(Register function, Register result, 1209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch, Label* miss); 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GetObjectType(Register function, 1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register map, 1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register type_reg); 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1215109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void GetInstanceType(Register object_map, Register object_instance_type) { 1216109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch lbu(object_instance_type, 1217109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldMemOperand(object_map, Map::kInstanceTypeOffset)); 1218109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1219109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if a map for a JSObject indicates that the object can have both smi 1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and HeapObject elements. Jump to the specified label if it does not. 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CheckFastObjectElements(Register map, 1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* fail); 1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if a map for a JSObject indicates that the object has fast smi only 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // elements. Jump to the specified label if it does not. 1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CheckFastSmiElements(Register map, 1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* fail); 1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check to see if maybe_number can be stored as a double in 1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // FastDoubleElements. If it can, store it at the index specified by key in 1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the FastDoubleElements array elements. Otherwise jump to fail. 1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void StoreNumberToDoubleElements(Register value_reg, 1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register key_reg, 1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register elements_reg, 1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* fail, 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_offset = 0); 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compare an object's map with the specified map and its transitioned 1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. Jumps to 1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // "branch_to" if the result of the comparison is "cond". If multiple map 1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // compares are required, the compare sequences branches to early_success. 1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CompareMapAndBranch(Register obj, 1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map, 1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* early_success, 1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond, 1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* branch_to); 1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // As above, but the map of the object is already loaded into the register 1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // which is preserved by the code generated. 1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CompareMapAndBranch(Register obj_map, 1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map, 1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* early_success, 1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond, 1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* branch_to); 1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if the map of an object is equal to a specified map and branch to 1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // label if not. Skip the smi check if not required (object is known to be a 1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match 1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // against maps that are ElementsKind transition maps of the specificed map. 1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CheckMap(Register obj, 1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map, 1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* fail, 1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheckType smi_check_type); 1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CheckMap(Register obj, 1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex index, 1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* fail, 1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheckType smi_check_type); 1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check if the map of an object is equal to a specified weak map and branch 1280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // to a specified target if equal. Skip the smi check if not required 1281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // (object is known to be a heap object) 1282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void DispatchWeakMap(Register obj, Register scratch1, Register scratch2, 1283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<WeakCell> cell, Handle<Code> success, 1284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SmiCheckType smi_check_type); 1285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the value is a NaN, canonicalize the value else, do nothing. 1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void FPUCanonicalizeNaN(const DoubleRegister dst, const DoubleRegister src); 1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Get value of the weak cell. 1291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void GetWeakValue(Register value, Handle<WeakCell> cell); 1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Load the value of the weak cell in the value register. Branch to the 1294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // given miss label is the weak cell was cleared. 1295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss); 1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load and check the instance type of an object for being a string. 1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Loads the type into the second argument register. 1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns a condition that will be enabled if the object was a string. 1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition IsObjectStringType(Register obj, 1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register type, 1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result) { 1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ld(type, FieldMemOperand(obj, HeapObject::kMapOffset)); 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lbu(type, FieldMemOperand(type, Map::kInstanceTypeOffset)); 1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch And(type, type, Operand(kIsNotStringMask)); 1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0u, kStringTag); 1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return eq; 1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get the number of least significant bits from a register. 1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits); 1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GetLeastBitsFromInt32(Register dst, Register src, int mun_least_bits); 1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the value of a number object into a FPU double register. If the 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // object is not a number a jump to the label not_number is performed 1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and the FPU double register is unchanged. 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ObjectToDoubleFPURegister( 1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister value, 1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register heap_number_map, 1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_number, 1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ObjectToDoubleFlags flags = NO_OBJECT_TO_DOUBLE_FLAGS); 1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the value of a smi object into a FPU double register. The register 1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // scratch1 can be the same register as smi in which case smi will hold the 1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // untagged value afterwards. 1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SmiToDoubleFPURegister(Register smi, 1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPURegister value, 1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1); 1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ------------------------------------------------------------------------- 1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Overflow handling functions. 1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Usage: first call the appropriate arithmetic function, then call one of the 1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // jump functions with the overflow_dst register as the second parameter. 1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 13383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline void AddBranchOvf(Register dst, Register left, const Operand& right, 13393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label* overflow_label, Register scratch = at) { 13403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AddBranchOvf(dst, left, right, overflow_label, nullptr, scratch); 13413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 13423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 13433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline void AddBranchNoOvf(Register dst, Register left, const Operand& right, 13443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label* no_overflow_label, Register scratch = at) { 13453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AddBranchOvf(dst, left, right, nullptr, no_overflow_label, scratch); 13463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 13483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void AddBranchOvf(Register dst, Register left, const Operand& right, 13493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label* overflow_label, Label* no_overflow_label, 13503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch = at); 1351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 13523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void AddBranchOvf(Register dst, Register left, Register right, 13533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label* overflow_label, Label* no_overflow_label, 13543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch = at); 1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 13563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline void SubBranchOvf(Register dst, Register left, const Operand& right, 13573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label* overflow_label, Register scratch = at) { 13583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch SubBranchOvf(dst, left, right, overflow_label, nullptr, scratch); 13593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 1360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 13613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inline void SubBranchNoOvf(Register dst, Register left, const Operand& right, 13623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label* no_overflow_label, Register scratch = at) { 13633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch SubBranchOvf(dst, left, right, nullptr, no_overflow_label, scratch); 13643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 13663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void SubBranchOvf(Register dst, Register left, const Operand& right, 13673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label* overflow_label, Label* no_overflow_label, 13683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch = at); 13693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 13703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void SubBranchOvf(Register dst, Register left, Register right, 13713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label* overflow_label, Label* no_overflow_label, 13723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch = at); 1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1374f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inline void MulBranchOvf(Register dst, Register left, const Operand& right, 1375f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label* overflow_label, Register scratch = at) { 1376f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MulBranchOvf(dst, left, right, overflow_label, nullptr, scratch); 1377f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1378f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1379f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inline void MulBranchNoOvf(Register dst, Register left, const Operand& right, 1380f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label* no_overflow_label, Register scratch = at) { 1381f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MulBranchOvf(dst, left, right, nullptr, no_overflow_label, scratch); 1382f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1383f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1384f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void MulBranchOvf(Register dst, Register left, const Operand& right, 1385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label* overflow_label, Label* no_overflow_label, 1386f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Register scratch = at); 1387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1388f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void MulBranchOvf(Register dst, Register left, Register right, 1389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label* overflow_label, Label* no_overflow_label, 1390f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Register scratch = at); 1391f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void DaddBranchOvf(Register dst, Register left, const Operand& right, 1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* overflow_label, Register scratch = at) { 1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DaddBranchOvf(dst, left, right, overflow_label, nullptr, scratch); 1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void DaddBranchNoOvf(Register dst, Register left, const Operand& right, 1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* no_overflow_label, Register scratch = at) { 1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DaddBranchOvf(dst, left, right, nullptr, no_overflow_label, scratch); 1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DaddBranchOvf(Register dst, Register left, const Operand& right, 1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* overflow_label, Label* no_overflow_label, 1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch = at); 1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DaddBranchOvf(Register dst, Register left, Register right, 1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* overflow_label, Label* no_overflow_label, 1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch = at); 1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void DsubBranchOvf(Register dst, Register left, const Operand& right, 1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* overflow_label, Register scratch = at) { 1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DsubBranchOvf(dst, left, right, overflow_label, nullptr, scratch); 1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline void DsubBranchNoOvf(Register dst, Register left, const Operand& right, 1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* no_overflow_label, Register scratch = at) { 1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DsubBranchOvf(dst, left, right, nullptr, no_overflow_label, scratch); 1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DsubBranchOvf(Register dst, Register left, const Operand& right, 1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* overflow_label, Label* no_overflow_label, 1422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch = at); 1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DsubBranchOvf(Register dst, Register left, Register right, 1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* overflow_label, Label* no_overflow_label, 1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch = at); 1427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BranchOnOverflow(Label* label, 1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register overflow_check, 1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchDelaySlot bd = PROTECT) { 1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Branch(label, lt, overflow_check, Operand(zero_reg), bd); 1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BranchOnNoOverflow(Label* label, 1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register overflow_check, 1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchDelaySlot bd = PROTECT) { 1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Branch(label, ge, overflow_check, Operand(zero_reg), bd); 1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RetOnOverflow(Register overflow_check, BranchDelaySlot bd = PROTECT) { 1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Ret(lt, overflow_check, Operand(zero_reg), bd); 1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RetOnNoOverflow(Register overflow_check, BranchDelaySlot bd = PROTECT) { 1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Ret(ge, overflow_check, Operand(zero_reg), bd); 1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ------------------------------------------------------------------------- 1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Runtime calls. 1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // See comments at the beginning of CEntryStub::Generate. 1452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline void PrepareCEntryArgs(int num_args) { li(a0, num_args); } 1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void PrepareCEntryFunction(const ExternalReference& ref) { 1455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier li(a1, Operand(ref)); 1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define COND_ARGS Condition cond = al, Register rs = zero_reg, \ 1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT 1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Call a code stub. 1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallStub(CodeStub* stub, 1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId ast_id = TypeFeedbackId::None(), 1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch COND_ARGS); 1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Tail call a code stub (jump). 1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TailCallStub(CodeStub* stub, COND_ARGS); 1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef COND_ARGS 1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallJSExitStub(CodeStub* stub); 1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Call a runtime routine. 1474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void CallRuntime(const Runtime::Function* f, int num_arguments, 1475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SaveFPRegsMode save_doubles = kDontSaveFPRegs, 1476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchDelaySlot bd = PROTECT); 1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void CallRuntimeSaveDoubles(Runtime::FunctionId fid) { 1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Runtime::Function* function = Runtime::FunctionForId(fid); 1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime(function, function->nargs, kSaveFPRegs); 1480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convenience function: Same as above, but takes the fid instead. 1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void CallRuntime(Runtime::FunctionId fid, 1484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SaveFPRegsMode save_doubles = kDontSaveFPRegs, 1485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchDelaySlot bd = PROTECT) { 1486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Runtime::Function* function = Runtime::FunctionForId(fid); 1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallRuntime(function, function->nargs, save_doubles, bd); 1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Convenience function: Same as above, but takes the fid instead. 1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void CallRuntime(Runtime::FunctionId fid, int num_arguments, 1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SaveFPRegsMode save_doubles = kDontSaveFPRegs, 1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchDelaySlot bd = PROTECT) { 1494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallRuntime(Runtime::FunctionForId(fid), num_arguments, save_doubles, bd); 1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convenience function: call an external reference. 1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallExternalReference(const ExternalReference& ext, 1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int num_arguments, 1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchDelaySlot bd = PROTECT); 1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convenience function: tail call a runtime routine (jump). 1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void TailCallRuntime(Runtime::FunctionId fid); 1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int CalculateStackPassedWords(int num_reg_arguments, 1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int num_double_arguments); 1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Before calling a C-function from generated code, align arguments on stack 1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and add space for the four mips argument slots. 1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // After aligning the frame, non-register arguments must be stored on the 1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // stack, after the argument-slots using helper: CFunctionArgumentOperand(). 1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The argument count assumes all arguments are word sized. 1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Some compilers/platforms require the stack to be aligned when calling 1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // C++ code. 1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Needs a scratch register to do some arithmetic. This register will be 1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // trashed. 1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PrepareCallCFunction(int num_reg_arguments, 1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int num_double_registers, 1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch); 1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PrepareCallCFunction(int num_reg_arguments, 1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch); 1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Arguments 1-4 are placed in registers a0 thru a3 respectively. 1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Arguments 5..n are stored to stack using following: 1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // sw(a4, CFunctionArgumentOperand(5)); 1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calls a C function and cleans up the space for arguments allocated 1528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // by PrepareCallCFunction. The called function is not allowed to trigger a 1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // garbage collection, since that might move the code and invalidate the 1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // return address (unless this is somehow accounted for by the called 1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // function). 1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallCFunction(ExternalReference function, int num_arguments); 1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallCFunction(Register function, int num_arguments); 1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallCFunction(ExternalReference function, 1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int num_reg_arguments, 1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int num_double_arguments); 1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallCFunction(Register function, 1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int num_reg_arguments, 1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int num_double_arguments); 1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MovFromFloatResult(DoubleRegister dst); 1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MovFromFloatParameter(DoubleRegister dst); 1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // There are two ways of passing double arguments on MIPS, depending on 1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // whether soft or hard floating point ABI is used. These functions 1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // abstract parameter passing for the three different ways we call 1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // C functions from generated code. 1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MovToFloatParameter(DoubleRegister src); 1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MovToFloatParameters(DoubleRegister src1, DoubleRegister src2); 1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MovToFloatResult(DoubleRegister src); 1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Jump to the builtin routine. 1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpToExternalReference(const ExternalReference& builtin, 1553f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BranchDelaySlot bd = PROTECT, 1554f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool builtin_exit_frame = false); 1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch struct Unresolved { 1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int pc; 1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t flags; // See Bootstrapper::FixupFlags decoders/encoders. 1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* name; 1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> CodeObject() { 1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!code_object_.is_null()); 1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return code_object_; 1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit code for a truncating division by a constant. The dividend register is 1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // unchanged and at gets clobbered. Dividend and result must be different. 1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TruncatingDiv(Register result, Register dividend, int32_t divisor); 1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ------------------------------------------------------------------------- 1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // StatsCounter support. 1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetCounter(StatsCounter* counter, int value, 1575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Register scratch2); 1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void IncrementCounter(StatsCounter* counter, int value, 1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Register scratch2); 1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DecrementCounter(StatsCounter* counter, int value, 1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Register scratch2); 1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ------------------------------------------------------------------------- 1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Debugging. 1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calls Abort(msg) if the condition cc is not satisfied. 1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use --debug_code to enable. 1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Assert(Condition cc, BailoutReason reason, Register rs, Operand rt); 1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AssertFastElements(Register elements); 1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Like Assert(), but always enabled. 1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Check(Condition cc, BailoutReason reason, Register rs, Operand rt); 1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Print a message to stdout and abort execution. 1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Abort(BailoutReason msg); 1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Verify restrictions about code generated in stubs. 1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_generating_stub(bool value) { generating_stub_ = value; } 1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool generating_stub() { return generating_stub_; } 1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_has_frame(bool value) { has_frame_ = value; } 1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_frame() { return has_frame_; } 1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool AllowThisStubCall(CodeStub* stub); 1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // --------------------------------------------------------------------------- 1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Number utilities. 1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check whether the value of reg is a power of two and not zero. If not 1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // control continues at the label not_power_of_two. If reg is a power of two 1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the register scratch contains the value of (reg - 1) when control falls 1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // through. 1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfNotPowerOfTwoOrZero(Register reg, 1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_power_of_two_or_zero); 1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ------------------------------------------------------------------------- 1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Smi utilities. 1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Test for overflow < 0: use BranchOnOverflow() or BranchOnNoOverflow(). 1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SmiTagCheckOverflow(Register reg, Register overflow); 1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SmiTagCheckOverflow(Register dst, Register src, Register overflow); 1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SmiTag(Register dst, Register src) { 1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kSmiShift == 32); 1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dsll32(dst, src, 0); 1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Addu(dst, src, src); 1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SmiTag(Register reg) { 1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiTag(reg, reg); 1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Try to convert int32 to smi. If the value is to large, preserve 1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the original value and jump to not_a_smi. Destroys scratch and 1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // sets flags. 1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TrySmiTag(Register reg, Register scratch, Label* not_a_smi) { 1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TrySmiTag(reg, reg, scratch, not_a_smi); 1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void TrySmiTag(Register dst, 1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src, 1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_a_smi) { 1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiTag(dst, src); 1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiTagCheckOverflow(at, src, scratch); 1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchOnOverflow(not_a_smi, scratch); 1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mov(dst, at); 1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SmiUntag(Register dst, Register src) { 1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kSmiShift == 32); 1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dsra32(dst, src, 0); 1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sra(dst, src, kSmiTagSize); 1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SmiUntag(Register reg) { 1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiUntag(reg, reg); 1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Left-shifted from int32 equivalent of Smi. 1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SmiScale(Register dst, Register src, int scale) { 1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The int portion is upper 32-bits of 64-bit word. 1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dsra(dst, src, kSmiShift - scale); 1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(scale >= kSmiTagSize); 1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sll(dst, src, scale - kSmiTagSize); 1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Combine load with untagging or scaling. 1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SmiLoadUntag(Register dst, MemOperand src); 1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SmiLoadScale(Register dst, MemOperand src, int scale); 1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns 2 values: the Smi and a scaled version of the int within the Smi. 1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SmiLoadWithScale(Register d_smi, 1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register d_scaled, 1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemOperand src, 1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int scale); 1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns 2 values: the untagged Smi (int32) and scaled version of that int. 1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SmiLoadUntagWithScale(Register d_int, 1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register d_scaled, 1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemOperand src, 1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int scale); 1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Test if the register contains a smi. 1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void SmiTst(Register value, Register scratch) { 1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch And(scratch, value, Operand(kSmiTagMask)); 1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void NonNegativeSmiTst(Register value, Register scratch) { 1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch And(scratch, value, Operand(kSmiTagMask | kSmiSignMask)); 1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Untag the source value into destination and jump if source is a smi. 1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Source and destination can be the same register. 1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case); 1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Untag the source value into destination and jump if source is not a smi. 1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Source and destination can be the same register. 1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void UntagAndJumpIfNotSmi(Register dst, Register src, Label* non_smi_case); 1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Jump the register contains a smi. 1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfSmi(Register value, 1715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* smi_label, 1716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch = at, 1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchDelaySlot bd = PROTECT); 1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Jump if the register contains a non-smi. 1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfNotSmi(Register value, 1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_smi_label, 1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch = at, 1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BranchDelaySlot bd = PROTECT); 1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Jump if either of the registers contain a non-smi. 1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi); 1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Jump if either of the registers contain a smi. 1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi); 1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 17303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Abort execution if argument is a number, enabled via --debug-code. 17313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void AssertNotNumber(Register object); 17323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Abort execution if argument is a smi, enabled via --debug-code. 1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AssertNotSmi(Register object); 1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AssertSmi(Register object); 1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Abort execution if argument is not a string, enabled via --debug-code. 1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AssertString(Register object); 1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Abort execution if argument is not a name, enabled via --debug-code. 1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AssertName(Register object); 1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Abort execution if argument is not a JSFunction, enabled via --debug-code. 1744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void AssertFunction(Register object); 1745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Abort execution if argument is not a JSBoundFunction, 1747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // enabled via --debug-code. 1748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void AssertBoundFunction(Register object); 1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1750bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Abort execution if argument is not a JSGeneratorObject, 1751bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // enabled via --debug-code. 1752bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch void AssertGeneratorObject(Register object); 1753bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1754109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Abort execution if argument is not a JSReceiver, enabled via --debug-code. 1755109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void AssertReceiver(Register object); 1756109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Abort execution if argument is not undefined or an AllocationSite, enabled 1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // via --debug-code. 1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AssertUndefinedOrAllocationSite(Register object, Register scratch); 1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Abort execution if reg is not the root value with the given index, 1762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // enabled via --debug-code. 1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AssertIsRoot(Register reg, Heap::RootListIndex index); 1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // --------------------------------------------------------------------------- 1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // HeapNumber utilities. 1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfNotHeapNumber(Register object, 1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register heap_number_map, 1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_heap_number); 1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ------------------------------------------------------------------------- 1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // String utilities. 1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Checks if both instance types are sequential one-byte strings and jumps to 1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // label if either is not. 1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfBothInstanceTypesAreNotSequentialOneByte( 1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register first_object_instance_type, Register second_object_instance_type, 1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Register scratch2, Label* failure); 1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if instance type is sequential one-byte string and jump to label if 1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // it is not. 1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfInstanceTypeIsNotSequentialOneByte(Register type, Register scratch, 1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* failure); 1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name); 1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitSeqStringSetCharCheck(Register string, 1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register index, 1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t encoding_mask); 1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Checks if both objects are sequential one-byte strings and jumps to label 1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // if either is not. Assumes that neither object is a smi. 1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfNonSmisNotBothSequentialOneByteStrings(Register first, 1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register second, 1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* failure); 1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Checks if both objects are sequential one-byte strings and jumps to label 1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // if either is not. 1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfNotBothSequentialOneByteStrings(Register first, Register second, 1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_flat_one_byte_strings); 1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClampUint8(Register output_reg, Register input_reg); 1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void ClampDoubleToUint8(Register result_reg, 1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoubleRegister input_reg, 1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoubleRegister temp_double_reg); 1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LoadInstanceDescriptors(Register map, Register descriptors); 1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EnumLength(Register dst, Register map); 1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void NumberOfOwnDescriptors(Register dst, Register map); 1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void LoadAccessor(Register dst, Register holder, int accessor_index, 1821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AccessorComponent accessor); 1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<typename Field> 1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DecodeField(Register dst, Register src) { 1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Ext(dst, src, Field::kShift, Field::kSize); 1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<typename Field> 1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DecodeField(Register reg) { 1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DecodeField<Field>(reg, reg); 1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<typename Field> 1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DecodeFieldToSmi(Register dst, Register src) { 1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int shift = Field::kShift; 1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int mask = Field::kMask >> shift; 1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dsrl(dst, src, shift); 1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch And(dst, dst, Operand(mask)); 1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dsll32(dst, dst, 0); 1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<typename Field> 1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DecodeFieldToSmi(Register reg) { 1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DecodeField<Field>(reg, reg); 1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generates function and stub prologue code. 18473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void StubPrologue(StackFrame::Type type); 1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Prologue(bool code_pre_aging); 1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Load the type feedback vector from a JavaScript frame. 1851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EmitLoadTypeFeedbackVector(Register vector); 1852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Activation support. 1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EnterFrame(StackFrame::Type type); 1855958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void EnterFrame(StackFrame::Type type, bool load_constant_pool_pointer_reg); 1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LeaveFrame(StackFrame::Type type); 1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1858f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void EnterBuiltinFrame(Register context, Register target, Register argc); 1859f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void LeaveBuiltinFrame(Register context, Register target, Register argc); 1860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Expects object in a0 and returns map with validated enum cache 1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // in a0. Assumes that any other register can be used as a scratch. 1863109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void CheckEnumCache(Label* call_runtime); 1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 18653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // AllocationMemento support. Arrays may have an associated AllocationMemento 18663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // object that can be checked for in order to pretransition to another type. 18673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // On entry, receiver_reg should point to the array object. scratch_reg gets 18683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // clobbered. If no info is present jump to no_memento_found, otherwise fall 18693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // through. 18703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void TestJSArrayForAllocationMemento(Register receiver_reg, 18713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch_reg, 18723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label* no_memento_found); 1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfJSArrayHasAllocationMemento(Register receiver_reg, 1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch_reg, 1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* memento_found) { 1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label no_memento_found; 1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestJSArrayForAllocationMemento(receiver_reg, scratch_reg, 18793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch &no_memento_found); 18803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Branch(memento_found); 1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&no_memento_found); 1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Jumps to found label if a prototype map has dictionary elements. 1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0, 1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Label* found); 1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsDoubleZeroRegSet() { return has_double_zero_reg_set_; } 1889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallCFunctionHelper(Register function, 1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int num_reg_arguments, 1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int num_double_arguments); 1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline Register GetRtAsRegisterHelper(const Operand& rt, Register scratch); 1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline int32_t GetOffset(int32_t offset, Label* L, OffsetSize bits); 1897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BranchShortHelperR6(int32_t offset, Label* L); 1898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BranchShortHelper(int16_t offset, Label* L, BranchDelaySlot bdslot); 1899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool BranchShortHelperR6(int32_t offset, Label* L, Condition cond, 1900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register rs, const Operand& rt); 1901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool BranchShortHelper(int16_t offset, Label* L, Condition cond, Register rs, 1902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operand& rt, BranchDelaySlot bdslot); 1903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool BranchShortCheck(int32_t offset, Label* L, Condition cond, Register rs, 1904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Operand& rt, BranchDelaySlot bdslot); 1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BranchAndLinkShortHelperR6(int32_t offset, Label* L); 1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BranchAndLinkShortHelper(int16_t offset, Label* L, 1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchDelaySlot bdslot); 1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BranchAndLinkShort(int32_t offset, BranchDelaySlot bdslot = PROTECT); 1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void BranchAndLinkShort(Label* L, BranchDelaySlot bdslot = PROTECT); 1911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool BranchAndLinkShortHelperR6(int32_t offset, Label* L, Condition cond, 1912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register rs, const Operand& rt); 1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool BranchAndLinkShortHelper(int16_t offset, Label* L, Condition cond, 1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register rs, const Operand& rt, 1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchDelaySlot bdslot); 1916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool BranchAndLinkShortCheck(int32_t offset, Label* L, Condition cond, 1917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register rs, const Operand& rt, 1918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchDelaySlot bdslot); 1919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BranchLong(Label* L, BranchDelaySlot bdslot); 1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BranchAndLinkLong(Label* L, BranchDelaySlot bdslot); 1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Common implementation of BranchF functions for the different formats. 1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BranchFCommon(SecondaryField sizeField, Label* target, Label* nan, 1924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Condition cc, FPURegister cmp1, FPURegister cmp2, 1925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchDelaySlot bd = PROTECT); 1926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void BranchShortF(SecondaryField sizeField, Label* target, Condition cc, 1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FPURegister cmp1, FPURegister cmp2, 1929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BranchDelaySlot bd = PROTECT); 1930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Helper functions for generating invokes. 1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InvokePrologue(const ParameterCount& expected, 1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const ParameterCount& actual, 1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* done, 1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool* definitely_mismatches, 1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InvokeFlag flag, 1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CallWrapper& call_wrapper); 1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InitializeNewString(Register string, 1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register length, 1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex map_index, 1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2); 1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace. 1947109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void InNewSpace(Register object, Register scratch, 1948109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Condition cond, // ne for new space, eq otherwise. 1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* branch); 1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Helper for finding the mark bits for an address. Afterwards, the 1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bitmap register points at the word with the mark bits and the mask 1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the position of the first bit. Leaves addr_reg unchanged. 1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void GetMarkBits(Register addr_reg, 1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register bitmap_reg, 1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register mask_reg); 1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute memory operands for safepoint stack slots. 1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static int SafepointRegisterStackIndex(int reg_code); 1960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemOperand SafepointRegisterSlot(Register reg); 1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemOperand SafepointRegistersAndDoublesSlot(Register reg); 1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool generating_stub_; 1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool has_frame_; 1965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool has_double_zero_reg_set_; 1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This handle will be patched with the code object on installation. 1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> code_object_; 1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Needs access to SafepointRegisterStackIndex for compiled frame 1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // traversal. 1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class StandardFrame; 1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The code patcher is used to patch (typically) small parts of code e.g. for 1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// debugging and other types of instrumentation. When using the code patcher 1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the exact number of bytes specified must be emitted. It is not legal to emit 1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// relocation information. If any of these constraints are violated it causes 1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// an assertion to fail. 1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CodePatcher { 1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum FlushICache { 1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FLUSH, 1984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DONT_FLUSH 1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodePatcher(Isolate* isolate, byte* address, int instructions, 1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlushICache flush_cache = FLUSH); 1989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~CodePatcher(); 1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Macro assembler to emit code. 1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm() { return &masm_; } 1993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit an instruction directly. 1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Emit(Instr instr); 1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit an address directly. 1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Emit(Address addr); 1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Change the condition part of an instruction leaving the rest of the current 2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instruction unchanged. 2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ChangeBranchCondition(Instr current_instr, uint32_t new_opcode); 2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte* address_; // The address of the code being patched. 2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size_; // Number of bytes of the expected patch size. 2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler masm_; // Macro assembler used to generate the code. 2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlushICache flush_cache_; // Whether to flush the I cache after patching. 2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2011109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtemplate <typename Func> 2012109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::GenerateSwitchTable(Register index, size_t case_count, 2013109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Func GetLabelFunction) { 2014109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Ensure that dd-ed labels following this instruction use 8 bytes aligned 2015109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // addresses. 2016109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (kArchVariant >= kMips64r6) { 2017109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch BlockTrampolinePoolFor(static_cast<int>(case_count) * 2 + 6); 2018109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Opposite of Align(8) as we have odd number of instructions in this case. 2019109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if ((pc_offset() & 7) == 0) { 2020109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch nop(); 2021109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 2022109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch addiupc(at, 5); 20233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Dlsa(at, at, index, kPointerSizeLog2); 2024109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ld(at, MemOperand(at)); 2025109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 2026109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label here; 20273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch BlockTrampolinePoolFor(static_cast<int>(case_count) * 2 + 11); 2028109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Align(8); 20293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch push(ra); 2030109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bal(&here); 2031109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch dsll(at, index, kPointerSizeLog2); // Branch delay slot. 2032109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bind(&here); 2033109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch daddu(at, at, ra); 20343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch pop(ra); 20353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ld(at, MemOperand(at, 6 * v8::internal::Assembler::kInstrSize)); 2036109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 2037109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch jr(at); 2038109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch nop(); // Branch delay slot nop. 2039109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (size_t index = 0; index < case_count; ++index) { 2040109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch dd(GetLabelFunction(index)); 2041109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 2042109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ACCESS_MASM(masm) masm-> 2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 2047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_MIPS_MACRO_ASSEMBLER_MIPS_H_ 2050