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