1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2014 the V8 project authors. All rights reserved. 2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file. 4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/code-generator.h" 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compilation-info.h" 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/code-generator-impl.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/gap-resolver.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/node-matchers.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/osr.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ppc/macro-assembler-ppc.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 { 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal { 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace compiler { 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define __ masm()-> 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define kScratchReg r11 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Adds PPC-specific methods to convert InstructionOperands. 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass PPCOperandConverter final : public InstructionOperandConverter { 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PPCOperandConverter(CodeGenerator* gen, Instruction* instr) 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : InstructionOperandConverter(gen, instr) {} 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t OutputCount() { return instr_->OutputCount(); } 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RCBit OutputRCBit() const { 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (instr_->flags_mode()) { 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kFlags_branch: 353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kFlags_deoptimize: 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kFlags_set: 3762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case kFlags_trap: 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return SetRC; 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kFlags_none: 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return LeaveRC; 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return LeaveRC; 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool CompareLogical() const { 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (instr_->flags_condition()) { 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kUnsignedLessThan: 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kUnsignedGreaterThanOrEqual: 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kUnsignedLessThanOrEqual: 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kUnsignedGreaterThan: 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand InputImmediate(size_t index) { 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Constant constant = ToConstant(instr_->InputAt(index)); 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (constant.type()) { 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kInt32: 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Operand(constant.ToInt32()); 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kFloat32: 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Operand( 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED)); 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kFloat64: 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Operand( 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED)); 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kInt64: 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Operand(constant.ToInt64()); 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kExternalReference: 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kHeapObject: 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kRpoNumber: 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Operand::Zero(); 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand MemoryOperand(AddressingMode* mode, size_t* first_index) { 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const size_t index = *first_index; 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *mode = AddressingModeField::decode(instr_->opcode()); 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (*mode) { 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_None: 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_MRI: 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *first_index += 2; 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MemOperand(InputRegister(index + 0), InputInt32(index + 1)); 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_MRR: 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *first_index += 2; 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MemOperand(InputRegister(index + 0), InputRegister(index + 1)); 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MemOperand(r0); 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand MemoryOperand(AddressingMode* mode, size_t first_index = 0) { 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MemoryOperand(mode, &first_index); 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand ToMemOperand(InstructionOperand* op) const { 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NOT_NULL(op); 107bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(op->IsStackSlot() || op->IsFPStackSlot()); 1083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return SlotToMemOperand(AllocatedOperand::cast(op)->index()); 1093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 1103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MemOperand SlotToMemOperand(int slot) const { 1123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FrameOffset offset = frame_access_state()->GetFrameOffset(slot); 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic inline bool HasRegisterInput(Instruction* instr, size_t index) { 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return instr->InputAt(index)->IsRegister(); 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace { 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineLoadNAN32 final : public OutOfLineCode { 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutOfLineLoadNAN32(CodeGenerator* gen, DoubleRegister result) 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : OutOfLineCode(gen), result_(result) {} 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadDoubleLiteral(result_, std::numeric_limits<float>::quiet_NaN(), 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kScratchReg); 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister const result_; 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineLoadNAN64 final : public OutOfLineCode { 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutOfLineLoadNAN64(CodeGenerator* gen, DoubleRegister result) 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : OutOfLineCode(gen), result_(result) {} 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadDoubleLiteral(result_, std::numeric_limits<double>::quiet_NaN(), 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kScratchReg); 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister const result_; 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineLoadZero final : public OutOfLineCode { 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutOfLineLoadZero(CodeGenerator* gen, Register result) 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : OutOfLineCode(gen), result_(result) {} 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { __ li(result_, Operand::Zero()); } 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const result_; 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineRecordWrite final : public OutOfLineCode { 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register offset, 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register value, Register scratch0, Register scratch1, 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordWriteMode mode) 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : OutOfLineCode(gen), 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object_(object), 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset_(offset), 175109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch offset_immediate_(0), 176109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch value_(value), 177109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch scratch0_(scratch0), 178109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch scratch1_(scratch1), 179bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch mode_(mode), 180bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch must_save_lr_(!gen->frame_access_state()->has_frame()) {} 181109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 182109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch OutOfLineRecordWrite(CodeGenerator* gen, Register object, int32_t offset, 183109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Register value, Register scratch0, Register scratch1, 184109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RecordWriteMode mode) 185109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : OutOfLineCode(gen), 186109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch object_(object), 187109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch offset_(no_reg), 188109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch offset_immediate_(offset), 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value_(value), 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scratch0_(scratch0), 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scratch1_(scratch1), 1923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch mode_(mode), 1933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch must_save_lr_(!gen->frame_access_state()->has_frame()) {} 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode_ > RecordWriteMode::kValueIsPointer) { 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ JumpIfSmi(value_, exit()); 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 199109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ CheckPageFlag(value_, scratch0_, 200109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch MemoryChunk::kPointersToHereAreInterestingMask, eq, 201109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch exit()); 202109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RememberedSetAction const remembered_set_action = 203109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET 204109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : OMIT_REMEMBERED_SET; 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SaveFPRegsMode const save_fp_mode = 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; 2073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (must_save_lr_) { 208109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // We need to save and restore lr if the frame was elided. 209109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ mflr(scratch1_); 210109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Push(scratch1_); 211109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, 213109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch remembered_set_action, save_fp_mode); 214109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (offset_.is(no_reg)) { 215109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ addi(scratch1_, object_, Operand(offset_immediate_)); 216109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 217109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(0, offset_immediate_); 218109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ add(scratch1_, object_, offset_); 219109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 22013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (must_save_lr_ && FLAG_enable_embedded_constant_pool) { 22113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ConstantPoolUnavailableScope constant_pool_unavailable(masm()); 22213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ CallStub(&stub); 22313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else { 22413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ CallStub(&stub); 22513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 2263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (must_save_lr_) { 227109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // We need to save and restore lr if the frame was elided. 228109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Pop(scratch1_); 229109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ mtlr(scratch1_); 230109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const object_; 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const offset_; 236109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int32_t const offset_immediate_; // Valid if offset_.is(no_reg). 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const value_; 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const scratch0_; 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const scratch1_; 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordWriteMode const mode_; 2413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bool must_save_lr_; 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCondition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) { 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (condition) { 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kEqual: 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return eq; 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kNotEqual: 250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ne; 251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSignedLessThan: 252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kUnsignedLessThan: 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return lt; 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSignedGreaterThanOrEqual: 255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kUnsignedGreaterThanOrEqual: 256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ge; 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSignedLessThanOrEqual: 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kUnsignedLessThanOrEqual: 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return le; 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSignedGreaterThan: 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kUnsignedGreaterThan: 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return gt; 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kOverflow: 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Overflow checked for add/sub only. 265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (op) { 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 26762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case kPPC_Add32: 26862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case kPPC_Add64: 269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Sub: 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_AddWithOverflow32: 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_SubWithOverflow32: 273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return lt; 274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kNotOverflow: 279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (op) { 280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 28162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case kPPC_Add32: 28262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case kPPC_Add64: 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Sub: 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_AddWithOverflow32: 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_SubWithOverflow32: 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ge; 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return kNoCondition; 297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace 300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#define ASSEMBLE_FLOAT_UNOP_RC(asm_instr, round) \ 302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputRCBit()); \ 3053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (round) { \ 3063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ frsp(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ 3073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } \ 308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#define ASSEMBLE_FLOAT_BINOP_RC(asm_instr, round) \ 311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputDoubleRegister(1), i.OutputRCBit()); \ 3143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (round) { \ 3153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ frsp(i.OutputDoubleRegister(), i.OutputDoubleRegister()); \ 3163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } \ 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_BINOP(asm_instr_reg, asm_instr_imm) \ 320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { \ 322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr_reg(i.OutputRegister(), i.InputRegister(0), \ 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputRegister(1)); \ 324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr_imm(i.OutputRegister(), i.InputRegister(0), \ 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputImmediate(1)); \ 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_BINOP_RC(asm_instr_reg, asm_instr_imm) \ 332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { \ 334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr_reg(i.OutputRegister(), i.InputRegister(0), \ 335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputRegister(1), i.OutputRCBit()); \ 336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr_imm(i.OutputRegister(), i.InputRegister(0), \ 338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputImmediate(1), i.OutputRCBit()); \ 339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_BINOP_INT_RC(asm_instr_reg, asm_instr_imm) \ 344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { \ 346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr_reg(i.OutputRegister(), i.InputRegister(0), \ 347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputRegister(1), i.OutputRCBit()); \ 348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr_imm(i.OutputRegister(), i.InputRegister(0), \ 350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputInt32(1), i.OutputRCBit()); \ 351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_ADD_WITH_OVERFLOW() \ 356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { \ 358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \ 359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputRegister(1), kScratchReg, r0); \ 360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \ 362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputInt32(1), kScratchReg, r0); \ 363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_SUB_WITH_OVERFLOW() \ 368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { \ 370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ SubAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \ 371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputRegister(1), kScratchReg, r0); \ 372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \ 374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch -i.InputInt32(1), kScratchReg, r0); \ 375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 380bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define ASSEMBLE_ADD_WITH_OVERFLOW32() \ 381bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch do { \ 382bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ASSEMBLE_ADD_WITH_OVERFLOW(); \ 383bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ extsw(kScratchReg, kScratchReg, SetRC); \ 384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 386bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define ASSEMBLE_SUB_WITH_OVERFLOW32() \ 387bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch do { \ 388bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ASSEMBLE_SUB_WITH_OVERFLOW(); \ 389bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ extsw(kScratchReg, kScratchReg, SetRC); \ 390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_ADD_WITH_OVERFLOW32 ASSEMBLE_ADD_WITH_OVERFLOW 393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_SUB_WITH_OVERFLOW32 ASSEMBLE_SUB_WITH_OVERFLOW 394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_COMPARE(cmp_instr, cmpl_instr) \ 398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CRegister cr = cr0; \ 400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { \ 401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (i.CompareLogical()) { \ 402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmpl_instr(i.InputRegister(0), i.InputRegister(1), cr); \ 403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp_instr(i.InputRegister(0), i.InputRegister(1), cr); \ 405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (i.CompareLogical()) { \ 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmpl_instr##i(i.InputRegister(0), i.InputImmediate(1), cr); \ 409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp_instr##i(i.InputRegister(0), i.InputImmediate(1), cr); \ 411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(SetRC, i.OutputRCBit()); \ 414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_FLOAT_COMPARE(cmp_instr) \ 418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CRegister cr = cr0; \ 420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp_instr(i.InputDoubleRegister(0), i.InputDoubleRegister(1), cr); \ 421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(SetRC, i.OutputRCBit()); \ 422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_MODULO(div_instr, mul_instr) \ 426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Register scratch = kScratchReg; \ 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ div_instr(scratch, i.InputRegister(0), i.InputRegister(1)); \ 429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mul_instr(scratch, scratch, i.InputRegister(1)); \ 430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(i.OutputRegister(), i.InputRegister(0), scratch, LeaveOE, \ 431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputRCBit()); \ 432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_FLOAT_MODULO() \ 436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameScope scope(masm(), StackFrame::MANUAL); \ 438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ PrepareCallCFunction(0, 2, kScratchReg); \ 439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ MovToFloatParameters(i.InputDoubleRegister(0), \ 440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputDoubleRegister(1)); \ 441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), \ 442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 0, 2); \ 443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ MovFromFloatResult(i.OutputDoubleRegister()); \ 444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 44713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define ASSEMBLE_IEEE754_UNOP(name) \ 44813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch do { \ 44913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* TODO(bmeurer): We should really get rid of this special instruction, */ \ 45013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* and generate a CallAddress instruction instead. */ \ 45113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FrameScope scope(masm(), StackFrame::MANUAL); \ 45213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ PrepareCallCFunction(0, 1, kScratchReg); \ 45313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ MovToFloatParameter(i.InputDoubleRegister(0)); \ 45413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ 45513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 0, 1); \ 45613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Move the result in the double result register. */ \ 45713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ MovFromFloatResult(i.OutputDoubleRegister()); \ 45813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 45913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } while (0) 46013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 46113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define ASSEMBLE_IEEE754_BINOP(name) \ 46213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch do { \ 46313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* TODO(bmeurer): We should really get rid of this special instruction, */ \ 46413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* and generate a CallAddress instruction instead. */ \ 46513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FrameScope scope(masm(), StackFrame::MANUAL); \ 46613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ PrepareCallCFunction(0, 2, kScratchReg); \ 46713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ MovToFloatParameters(i.InputDoubleRegister(0), \ 46813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch i.InputDoubleRegister(1)); \ 46913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ 47013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 0, 2); \ 47113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Move the result in the double result register. */ \ 47213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ MovFromFloatResult(i.OutputDoubleRegister()); \ 47313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 47413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } while (0) 475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 476f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define ASSEMBLE_FLOAT_MAX() \ 477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DoubleRegister left_reg = i.InputDoubleRegister(0); \ 479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DoubleRegister right_reg = i.InputDoubleRegister(1); \ 480f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DoubleRegister result_reg = i.OutputDoubleRegister(); \ 481f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label check_nan_left, check_zero, return_left, return_right, done; \ 482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fcmpu(left_reg, right_reg); \ 483f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bunordered(&check_nan_left); \ 484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ beq(&check_zero); \ 485f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bge(&return_left); \ 486f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ b(&return_right); \ 487f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch \ 488f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&check_zero); \ 489f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fcmpu(left_reg, kDoubleRegZero); \ 490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch /* left == right != 0. */ \ 491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bne(&return_left); \ 492f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch /* At this point, both left and right are either 0 or -0. */ \ 493f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fadd(result_reg, left_reg, right_reg); \ 494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ b(&done); \ 495f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch \ 496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&check_nan_left); \ 497f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fcmpu(left_reg, left_reg); \ 498f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch /* left == NaN. */ \ 499f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bunordered(&return_left); \ 500f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&return_right); \ 501f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!right_reg.is(result_reg)) { \ 502f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fmr(result_reg, right_reg); \ 503f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } \ 504f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ b(&done); \ 505f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch \ 506f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&return_left); \ 507f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!left_reg.is(result_reg)) { \ 508f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fmr(result_reg, left_reg); \ 509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } \ 510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&done); \ 511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } while (0) \ 512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 514f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define ASSEMBLE_FLOAT_MIN() \ 515f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch do { \ 516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DoubleRegister left_reg = i.InputDoubleRegister(0); \ 517f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DoubleRegister right_reg = i.InputDoubleRegister(1); \ 518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DoubleRegister result_reg = i.OutputDoubleRegister(); \ 519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label check_nan_left, check_zero, return_left, return_right, done; \ 520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fcmpu(left_reg, right_reg); \ 521f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bunordered(&check_nan_left); \ 522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ beq(&check_zero); \ 523f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ ble(&return_left); \ 524f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ b(&return_right); \ 525f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch \ 526f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&check_zero); \ 527f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fcmpu(left_reg, kDoubleRegZero); \ 528f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch /* left == right != 0. */ \ 529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bne(&return_left); \ 530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch /* At this point, both left and right are either 0 or -0. */ \ 531f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch /* Min: The algorithm is: -((-L) + (-R)), which in case of L and R being */\ 532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch /* different registers is most efficiently expressed as -((-L) - R). */ \ 533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fneg(left_reg, left_reg); \ 534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (left_reg.is(right_reg)) { \ 535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fadd(result_reg, left_reg, right_reg); \ 536f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { \ 537f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fsub(result_reg, left_reg, right_reg); \ 538f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } \ 539f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fneg(result_reg, result_reg); \ 540f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ b(&done); \ 541f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch \ 542f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&check_nan_left); \ 543f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fcmpu(left_reg, left_reg); \ 544f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch /* left == NaN. */ \ 545f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bunordered(&return_left); \ 546f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch \ 547f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&return_right); \ 548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!right_reg.is(result_reg)) { \ 549f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fmr(result_reg, right_reg); \ 550f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } \ 551f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ b(&done); \ 552f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch \ 553f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&return_left); \ 554f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!left_reg.is(result_reg)) { \ 555f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fmr(result_reg, left_reg); \ 556f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } \ 557f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&done); \ 558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_LOAD_FLOAT(asm_instr, asm_instrx) \ 562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister result = i.OutputDoubleRegister(); \ 564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressingMode mode = kMode_None; \ 565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand operand = i.MemoryOperand(&mode); \ 566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode == kMode_MRI) { \ 567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(result, operand); \ 568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instrx(result, operand); \ 570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_LOAD_INTEGER(asm_instr, asm_instrx) \ 576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register result = i.OutputRegister(); \ 578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressingMode mode = kMode_None; \ 579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand operand = i.MemoryOperand(&mode); \ 580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode == kMode_MRI) { \ 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(result, operand); \ 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instrx(result, operand); \ 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_STORE_FLOAT32() \ 590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; \ 592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressingMode mode = kMode_None; \ 593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand operand = i.MemoryOperand(&mode, &index); \ 594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister value = i.InputDoubleRegister(index); \ 595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ frsp(kScratchDoubleReg, value); \ 596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode == kMode_MRI) { \ 597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ stfs(kScratchDoubleReg, operand); \ 598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ stfsx(kScratchDoubleReg, operand); \ 600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_STORE_DOUBLE() \ 606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; \ 608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressingMode mode = kMode_None; \ 609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand operand = i.MemoryOperand(&mode, &index); \ 610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister value = i.InputDoubleRegister(index); \ 611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode == kMode_MRI) { \ 612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ stfd(value, operand); \ 613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ stfdx(value, operand); \ 615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_STORE_INTEGER(asm_instr, asm_instrx) \ 621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; \ 623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressingMode mode = kMode_None; \ 624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand operand = i.MemoryOperand(&mode, &index); \ 625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register value = i.InputRegister(index); \ 626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode == kMode_MRI) { \ 627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(value, operand); \ 628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instrx(value, operand); \ 630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 634bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#if V8_TARGET_ARCH_PPC64 635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// TODO(mbrandy): fix paths that produce garbage in offset's upper 32-bits. 636bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define CleanUInt32(x) __ ClearLeftImm(x, x, Operand(32)) 637bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#else 638bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define CleanUInt32(x) 639bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#endif 640bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr, asm_instrx, width) \ 642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister result = i.OutputDoubleRegister(); \ 644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; \ 645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressingMode mode = kMode_None; \ 646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand operand = i.MemoryOperand(&mode, index); \ 647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(kMode_MRR, mode); \ 648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register offset = operand.rb(); \ 649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 2)) { \ 650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmplw(offset, i.InputRegister(2)); \ 651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmplwi(offset, i.InputImmediate(2)); \ 653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto ool = new (zone()) OutOfLineLoadNAN##width(this, result); \ 655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bge(ool->entry()); \ 656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode == kMode_MRI) { \ 657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(result, operand); \ 658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 659bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CleanUInt32(offset); \ 660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instrx(result, operand); \ 661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(ool->exit()); \ 663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr, asm_instrx) \ 667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register result = i.OutputRegister(); \ 669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; \ 670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressingMode mode = kMode_None; \ 671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand operand = i.MemoryOperand(&mode, index); \ 672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(kMode_MRR, mode); \ 673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register offset = operand.rb(); \ 674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 2)) { \ 675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmplw(offset, i.InputRegister(2)); \ 676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmplwi(offset, i.InputImmediate(2)); \ 678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto ool = new (zone()) OutOfLineLoadZero(this, result); \ 680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bge(ool->entry()); \ 681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode == kMode_MRI) { \ 682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(result, operand); \ 683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 684bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CleanUInt32(offset); \ 685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instrx(result, operand); \ 686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(ool->exit()); \ 688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_CHECKED_STORE_FLOAT32() \ 692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done; \ 694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; \ 695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressingMode mode = kMode_None; \ 696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand operand = i.MemoryOperand(&mode, index); \ 697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(kMode_MRR, mode); \ 698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register offset = operand.rb(); \ 699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 2)) { \ 700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmplw(offset, i.InputRegister(2)); \ 701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmplwi(offset, i.InputImmediate(2)); \ 703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bge(&done); \ 705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister value = i.InputDoubleRegister(3); \ 706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ frsp(kScratchDoubleReg, value); \ 707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode == kMode_MRI) { \ 708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ stfs(kScratchDoubleReg, operand); \ 709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 710bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CleanUInt32(offset); \ 711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ stfsx(kScratchDoubleReg, operand); \ 712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&done); \ 714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_CHECKED_STORE_DOUBLE() \ 718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done; \ 720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; \ 721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressingMode mode = kMode_None; \ 722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand operand = i.MemoryOperand(&mode, index); \ 723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(kMode_MRR, mode); \ 724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register offset = operand.rb(); \ 725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 2)) { \ 726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmplw(offset, i.InputRegister(2)); \ 727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmplwi(offset, i.InputImmediate(2)); \ 729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bge(&done); \ 731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister value = i.InputDoubleRegister(3); \ 732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode == kMode_MRI) { \ 733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ stfd(value, operand); \ 734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 735bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CleanUInt32(offset); \ 736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ stfdx(value, operand); \ 737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&done); \ 739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr, asm_instrx) \ 743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done; \ 745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; \ 746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressingMode mode = kMode_None; \ 747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand operand = i.MemoryOperand(&mode, index); \ 748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(kMode_MRR, mode); \ 749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register offset = operand.rb(); \ 750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 2)) { \ 751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmplw(offset, i.InputRegister(2)); \ 752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmplwi(offset, i.InputImmediate(2)); \ 754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bge(&done); \ 756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register value = i.InputRegister(3); \ 757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode == kMode_MRI) { \ 758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(value, operand); \ 759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 760bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CleanUInt32(offset); \ 761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instrx(value, operand); \ 762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&done); \ 764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 76762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define ASSEMBLE_ATOMIC_LOAD_INTEGER(asm_instr, asm_instrx) \ 76862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch do { \ 76962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label done; \ 77062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Register result = i.OutputRegister(); \ 77162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AddressingMode mode = kMode_None; \ 77262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MemOperand operand = i.MemoryOperand(&mode); \ 77362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (mode == kMode_MRI) { \ 77462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ asm_instr(result, operand); \ 77562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { \ 77662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ asm_instrx(result, operand); \ 77762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } \ 77862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ lwsync(); \ 779bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } while (0) 78062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define ASSEMBLE_ATOMIC_STORE_INTEGER(asm_instr, asm_instrx) \ 78162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch do { \ 78262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t index = 0; \ 78362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AddressingMode mode = kMode_None; \ 78462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MemOperand operand = i.MemoryOperand(&mode, &index); \ 78562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Register value = i.InputRegister(index); \ 78662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ lwsync(); \ 78762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (mode == kMode_MRI) { \ 78862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ asm_instr(value, operand); \ 78962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { \ 79062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ asm_instrx(value, operand); \ 79162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } \ 79262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ sync(); \ 79362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); \ 794bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } while (0) 795bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 7963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid CodeGenerator::AssembleDeconstructFrame() { 7973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ LeaveFrame(StackFrame::MANUAL); 7983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 7993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 800f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssemblePrepareTailCall() { 8013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (frame_access_state()->has_frame()) { 802109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ RestoreFrameStateForTailCall(); 803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->SetFrameAccessToSP(); 805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 8073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, 8083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch1, 8093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch2, 8103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch3) { 8113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3)); 8123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label done; 8133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 8143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Check if current frame is an arguments adaptor frame. 8153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ LoadP(scratch1, MemOperand(fp, StandardFrameConstants::kContextOffset)); 81662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ cmpi(scratch1, 81762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); 8183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ bne(&done); 8193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 8203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Load arguments count from current arguments adaptor frame (note, it 8213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // does not include receiver). 8223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register caller_args_count_reg = scratch1; 8233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ LoadP(caller_args_count_reg, 8243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); 8253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ SmiUntag(caller_args_count_reg); 8263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 8273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ParameterCount callee_args_count(args_reg); 8283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, 8293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch scratch3); 8303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ bind(&done); 8313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 833f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace { 834f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 835f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid FlushPendingPushRegisters(MacroAssembler* masm, 836f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FrameAccessState* frame_access_state, 837f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ZoneVector<Register>* pending_pushes) { 838f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (pending_pushes->size()) { 839f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case 0: 840f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 841f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case 1: 842f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch masm->Push((*pending_pushes)[0]); 843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 844f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case 2: 845f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch masm->Push((*pending_pushes)[0], (*pending_pushes)[1]); 846f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 847f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case 3: 848f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch masm->Push((*pending_pushes)[0], (*pending_pushes)[1], 849f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (*pending_pushes)[2]); 850f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 851f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 852f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 853f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 854f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 855f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_access_state->IncreaseSPDelta(pending_pushes->size()); 856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch pending_pushes->resize(0); 857f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 858f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 859f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid AddPendingPushRegister(MacroAssembler* masm, 860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FrameAccessState* frame_access_state, 861f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ZoneVector<Register>* pending_pushes, 862f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Register reg) { 863f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch pending_pushes->push_back(reg); 864f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (pending_pushes->size() == 3 || reg.is(ip)) { 865f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlushPendingPushRegisters(masm, frame_access_state, pending_pushes); 866f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 869f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid AdjustStackPointerForTailCall( 870f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MacroAssembler* masm, FrameAccessState* state, int new_slot_above_sp, 871f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ZoneVector<Register>* pending_pushes = nullptr, 872f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool allow_shrinkage = true) { 873f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int current_sp_offset = state->GetSPToFPSlotCount() + 874f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch StandardFrameConstants::kFixedSlotCountAboveFp; 875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int stack_slot_delta = new_slot_above_sp - current_sp_offset; 876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (stack_slot_delta > 0) { 877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (pending_pushes != nullptr) { 878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlushPendingPushRegisters(masm, state, pending_pushes); 879f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 880f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch masm->Add(sp, sp, -stack_slot_delta * kPointerSize, r0); 881f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch state->IncreaseSPDelta(stack_slot_delta); 882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (allow_shrinkage && stack_slot_delta < 0) { 883f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (pending_pushes != nullptr) { 884f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlushPendingPushRegisters(masm, state, pending_pushes); 885f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch masm->Add(sp, sp, -stack_slot_delta * kPointerSize, r0); 887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch state->IncreaseSPDelta(stack_slot_delta); 888f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 890f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 891f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace 892f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 893f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssembleTailCallBeforeGap(Instruction* instr, 894f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int first_unused_stack_slot) { 895f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CodeGenerator::PushTypeFlags flags(kImmediatePush | kScalarPush); 896f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ZoneVector<MoveOperands*> pushes(zone()); 897f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch GetPushCompatibleMoves(instr, flags, &pushes); 898f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 899f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!pushes.empty() && 900f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (LocationOperand::cast(pushes.back()->destination()).index() + 1 == 901f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch first_unused_stack_slot)) { 902f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PPCOperandConverter g(this, instr); 903f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ZoneVector<Register> pending_pushes(zone()); 904f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (auto move : pushes) { 905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand destination_location( 906f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand::cast(move->destination())); 907f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand source(move->source()); 908f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AdjustStackPointerForTailCall( 909f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch masm(), frame_access_state(), 910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch destination_location.index() - pending_pushes.size(), 911f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch &pending_pushes); 912f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (source.IsStackSlot()) { 913f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand source_location(LocationOperand::cast(source)); 914f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ LoadP(ip, g.SlotToMemOperand(source_location.index())); 915f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AddPendingPushRegister(masm(), frame_access_state(), &pending_pushes, 916f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ip); 917f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (source.IsRegister()) { 918f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand source_location(LocationOperand::cast(source)); 919f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AddPendingPushRegister(masm(), frame_access_state(), &pending_pushes, 920f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch source_location.GetRegister()); 921f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (source.IsImmediate()) { 922f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AddPendingPushRegister(masm(), frame_access_state(), &pending_pushes, 923f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ip); 924f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 925f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Pushes of non-scalar data types is not supported. 926f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNIMPLEMENTED(); 927f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 928f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch move->Eliminate(); 929f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 930f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlushPendingPushRegisters(masm(), frame_access_state(), &pending_pushes); 931f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 932f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AdjustStackPointerForTailCall(masm(), frame_access_state(), 933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch first_unused_stack_slot, nullptr, false); 934f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 935f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 936f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssembleTailCallAfterGap(Instruction* instr, 937f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int first_unused_stack_slot) { 938f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AdjustStackPointerForTailCall(masm(), frame_access_state(), 939f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch first_unused_stack_slot); 940f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 941f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 942f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Assembles an instruction after register allocation, producing machine code. 944bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( 945bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Instruction* instr) { 946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PPCOperandConverter i(this, instr); 947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArchOpcode opcode = ArchOpcodeField::decode(instr->opcode()); 948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (opcode) { 950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchCallCodeObject: { 951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool( 952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm()); 953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EnsureSpaceForLazyDeopt(); 954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 0)) { 955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ addi(ip, i.InputRegister(0), 956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand(Code::kHeaderSize - kHeapObjectTag)); 957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Call(ip); 958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Call(Handle<Code>::cast(i.InputHeapObject(0)), 960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::CODE_TARGET); 961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordCallPosition(instr); 963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 9673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kArchTailCallCodeObjectFromJSFunction: 968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchTailCallCodeObject: { 9693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (opcode == kArchTailCallCodeObjectFromJSFunction) { 9703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 9713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch i.TempRegister(0), i.TempRegister(1), 9723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch i.TempRegister(2)); 9733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 0)) { 975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ addi(ip, i.InputRegister(0), 976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand(Code::kHeaderSize - kHeapObjectTag)); 977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Jump(ip); 978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We cannot use the constant pool to load the target since 980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // we've already restored the caller's frame. 981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConstantPoolUnavailableScope constant_pool_unavailable(masm()); 982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Jump(Handle<Code>::cast(i.InputHeapObject(0)), 983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::CODE_TARGET); 984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 987f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_access_state()->SetFrameAccessToDefault(); 988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 990bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kArchTailCallAddress: { 991bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CHECK(!instr->InputAt(0)->IsImmediate()); 992bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ Jump(i.InputRegister(0)); 993bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch frame_access_state()->ClearSPDelta(); 994f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_access_state()->SetFrameAccessToDefault(); 995bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 996bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchCallJSFunction: { 998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool( 999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm()); 1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EnsureSpaceForLazyDeopt(); 1001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register func = i.InputRegister(0); 1002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code) { 1003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check the function's context matches the context argument. 1004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(kScratchReg, 1005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FieldMemOperand(func, JSFunction::kContextOffset)); 1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp(cp, kScratchReg); 1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Assert(eq, kWrongFunctionContext); 1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Call(ip); 1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordCallPosition(instr); 1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1016c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case kArchTailCallJSFunctionFromJSFunction: { 1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register func = i.InputRegister(0); 1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code) { 1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check the function's context matches the context argument. 1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(kScratchReg, 1021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FieldMemOperand(func, JSFunction::kContextOffset)); 1022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp(cp, kScratchReg); 1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Assert(eq, kWrongFunctionContext); 1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1025c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 1026c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i.TempRegister(0), i.TempRegister(1), 1027c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i.TempRegister(2)); 1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Jump(ip); 1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 1032f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_access_state()->SetFrameAccessToDefault(); 1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchPrepareCallCFunction: { 1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int const num_parameters = MiscField::decode(instr->opcode()); 1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ PrepareCallCFunction(num_parameters, kScratchReg); 1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Frame alignment requires using FP-relative frame addressing. 1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->SetFrameAccessToFP(); 1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchPrepareTailCall: 1043f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AssemblePrepareTailCall(); 1044f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1045f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kArchComment: { 1046f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Address comment_string = i.InputExternalReference(0).address(); 1047f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ RecordComment(reinterpret_cast<const char*>(comment_string)); 1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1049f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchCallCFunction: { 1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int const num_parameters = MiscField::decode(instr->opcode()); 1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsImmediate()) { 1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference ref = i.InputExternalReference(0); 1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CallCFunction(ref, num_parameters); 1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register func = i.InputRegister(0); 1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CallCFunction(func, num_parameters); 1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->SetFrameAccessToDefault(); 1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchJmp: 1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchJump(i.InputRpo(0)); 1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchLookupSwitch: 1068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchLookupSwitch(instr); 1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchTableSwitch: 1072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchTableSwitch(instr); 1073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 107513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kArchDebugBreak: 107613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ stop("kArchDebugBreak"); 107713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchNop: 1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchThrowTerminator: 1080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // don't emit code for nops. 1081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchDeoptimize: { 1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int deopt_state_id = 1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); 108662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CodeGenResult result = 108762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AssembleDeoptimizerCall(deopt_state_id, current_source_position_); 1088bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (result != kSuccess) return result; 1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchRet: 1092c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AssembleReturn(instr->InputAt(0)); 1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchStackPointer: 1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mr(i.OutputRegister(), sp); 1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchFramePointer: 1100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mr(i.OutputRegister(), fp); 1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1103109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kArchParentFramePointer: 11043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (frame_access_state()->has_frame()) { 1105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ LoadP(i.OutputRegister(), MemOperand(fp, 0)); 1106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 1107109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ mr(i.OutputRegister(), fp); 1108109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1109109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchTruncateDoubleToI: 1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(mbrandy): move slow call to stub out of line. 1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); 1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchStoreWithWriteBarrier: { 1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordWriteMode mode = 1117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<RecordWriteMode>(MiscField::decode(instr->opcode())); 1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register object = i.InputRegister(0); 1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register value = i.InputRegister(2); 1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch0 = i.TempRegister(0); 1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch1 = i.TempRegister(1); 1122109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch OutOfLineRecordWrite* ool; 1123109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1124109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AddressingMode addressing_mode = 1125109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AddressingModeField::decode(instr->opcode()); 1126109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (addressing_mode == kMode_MRI) { 1127109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int32_t offset = i.InputInt32(1); 1128109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value, 1129109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch scratch0, scratch1, mode); 1130109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ StoreP(value, MemOperand(object, offset)); 1131109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 1132109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(kMode_MRR, addressing_mode); 1133109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Register offset(i.InputRegister(1)); 1134109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value, 1135109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch scratch0, scratch1, mode); 1136109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ StorePX(value, MemOperand(object, offset)); 1137109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CheckPageFlag(object, scratch0, 1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemoryChunk::kPointersFromHereAreInterestingMask, ne, 1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ool->entry()); 1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(ool->exit()); 1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1144109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kArchStackSlot: { 1145109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FrameOffset offset = 1146109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch frame_access_state()->GetFrameOffset(i.InputInt32(0)); 1147109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ addi(i.OutputRegister(), offset.from_stack_pointer() ? sp : fp, 1148109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Operand(offset.offset())); 1149109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 1150109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_And: 1152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { 1153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ and_(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 1154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputRCBit()); 1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ andi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1)); 1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_AndComplement: 1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ andc(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputRCBit()); 1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Or: 1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { 1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ orx(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputRCBit()); 1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ori(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1)); 1169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_OrComplement: 1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ orc(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputRCBit()); 1175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Xor: 1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { 1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ xor_(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputRCBit()); 1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ xori(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1)); 1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_ShiftLeft32: 1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_BINOP_RC(slw, slwi); 1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_ShiftLeft64: 1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_BINOP_RC(sld, sldi); 1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_ShiftRight32: 1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_BINOP_RC(srw, srwi); 1195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_ShiftRight64: 1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_BINOP_RC(srd, srdi); 1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_ShiftRightAlg32: 1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_BINOP_INT_RC(sraw, srawi); 1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_ShiftRightAlg64: 1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_BINOP_INT_RC(srad, sradi); 1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 12093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#if !V8_TARGET_ARCH_PPC64 12103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kPPC_AddPair: 12113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(0) ... left low word. 12123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(1) ... left high word. 12133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(2) ... right low word. 12143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(3) ... right high word. 12153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ addc(i.OutputRegister(0), i.InputRegister(0), i.InputRegister(2)); 12163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ adde(i.OutputRegister(1), i.InputRegister(1), i.InputRegister(3)); 12173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 12183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 12193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kPPC_SubPair: 12203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(0) ... left low word. 12213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(1) ... left high word. 12223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(2) ... right low word. 12233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(3) ... right high word. 12243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ subc(i.OutputRegister(0), i.InputRegister(0), i.InputRegister(2)); 12253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ sube(i.OutputRegister(1), i.InputRegister(1), i.InputRegister(3)); 12263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 12273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 12283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kPPC_MulPair: 12293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(0) ... left low word. 12303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(1) ... left high word. 12313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(2) ... right low word. 12323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(3) ... right high word. 12333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ mullw(i.TempRegister(0), i.InputRegister(0), i.InputRegister(3)); 12343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ mullw(i.TempRegister(1), i.InputRegister(2), i.InputRegister(1)); 12353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ add(i.TempRegister(0), i.TempRegister(0), i.TempRegister(1)); 12363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ mullw(i.OutputRegister(0), i.InputRegister(0), i.InputRegister(2)); 12373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ mulhwu(i.OutputRegister(1), i.InputRegister(0), i.InputRegister(2)); 12383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ add(i.OutputRegister(1), i.OutputRegister(1), i.TempRegister(0)); 12393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 1240c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case kPPC_ShiftLeftPair: { 1241c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Register second_output = 1242c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch instr->OutputCount() >= 2 ? i.OutputRegister(1) : i.TempRegister(0); 12433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (instr->InputAt(2)->IsImmediate()) { 1244c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ ShiftLeftPair(i.OutputRegister(0), second_output, i.InputRegister(0), 1245c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i.InputRegister(1), i.InputInt32(2)); 12463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 1247c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ ShiftLeftPair(i.OutputRegister(0), second_output, i.InputRegister(0), 1248c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i.InputRegister(1), kScratchReg, i.InputRegister(2)); 12493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 12503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 1251c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1252c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case kPPC_ShiftRightPair: { 1253c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Register second_output = 1254c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch instr->OutputCount() >= 2 ? i.OutputRegister(1) : i.TempRegister(0); 12553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (instr->InputAt(2)->IsImmediate()) { 1256c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ ShiftRightPair(i.OutputRegister(0), second_output, 12573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch i.InputRegister(0), i.InputRegister(1), 12583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch i.InputInt32(2)); 12593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 1260c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ ShiftRightPair(i.OutputRegister(0), second_output, 12613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch i.InputRegister(0), i.InputRegister(1), kScratchReg, 12623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch i.InputRegister(2)); 12633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 12643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 1265c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1266c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case kPPC_ShiftRightAlgPair: { 1267c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Register second_output = 1268c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch instr->OutputCount() >= 2 ? i.OutputRegister(1) : i.TempRegister(0); 12693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (instr->InputAt(2)->IsImmediate()) { 1270c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ ShiftRightAlgPair(i.OutputRegister(0), second_output, 12713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch i.InputRegister(0), i.InputRegister(1), 12723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch i.InputInt32(2)); 12733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 1274c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ ShiftRightAlgPair(i.OutputRegister(0), second_output, 12753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch i.InputRegister(0), i.InputRegister(1), 12763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch kScratchReg, i.InputRegister(2)); 12773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 12783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 1279c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 12803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#endif 1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_RotRight32: 1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { 1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ subfic(kScratchReg, i.InputRegister(1), Operand(32)); 1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ rotlw(i.OutputRegister(), i.InputRegister(0), kScratchReg, 1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputRCBit()); 1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int sh = i.InputInt32(1); 1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ rotrwi(i.OutputRegister(), i.InputRegister(0), sh, i.OutputRCBit()); 1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_RotRight64: 1293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { 1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ subfic(kScratchReg, i.InputRegister(1), Operand(64)); 1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ rotld(i.OutputRegister(), i.InputRegister(0), kScratchReg, 1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputRCBit()); 1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int sh = i.InputInt32(1); 1299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ rotrdi(i.OutputRegister(), i.InputRegister(0), sh, i.OutputRCBit()); 1300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Not: 1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ notx(i.OutputRegister(), i.InputRegister(0), i.OutputRCBit()); 1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_RotLeftAndMask32: 1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ rlwinm(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1), 1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 31 - i.InputInt32(2), 31 - i.InputInt32(3), i.OutputRCBit()); 1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_RotLeftAndClear64: 1312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ rldic(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1), 1313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 63 - i.InputInt32(2), i.OutputRCBit()); 1314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_RotLeftAndClearLeft64: 1316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ rldicl(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1), 1317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 63 - i.InputInt32(2), i.OutputRCBit()); 1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_RotLeftAndClearRight64: 1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ rldicr(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1), 1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 63 - i.InputInt32(2), i.OutputRCBit()); 1322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 132462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case kPPC_Add32: 1325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FlagsModeField::decode(instr->opcode()) != kFlags_none) { 1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_ADD_WITH_OVERFLOW(); 1328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { 1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LeaveOE, i.OutputRCBit()); 1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ addi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1)); 1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 133762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ extsw(i.OutputRegister(), i.OutputRegister()); 1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 134262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#if V8_TARGET_ARCH_PPC64 134362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case kPPC_Add64: 134462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (FlagsModeField::decode(instr->opcode()) != kFlags_none) { 134562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ASSEMBLE_ADD_WITH_OVERFLOW(); 134662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 134762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (HasRegisterInput(instr, 1)) { 134862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ add(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 134962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch LeaveOE, i.OutputRCBit()); 135062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 135162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ addi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1)); 135262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 135362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 135462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 135562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 135662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#endif 1357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_AddWithOverflow32: 1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_ADD_WITH_OVERFLOW32(); 1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_AddDouble: 13613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_FLOAT_BINOP_RC(fadd, MiscField::decode(instr->opcode())); 1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Sub: 1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FlagsModeField::decode(instr->opcode()) != kFlags_none) { 1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SUB_WITH_OVERFLOW(); 1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { 1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LeaveOE, i.OutputRCBit()); 1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ subi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1)); 1374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_SubWithOverflow32: 1381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SUB_WITH_OVERFLOW32(); 1382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_SubDouble: 13843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_FLOAT_BINOP_RC(fsub, MiscField::decode(instr->opcode())); 1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Mul32: 1387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mullw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 1388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LeaveOE, i.OutputRCBit()); 1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Mul64: 1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mulld(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LeaveOE, i.OutputRCBit()); 1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1396f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1397f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kPPC_Mul32WithHigh32: 1398f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (i.OutputRegister(0).is(i.InputRegister(0)) || 1399f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i.OutputRegister(0).is(i.InputRegister(1)) || 1400f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i.OutputRegister(1).is(i.InputRegister(0)) || 1401f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i.OutputRegister(1).is(i.InputRegister(1))) { 1402f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ mullw(kScratchReg, 1403f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i.InputRegister(0), i.InputRegister(1)); // low 1404f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ mulhw(i.OutputRegister(1), 1405f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i.InputRegister(0), i.InputRegister(1)); // high 1406f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ mr(i.OutputRegister(0), kScratchReg); 1407f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1408f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ mullw(i.OutputRegister(0), 1409f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i.InputRegister(0), i.InputRegister(1)); // low 1410f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ mulhw(i.OutputRegister(1), 1411f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch i.InputRegister(0), i.InputRegister(1)); // high 1412f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1413f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_MulHigh32: 1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mulhw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputRCBit()); 1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_MulHighU32: 1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mulhwu(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputRCBit()); 1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_MulDouble: 14233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_FLOAT_BINOP_RC(fmul, MiscField::decode(instr->opcode())); 1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Div32: 1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ divw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); 1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Div64: 1431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ divd(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); 1432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_DivU32: 1436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ divwu(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); 1437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_DivU64: 1441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ divdu(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); 1442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_DivDouble: 14463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_FLOAT_BINOP_RC(fdiv, MiscField::decode(instr->opcode())); 1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Mod32: 144962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (CpuFeatures::IsSupported(MODULO)) { 145062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ modsw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); 145162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 145262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ASSEMBLE_MODULO(divw, mullw); 145362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 1454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Mod64: 145762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (CpuFeatures::IsSupported(MODULO)) { 145862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ modsd(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); 145962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 146062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ASSEMBLE_MODULO(divd, mulld); 146162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_ModU32: 146562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (CpuFeatures::IsSupported(MODULO)) { 146662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ moduw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); 146762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 146862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ASSEMBLE_MODULO(divwu, mullw); 146962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_ModU64: 147362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (CpuFeatures::IsSupported(MODULO)) { 147462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ modud(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); 147562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 147662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ASSEMBLE_MODULO(divdu, mulld); 147762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_ModDouble: 1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(bmeurer): We should really get rid of this special instruction, 1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // and generate a CallAddress instruction instead. 1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_FLOAT_MODULO(); 1484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1485f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Acos: 1486f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(acos); 1487f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1488f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Acosh: 1489f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(acosh); 1490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Asin: 1492f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(asin); 1493f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Asinh: 1495f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(asinh); 1496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 149713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Atan: 149813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(atan); 149913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 150013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Atan2: 150113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_BINOP(atan2); 150213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 1503f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Atanh: 1504f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(atanh); 1505f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 150613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Tan: 150713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(tan); 150813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 1509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Tanh: 1510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(tanh); 1511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 151213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Cbrt: 151313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(cbrt); 151413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 151513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Sin: 151613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(sin); 151713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 1518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Sinh: 1519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(sinh); 1520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 152113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Cos: 152213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(cos); 152313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 1524f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Cosh: 1525f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(cosh); 1526f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 152713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Exp: 152813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(exp); 152913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 153013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Expm1: 153113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(expm1); 153213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 153313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Log: 153413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(log); 153513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 153613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Log1p: 153713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(log1p); 153813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 153913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Log2: 154013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(log2); 154113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 154213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Log10: 154313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(log10); 154413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 1545f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Pow: { 1546f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MathPowStub stub(isolate(), MathPowStub::DOUBLE); 1547f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ CallStub(&stub); 1548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Move(d1, d3); 1549f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1550f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Neg: 1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ neg(i.OutputRegister(), i.InputRegister(0), LeaveOE, i.OutputRCBit()); 1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_MaxDouble: 1555f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_FLOAT_MAX(); 1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_MinDouble: 1558f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_FLOAT_MIN(); 1559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_AbsDouble: 15613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_FLOAT_UNOP_RC(fabs, 0); 1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_SqrtDouble: 15643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_FLOAT_UNOP_RC(fsqrt, MiscField::decode(instr->opcode())); 1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_FloorDouble: 15673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_FLOAT_UNOP_RC(frim, MiscField::decode(instr->opcode())); 1568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_CeilDouble: 15703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_FLOAT_UNOP_RC(frip, MiscField::decode(instr->opcode())); 1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_TruncateDouble: 15733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_FLOAT_UNOP_RC(friz, MiscField::decode(instr->opcode())); 1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_RoundDouble: 15763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_FLOAT_UNOP_RC(frin, MiscField::decode(instr->opcode())); 1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_NegDouble: 15793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_FLOAT_UNOP_RC(fneg, 0); 1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Cntlz32: 1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cntlzw_(i.OutputRegister(), i.InputRegister(0)); 1583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Cntlz64: 1587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cntlzd_(i.OutputRegister(), i.InputRegister(0)); 1588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Popcnt32: 1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ popcntw(i.OutputRegister(), i.InputRegister(0)); 1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Popcnt64: 1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ popcntd(i.OutputRegister(), i.InputRegister(0)); 1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Cmp32: 1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_COMPARE(cmpw, cmplw); 1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Cmp64: 1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_COMPARE(cmp, cmpl); 1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_CmpDouble: 1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_FLOAT_COMPARE(fcmpu); 1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Tst32: 1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { 1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ and_(r0, i.InputRegister(0), i.InputRegister(1), i.OutputRCBit()); 1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ andi(r0, i.InputRegister(0), i.InputImmediate(1)); 1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ extsw(r0, r0, i.OutputRCBit()); 1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(SetRC, i.OutputRCBit()); 1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Tst64: 1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasRegisterInput(instr, 1)) { 1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ and_(r0, i.InputRegister(0), i.InputRegister(1), i.OutputRCBit()); 1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ andi(r0, i.InputRegister(0), i.InputImmediate(1)); 1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(SetRC, i.OutputRCBit()); 1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 163313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kPPC_Float64SilenceNaN: { 163413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DoubleRegister value = i.InputDoubleRegister(0); 163513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DoubleRegister result = i.OutputDoubleRegister(); 163613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ CanonicalizeNaN(result, value); 163713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 163813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Push: 1640bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ stfdu(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize)); 1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); 1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Push(i.InputRegister(0)); 1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->IncreaseSPDelta(1); 1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_PushFrame: { 1650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int num_slots = i.InputInt32(1); 1651bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 165213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch LocationOperand* op = LocationOperand::cast(instr->InputAt(0)); 165313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (op->representation() == MachineRepresentation::kFloat64) { 165413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ StoreDoubleU(i.InputDoubleRegister(0), 1655bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MemOperand(sp, -num_slots * kPointerSize), r0); 165613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else { 165713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(op->representation() == MachineRepresentation::kFloat32); 165813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ StoreSingleU(i.InputDoubleRegister(0), 165913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch MemOperand(sp, -num_slots * kPointerSize), r0); 166013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ StorePU(i.InputRegister(0), 1663bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MemOperand(sp, -num_slots * kPointerSize), r0); 1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_StoreToStackSlot: { 1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int slot = i.InputInt32(1); 1669bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 167013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch LocationOperand* op = LocationOperand::cast(instr->InputAt(0)); 167113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (op->representation() == MachineRepresentation::kFloat64) { 167213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ StoreDouble(i.InputDoubleRegister(0), 167313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch MemOperand(sp, slot * kPointerSize), r0); 167413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else { 167513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(op->representation() == MachineRepresentation::kFloat32); 167613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ StoreSingle(i.InputDoubleRegister(0), 167713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch MemOperand(sp, slot * kPointerSize), r0); 167813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1680bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ StoreP(i.InputRegister(0), MemOperand(sp, slot * kPointerSize), r0); 1681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_ExtendSignWord8: 1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ extsb(i.OutputRegister(), i.InputRegister(0)); 1686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_ExtendSignWord16: 1689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ extsh(i.OutputRegister(), i.InputRegister(0)); 1690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_ExtendSignWord32: 1694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ extsw(i.OutputRegister(), i.InputRegister(0)); 1695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Uint32ToUint64: 1698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Zero extend 1699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ clrldi(i.OutputRegister(), i.InputRegister(0), Operand(32)); 1700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Int64ToInt32: 1703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ extsw(i.OutputRegister(), i.InputRegister(0)); 1704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Int64ToFloat32: 1707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ConvertInt64ToFloat(i.InputRegister(0), i.OutputDoubleRegister()); 1708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Int64ToDouble: 1711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ConvertInt64ToDouble(i.InputRegister(0), i.OutputDoubleRegister()); 1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Uint64ToFloat32: 1715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ConvertUnsignedInt64ToFloat(i.InputRegister(0), 1716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputDoubleRegister()); 1717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Uint64ToDouble: 1720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ConvertUnsignedInt64ToDouble(i.InputRegister(0), 1721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputDoubleRegister()); 1722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1725109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kPPC_Int32ToFloat32: 1726109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ ConvertIntToFloat(i.InputRegister(0), i.OutputDoubleRegister()); 1727109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1728109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 1729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Int32ToDouble: 1730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ConvertIntToDouble(i.InputRegister(0), i.OutputDoubleRegister()); 1731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1733109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kPPC_Uint32ToFloat32: 1734109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ ConvertUnsignedIntToFloat(i.InputRegister(0), 1735109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch i.OutputDoubleRegister()); 1736109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1737109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 1738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Uint32ToDouble: 1739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ConvertUnsignedIntToDouble(i.InputRegister(0), 1740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputDoubleRegister()); 1741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_DoubleToInt32: 1744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_DoubleToUint32: 1745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_DoubleToInt64: { 1746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool check_conversion = 1748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (opcode == kPPC_DoubleToInt64 && i.OutputCount() > 1); 1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (check_conversion) { 1750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mtfsb0(VXCVI); // clear FPSCR:VXCVI bit 1751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ConvertDoubleToInt64(i.InputDoubleRegister(0), 1754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if !V8_TARGET_ARCH_PPC64 1755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kScratchReg, 1756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputRegister(0), kScratchDoubleReg); 1758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (check_conversion) { 1760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Set 2nd output to zero if conversion fails. 1761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CRegister cr = cr7; 1762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int crbit = v8::internal::Assembler::encode_crbit( 1763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cr, static_cast<CRBit>(VXCVI % CRWIDTH)); 1764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mcrfs(cr, VXCVI); // extract FPSCR field containing VXCVI into cr7 1765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(ISELECT)) { 1766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ li(i.OutputRegister(1), Operand(1)); 1767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ isel(i.OutputRegister(1), r0, i.OutputRegister(1), crbit); 1768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ li(i.OutputRegister(1), Operand::Zero()); 1770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bc(v8::internal::Assembler::kInstrSize * 2, BT, crbit); 1771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ li(i.OutputRegister(1), Operand(1)); 1772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_DoubleToUint64: { 1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool check_conversion = (i.OutputCount() > 1); 1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (check_conversion) { 1782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mtfsb0(VXCVI); // clear FPSCR:VXCVI bit 1783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ConvertDoubleToUnsignedInt64(i.InputDoubleRegister(0), 1785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.OutputRegister(0), kScratchDoubleReg); 1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (check_conversion) { 1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Set 2nd output to zero if conversion fails. 1788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CRegister cr = cr7; 1789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int crbit = v8::internal::Assembler::encode_crbit( 1790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cr, static_cast<CRBit>(VXCVI % CRWIDTH)); 1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mcrfs(cr, VXCVI); // extract FPSCR field containing VXCVI into cr7 1792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(ISELECT)) { 1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ li(i.OutputRegister(1), Operand(1)); 1794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ isel(i.OutputRegister(1), r0, i.OutputRegister(1), crbit); 1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ li(i.OutputRegister(1), Operand::Zero()); 1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bc(v8::internal::Assembler::kInstrSize * 2, BT, crbit); 1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ li(i.OutputRegister(1), Operand(1)); 1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_DoubleToFloat32: 18063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_FLOAT_UNOP_RC(frsp, 0); 1807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_Float32ToDouble: 1809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Nothing to do. 1810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); 1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_DoubleExtractLowWord32: 1814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ MovDoubleLowToInt(i.OutputRegister(), i.InputDoubleRegister(0)); 1815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_DoubleExtractHighWord32: 1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ MovDoubleHighToInt(i.OutputRegister(), i.InputDoubleRegister(0)); 1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_DoubleInsertLowWord32: 1822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ InsertDoubleLow(i.OutputDoubleRegister(), i.InputRegister(1), r0); 1823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_DoubleInsertHighWord32: 1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ InsertDoubleHigh(i.OutputDoubleRegister(), i.InputRegister(1), r0); 1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_DoubleConstruct: 1830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ MovInt64ComponentsToDouble(i.OutputDoubleRegister(), 1832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputRegister(0), i.InputRegister(1), r0); 1833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 1834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ MovInt64ToDouble(i.OutputDoubleRegister(), i.InputRegister(0), 1835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputRegister(1)); 1836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_BitcastFloat32ToInt32: 1840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ MovFloatToInt(i.OutputRegister(), i.InputDoubleRegister(0)); 1841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_BitcastInt32ToFloat32: 1843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ MovIntToFloat(i.OutputDoubleRegister(), i.InputRegister(0)); 1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_BitcastDoubleToInt64: 1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ MovDoubleToInt64(i.OutputRegister(), i.InputDoubleRegister(0)); 1848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_BitcastInt64ToDouble: 1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ MovInt64ToDouble(i.OutputDoubleRegister(), i.InputRegister(0)); 1851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_LoadWordU8: 1854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_LOAD_INTEGER(lbz, lbzx); 1855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_LoadWordS8: 1857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_LOAD_INTEGER(lbz, lbzx); 1858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ extsb(i.OutputRegister(), i.OutputRegister()); 1859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_LoadWordU16: 1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_LOAD_INTEGER(lhz, lhzx); 1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_LoadWordS16: 1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_LOAD_INTEGER(lha, lhax); 1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1866bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kPPC_LoadWordU32: 1867bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ASSEMBLE_LOAD_INTEGER(lwz, lwzx); 1868bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 1869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_LoadWordS32: 1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_LOAD_INTEGER(lwa, lwax); 1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_LoadWord64: 1874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_LOAD_INTEGER(ld, ldx); 1875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_LoadFloat32: 1878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_LOAD_FLOAT(lfs, lfsx); 1879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_LoadDouble: 1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_LOAD_FLOAT(lfd, lfdx); 1882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_StoreWord8: 1884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_STORE_INTEGER(stb, stbx); 1885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_StoreWord16: 1887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_STORE_INTEGER(sth, sthx); 1888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_StoreWord32: 1890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_STORE_INTEGER(stw, stwx); 1891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_StoreWord64: 1894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_STORE_INTEGER(std, stdx); 1895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_StoreFloat32: 1898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_STORE_FLOAT32(); 1899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPPC_StoreDouble: 1901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_STORE_DOUBLE(); 1902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadInt8: 1904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_LOAD_INTEGER(lbz, lbzx); 1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ extsb(i.OutputRegister(), i.OutputRegister()); 1906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadUint8: 1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_LOAD_INTEGER(lbz, lbzx); 1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadInt16: 1911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_LOAD_INTEGER(lha, lhax); 1912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadUint16: 1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_LOAD_INTEGER(lhz, lhzx); 1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadWord32: 1917bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ASSEMBLE_CHECKED_LOAD_INTEGER(lwz, lwzx); 1918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadWord64: 1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_LOAD_INTEGER(ld, ldx); 1922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadFloat32: 1927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_LOAD_FLOAT(lfs, lfsx, 32); 1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadFloat64: 1930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_LOAD_FLOAT(lfd, lfdx, 64); 1931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedStoreWord8: 1933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_STORE_INTEGER(stb, stbx); 1934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedStoreWord16: 1936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_STORE_INTEGER(sth, sthx); 1937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedStoreWord32: 1939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_STORE_INTEGER(stw, stwx); 1940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedStoreWord64: 1942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 1943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_STORE_INTEGER(std, stdx); 1944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 1945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 1947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedStoreFloat32: 1949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_STORE_FLOAT32(); 1950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedStoreFloat64: 1952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_STORE_DOUBLE(); 1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1954bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1955bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadInt8: 1956bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ASSEMBLE_ATOMIC_LOAD_INTEGER(lbz, lbzx); 1957bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ extsb(i.OutputRegister(), i.OutputRegister()); 1958bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 1959bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadUint8: 1960bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ASSEMBLE_ATOMIC_LOAD_INTEGER(lbz, lbzx); 1961bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 1962bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadInt16: 1963bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ASSEMBLE_ATOMIC_LOAD_INTEGER(lha, lhax); 1964bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 1965bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadUint16: 1966bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ASSEMBLE_ATOMIC_LOAD_INTEGER(lhz, lhzx); 1967bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 1968bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadWord32: 1969bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ASSEMBLE_ATOMIC_LOAD_INTEGER(lwz, lwzx); 1970bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 1971bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 1972bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicStoreWord8: 1973bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ASSEMBLE_ATOMIC_STORE_INTEGER(stb, stbx); 1974bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 1975bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicStoreWord16: 1976bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ASSEMBLE_ATOMIC_STORE_INTEGER(sth, sthx); 1977bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 1978bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicStoreWord32: 1979bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ASSEMBLE_ATOMIC_STORE_INTEGER(stw, stwx); 1980bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 1981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1985bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return kSuccess; 1986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // NOLINT(readability/fn_size) 1987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Assembles branches after an instruction. 1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { 1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PPCOperandConverter i(this, instr); 1992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* tlabel = branch->true_label; 1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* flabel = branch->false_label; 1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArchOpcode op = instr->arch_opcode(); 1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FlagsCondition condition = branch->condition; 1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CRegister cr = cr0; 1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Condition cond = FlagsConditionToCondition(condition, op); 1999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (op == kPPC_CmpDouble) { 2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // check for unordered if necessary 2001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (cond == le) { 2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bunordered(flabel, cr); 2003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unnecessary for eq/lt since only FU bit will be set. 2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (cond == gt) { 2005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bunordered(tlabel, cr); 2006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unnecessary for ne/ge since only FU bit will be set. 2007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ b(cond, tlabel, cr); 2010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!branch->fallthru) __ b(flabel); // no fallthru to flabel. 2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchJump(RpoNumber target) { 2015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target)); 2016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 201862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid CodeGenerator::AssembleArchTrap(Instruction* instr, 201962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FlagsCondition condition) { 202062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch class OutOfLineTrap final : public OutOfLineCode { 202162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public: 202262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch OutOfLineTrap(CodeGenerator* gen, bool frame_elided, Instruction* instr) 202362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : OutOfLineCode(gen), 202462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch frame_elided_(frame_elided), 202562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch instr_(instr), 202662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch gen_(gen) {} 202762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 202862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void Generate() final { 202962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PPCOperandConverter i(gen_, instr_); 203062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 203162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Builtins::Name trap_id = 203262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static_cast<Builtins::Name>(i.InputInt32(instr_->InputCount() - 1)); 203362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool old_has_frame = __ has_frame(); 203462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (frame_elided_) { 203562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ set_has_frame(true); 203662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ EnterFrame(StackFrame::WASM_COMPILED, true); 203762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 203862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GenerateCallToTrap(trap_id); 203962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (frame_elided_) { 204062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ set_has_frame(old_has_frame); 204162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 204262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 204362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 204462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private: 204562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void GenerateCallToTrap(Builtins::Name trap_id) { 204662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (trap_id == Builtins::builtin_count) { 204762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // We cannot test calls to the runtime in cctest/test-run-wasm. 204862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Therefore we emit a call to C here instead of a call to the runtime. 204962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // We use the context register as the scratch register, because we do 205062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // not have a context here. 205162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ PrepareCallCFunction(0, 0, cp); 205262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ CallCFunction( 205362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ExternalReference::wasm_call_trap_callback_for_testing(isolate()), 205462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 0); 205562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ LeaveFrame(StackFrame::WASM_COMPILED); 205662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Ret(); 205762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 205862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch gen_->AssembleSourcePosition(instr_); 205962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Call(handle(isolate()->builtins()->builtin(trap_id), isolate()), 206062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch RelocInfo::CODE_TARGET); 206162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ReferenceMap* reference_map = 206262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch new (gen_->zone()) ReferenceMap(gen_->zone()); 206362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0, 206462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Safepoint::kNoLazyDeopt); 206562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (FLAG_debug_code) { 206662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ stop(GetBailoutReason(kUnexpectedReturnFromWasmTrap)); 206762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 206862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 206962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 207062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 207162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool frame_elided_; 207262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Instruction* instr_; 207362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CodeGenerator* gen_; 207462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch }; 207562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool frame_elided = !frame_access_state()->has_frame(); 207662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto ool = new (zone()) OutOfLineTrap(this, frame_elided, instr); 207762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label* tlabel = ool->entry(); 207862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label end; 207962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 208062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ArchOpcode op = instr->arch_opcode(); 208162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CRegister cr = cr0; 208262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Condition cond = FlagsConditionToCondition(condition, op); 208362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (op == kPPC_CmpDouble) { 208462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // check for unordered if necessary 208562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (cond == le) { 208662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ bunordered(&end, cr); 208762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Unnecessary for eq/lt since only FU bit will be set. 208862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (cond == gt) { 208962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ bunordered(tlabel, cr); 209062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Unnecessary for ne/ge since only FU bit will be set. 209162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 209262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 209362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ b(cond, tlabel, cr); 209462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ bind(&end); 209562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 2096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Assembles boolean materializations after an instruction. 2098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchBoolean(Instruction* instr, 2099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FlagsCondition condition) { 2100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PPCOperandConverter i(this, instr); 2101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done; 2102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArchOpcode op = instr->arch_opcode(); 2103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CRegister cr = cr0; 2104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_value = -1; 2105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Materialize a full 32-bit 1 or 0 value. The result register is always the 2107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // last output of the instruction. 2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, instr->OutputCount()); 2109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg = i.OutputRegister(instr->OutputCount() - 1); 2110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Condition cond = FlagsConditionToCondition(condition, op); 2112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (op == kPPC_CmpDouble) { 2113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // check for unordered if necessary 2114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (cond == le) { 2115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg_value = 0; 2116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ li(reg, Operand::Zero()); 2117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bunordered(&done, cr); 2118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (cond == gt) { 2119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg_value = 1; 2120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ li(reg, Operand(1)); 2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bunordered(&done, cr); 2122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unnecessary for eq/lt & ne/ge since only FU bit will be set. 2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(ISELECT)) { 2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (cond) { 2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case eq: 2129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case lt: 2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case gt: 2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (reg_value != 1) __ li(reg, Operand(1)); 2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ li(kScratchReg, Operand::Zero()); 2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ isel(cond, reg, reg, kScratchReg, cr); 2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case ne: 2136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case ge: 2137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case le: 2138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (reg_value != 1) __ li(reg, Operand(1)); 2139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // r0 implies logical zero in this form 2140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ isel(NegateCondition(cond), reg, r0, reg, cr); 2141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 2143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (reg_value != 0) __ li(reg, Operand::Zero()); 2148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ b(NegateCondition(cond), &done, cr); 2149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ li(reg, Operand(1)); 2150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&done); 2152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) { 2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PPCOperandConverter i(this, instr); 2157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register input = i.InputRegister(0); 2158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t index = 2; index < instr->InputCount(); index += 2) { 2159bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ Cmpwi(input, Operand(i.InputInt32(index + 0)), r0); 2160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ beq(GetLabel(i.InputRpo(index + 1))); 2161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchJump(i.InputRpo(1)); 2163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchTableSwitch(Instruction* instr) { 2167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PPCOperandConverter i(this, instr); 2168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register input = i.InputRegister(0); 2169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t const case_count = static_cast<int32_t>(instr->InputCount() - 2); 2170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label** cases = zone()->NewArray<Label*>(case_count); 2171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int32_t index = 0; index < case_count; ++index) { 2172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cases[index] = GetLabel(i.InputRpo(index + 2)); 2173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* const table = AddJumpTable(cases, case_count); 2175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cmpli(input, Operand(case_count), r0); 2176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bge(GetLabel(i.InputRpo(1))); 2177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov_label_addr(kScratchReg, table); 2178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ShiftLeftImm(r0, input, Operand(kPointerSizeLog2)); 2179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadPX(kScratchReg, MemOperand(kScratchReg, r0)); 2180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Jump(kScratchReg); 2181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2183bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall( 218462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int deoptimization_id, SourcePosition pos) { 218562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DeoptimizeKind deoptimization_kind = GetDeoptimizationKind(deoptimization_id); 218662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DeoptimizeReason deoptimization_reason = 218762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GetDeoptimizationReason(deoptimization_id); 218862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Deoptimizer::BailoutType bailout_type = 218962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch deoptimization_kind == DeoptimizeKind::kSoft ? Deoptimizer::SOFT 219062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : Deoptimizer::EAGER; 2191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( 2192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate(), deoptimization_id, bailout_type); 21933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // TODO(turbofan): We should be able to generate better code by sharing the 21943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // actual final call site and just bl'ing to it here, similar to what we do 21953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // in the lithium backend. 2196bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts; 2197c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ RecordDeoptReason(deoptimization_reason, pos, deoptimization_id); 2198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); 2199bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return kSuccess; 2200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2202bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeGenerator::FinishFrame(Frame* frame) { 2203bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 2204bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch const RegList double_saves = descriptor->CalleeSavedFPRegisters(); 2205bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 2206bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Save callee-saved Double registers. 2207bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (double_saves != 0) { 2208bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch frame->AlignSavedCalleeRegisterSlots(); 2209bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(kNumCalleeSavedDoubles == 2210bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch base::bits::CountPopulation32(double_saves)); 2211bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch frame->AllocateSavedCalleeRegisterSlots(kNumCalleeSavedDoubles * 2212bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch (kDoubleSize / kPointerSize)); 2213bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2214bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Save callee-saved registers. 2215bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch const RegList saves = 2216bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch FLAG_enable_embedded_constant_pool 2217bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ? descriptor->CalleeSavedRegisters() & ~kConstantPoolRegister.bit() 2218bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch : descriptor->CalleeSavedRegisters(); 2219bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (saves != 0) { 2220bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // register save area does not include the fp or constant pool pointer. 2221bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch const int num_saves = 2222bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch kNumCalleeSaved - 1 - (FLAG_enable_embedded_constant_pool ? 1 : 0); 2223bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(num_saves == base::bits::CountPopulation32(saves)); 2224bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch frame->AllocateSavedCalleeRegisterSlots(num_saves); 2225bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2226bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 2227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2228bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeGenerator::AssembleConstructFrame() { 2229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 22303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (frame_access_state()->has_frame()) { 22313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (descriptor->IsCFunctionCall()) { 22323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ function_descriptor(); 22333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ mflr(r0); 22343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (FLAG_enable_embedded_constant_pool) { 22353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Push(r0, fp, kConstantPoolRegister); 22363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Adjust FP to point to saved FP. 22373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ subi(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset)); 22383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 22393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Push(r0, fp); 22403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ mr(fp, sp); 22413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 22423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (descriptor->IsJSFunctionCall()) { 22433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Prologue(this->info()->GeneratePreagedPrologue(), ip); 2244c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (descriptor->PushArgumentCount()) { 2245c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ Push(kJavaScriptCallArgCountRegister); 2246c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 2247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 22483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch StackFrame::Type type = info()->GetOutputStackFrameType(); 22493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // TODO(mbrandy): Detect cases where ip is the entrypoint (for 22503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // efficient intialization of the constant pool pointer register). 22513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ StubPrologue(type); 2252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2255c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int shrink_slots = 2256c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch frame()->GetTotalFrameSlotCount() - descriptor->CalculateFixedFrameSize(); 2257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info()->is_osr()) { 2258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TurboFan OSR-compiled functions cannot be entered directly. 2259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Abort(kShouldNotDirectlyEnterOsrFunction); 2260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unoptimized code jumps directly to this entrypoint while the unoptimized 2262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // frame is still on the stack. Optimized code uses OSR values directly from 2263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the unoptimized frame. Thus, all that needs to be done is to allocate the 2264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // remaining stack slots. 2265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); 2266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch osr_pc_offset_ = __ pc_offset(); 2267bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); 2268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegList double_saves = descriptor->CalleeSavedFPRegisters(); 2271bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (shrink_slots > 0) { 2272bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ Add(sp, sp, -shrink_slots * kPointerSize, r0); 2273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Save callee-saved Double registers. 2276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (double_saves != 0) { 2277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ MultiPushDoubles(double_saves); 2278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(kNumCalleeSavedDoubles == 2279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch base::bits::CountPopulation32(double_saves)); 2280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Save callee-saved registers. 2283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegList saves = 2284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FLAG_enable_embedded_constant_pool 2285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? descriptor->CalleeSavedRegisters() & ~kConstantPoolRegister.bit() 2286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : descriptor->CalleeSavedRegisters(); 2287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (saves != 0) { 2288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ MultiPush(saves); 2289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // register save area does not include the fp or constant pool pointer. 2290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2293c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid CodeGenerator::AssembleReturn(InstructionOperand* pop) { 2294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 2295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int pop_count = static_cast<int>(descriptor->StackParameterCount()); 2296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore registers. 2298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegList saves = 2299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FLAG_enable_embedded_constant_pool 2300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? descriptor->CalleeSavedRegisters() & ~kConstantPoolRegister.bit() 2301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : descriptor->CalleeSavedRegisters(); 2302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (saves != 0) { 2303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ MultiPop(saves); 2304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore double registers. 2307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegList double_saves = descriptor->CalleeSavedFPRegisters(); 2308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (double_saves != 0) { 2309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ MultiPopDoubles(double_saves); 2310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2311c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch PPCOperandConverter g(this, nullptr); 2312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (descriptor->IsCFunctionCall()) { 23143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AssembleDeconstructFrame(); 23153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (frame_access_state()->has_frame()) { 2316c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Canonicalize JSFunction return sites for now unless they have an variable 2317c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // number of stack slot pops 2318c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (pop->IsImmediate() && g.ToConstant(pop).ToInt32() == 0) { 2319c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (return_label_.is_bound()) { 2320c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ b(&return_label_); 2321c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 2322c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 2323c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ bind(&return_label_); 2324c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AssembleDeconstructFrame(); 2325c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 2326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 23273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AssembleDeconstructFrame(); 2328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2330c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (pop->IsImmediate()) { 2331c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(Constant::kInt32, g.ToConstant(pop).type()); 2332c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch pop_count += g.ToConstant(pop).ToInt32(); 2333c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 2334c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ Drop(g.ToRegister(pop)); 2335c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 2336c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ Drop(pop_count); 2337c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ Ret(); 2338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleMove(InstructionOperand* source, 2342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* destination) { 2343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PPCOperandConverter g(this, nullptr); 2344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Dispatch on the source and destination operand kinds. Not all 2345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // combinations are possible. 2346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsRegister()) { 2347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(destination->IsRegister() || destination->IsStackSlot()); 2348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register src = g.ToRegister(source); 2349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (destination->IsRegister()) { 2350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(g.ToRegister(destination), src); 2351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ StoreP(src, g.ToMemOperand(destination), r0); 2353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (source->IsStackSlot()) { 2355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(destination->IsRegister() || destination->IsStackSlot()); 2356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand src = g.ToMemOperand(source); 2357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (destination->IsRegister()) { 2358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(g.ToRegister(destination), src, r0); 2359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register temp = kScratchReg; 2361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(temp, src, r0); 2362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ StoreP(temp, g.ToMemOperand(destination), r0); 2363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (source->IsConstant()) { 2365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Constant src = g.ToConstant(source); 2366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (destination->IsRegister() || destination->IsStackSlot()) { 2367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register dst = 2368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch destination->IsRegister() ? g.ToRegister(destination) : kScratchReg; 2369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (src.type()) { 2370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kInt32: 2371bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#if V8_TARGET_ARCH_PPC64 237262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (RelocInfo::IsWasmSizeReference(src.rmode())) { 2373bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#else 237462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (RelocInfo::IsWasmReference(src.rmode())) { 2375bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#endif 2376bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ mov(dst, Operand(src.ToInt32(), src.rmode())); 2377bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 2378bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ mov(dst, Operand(src.ToInt32())); 2379bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kInt64: 2382bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#if V8_TARGET_ARCH_PPC64 238362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (RelocInfo::IsWasmPtrReference(src.rmode())) { 2384bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ mov(dst, Operand(src.ToInt64(), src.rmode())); 2385bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 238662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(!RelocInfo::IsWasmSizeReference(src.rmode())); 2387bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#endif 2388bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ mov(dst, Operand(src.ToInt64())); 2389bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#if V8_TARGET_ARCH_PPC64 2390bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2391bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#endif 2392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kFloat32: 2394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(dst, 2395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()->factory()->NewNumber(src.ToFloat32(), TENURED)); 2396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kFloat64: 2398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(dst, 2399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()->factory()->NewNumber(src.ToFloat64(), TENURED)); 2400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kExternalReference: 2402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(dst, Operand(src.ToExternalReference())); 2403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kHeapObject: { 2405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<HeapObject> src_object = src.ToHeapObject(); 2406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Heap::RootListIndex index; 2407f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsMaterializableFromRoot(src_object, &index)) { 2408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadRoot(dst, index); 2409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(dst, src_object); 2411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kRpoNumber: 2415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); // TODO(dcarney): loading RPO constants on PPC. 2416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (destination->IsStackSlot()) { 2419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ StoreP(dst, g.ToMemOperand(destination), r0); 2420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2422bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DoubleRegister dst = destination->IsFPRegister() 2423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? g.ToDoubleRegister(destination) 2424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : kScratchDoubleReg; 242562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch double value; 242662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// bit_cast of snan is converted to qnan on ia32/x64 242762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 242862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch intptr_t valueInt = (src.type() == Constant::kFloat32) 242962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ? src.ToFloat32AsInt() 243062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : src.ToFloat64AsInt(); 243162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (valueInt == ((src.type() == Constant::kFloat32) 243262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ? 0x7fa00000 243362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : 0x7fa0000000000000)) { 243462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = bit_cast<double, int64_t>(0x7ff4000000000000L); 243562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 243662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#endif 243762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = (src.type() == Constant::kFloat32) ? src.ToFloat32() 243862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : src.ToFloat64(); 243962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 244062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 244162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#endif 2442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadDoubleLiteral(dst, value, kScratchReg); 2443bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (destination->IsFPStackSlot()) { 2444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ StoreDouble(dst, g.ToMemOperand(destination), r0); 2445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2447bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (source->IsFPRegister()) { 2448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister src = g.ToDoubleRegister(source); 2449bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (destination->IsFPRegister()) { 2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister dst = g.ToDoubleRegister(destination); 2451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(dst, src); 2452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2453bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(destination->IsFPStackSlot()); 245413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch LocationOperand* op = LocationOperand::cast(source); 245513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (op->representation() == MachineRepresentation::kFloat64) { 245613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ StoreDouble(src, g.ToMemOperand(destination), r0); 245713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else { 245813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ StoreSingle(src, g.ToMemOperand(destination), r0); 245913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 2460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2461bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (source->IsFPStackSlot()) { 2462bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot()); 2463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand src = g.ToMemOperand(source); 2464bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (destination->IsFPRegister()) { 246513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch LocationOperand* op = LocationOperand::cast(source); 246613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (op->representation() == MachineRepresentation::kFloat64) { 246713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ LoadDouble(g.ToDoubleRegister(destination), src, r0); 246813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else { 246913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ LoadSingle(g.ToDoubleRegister(destination), src, r0); 247013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 2471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 247213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch LocationOperand* op = LocationOperand::cast(source); 2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister temp = kScratchDoubleReg; 247413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (op->representation() == MachineRepresentation::kFloat64) { 247513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ LoadDouble(temp, src, r0); 247613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ StoreDouble(temp, g.ToMemOperand(destination), r0); 247713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else { 247813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ LoadSingle(temp, src, r0); 247913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ StoreSingle(temp, g.ToMemOperand(destination), r0); 248013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 2481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleSwap(InstructionOperand* source, 2489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* destination) { 2490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PPCOperandConverter g(this, nullptr); 2491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Dispatch on the source and destination operand kinds. Not all 2492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // combinations are possible. 2493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsRegister()) { 2494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Register-register. 2495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register temp = kScratchReg; 2496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register src = g.ToRegister(source); 2497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (destination->IsRegister()) { 2498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register dst = g.ToRegister(destination); 2499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mr(temp, src); 2500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mr(src, dst); 2501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mr(dst, temp); 2502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(destination->IsStackSlot()); 2504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand dst = g.ToMemOperand(destination); 2505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mr(temp, src); 2506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(src, dst); 2507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ StoreP(temp, dst); 2508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if V8_TARGET_ARCH_PPC64 2510bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (source->IsStackSlot() || source->IsFPStackSlot()) { 2511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#else 2512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (source->IsStackSlot()) { 2513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(destination->IsStackSlot()); 2514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 2515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register temp_0 = kScratchReg; 2516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register temp_1 = r0; 2517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand src = g.ToMemOperand(source); 2518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand dst = g.ToMemOperand(destination); 2519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(temp_0, src); 2520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(temp_1, dst); 2521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ StoreP(temp_0, dst); 2522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ StoreP(temp_1, src); 2523bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (source->IsFPRegister()) { 2524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister temp = kScratchDoubleReg; 2525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister src = g.ToDoubleRegister(source); 2526bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (destination->IsFPRegister()) { 2527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister dst = g.ToDoubleRegister(destination); 2528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fmr(temp, src); 2529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fmr(src, dst); 2530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fmr(dst, temp); 2531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2532bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(destination->IsFPStackSlot()); 2533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand dst = g.ToMemOperand(destination); 2534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fmr(temp, src); 2535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lfd(src, dst); 2536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ stfd(temp, dst); 2537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if !V8_TARGET_ARCH_PPC64 2539bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (source->IsFPStackSlot()) { 2540bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(destination->IsFPStackSlot()); 2541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister temp_0 = kScratchDoubleReg; 2542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister temp_1 = d0; 2543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand src = g.ToMemOperand(source); 2544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemOperand dst = g.ToMemOperand(destination); 2545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lfd(temp_0, src); 2546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lfd(temp_1, dst); 2547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ stfd(temp_0, dst); 2548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ stfd(temp_1, src); 2549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 2550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // No other combinations are possible. 2552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) { 2558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t index = 0; index < target_count; ++index) { 2559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ emit_label_addr(targets[index]); 2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::EnsureSpaceForLazyDeopt() { 2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!info()->ShouldEnsureSpaceForLazyDeopt()) { 2566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int space_needed = Deoptimizer::patch_size(); 2570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Ensure that we have enough space after the previous lazy-bailout 2571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // instruction for patching the code here. 2572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int current_pc = masm()->pc_offset(); 2573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (current_pc < last_lazy_deopt_pc_ + space_needed) { 2574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Block tramoline pool emission for duration of padding. 2575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool( 2576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm()); 2577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 2578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize); 2579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (padding_size > 0) { 2580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ nop(); 2581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch padding_size -= v8::internal::Assembler::kInstrSize; 2582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef __ 2587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace compiler 2589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 2590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 2591