1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2013 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"
12109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/frames.h"
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/x87/assembler-x87.h"
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/x87/frames-x87.h"
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/x87/macro-assembler-x87.h"
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 {
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal {
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace compiler {
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define __ masm()->
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Adds X87 specific methods for decoding operands.
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass X87OperandConverter : public InstructionOperandConverter {
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X87OperandConverter(CodeGenerator* gen, Instruction* instr)
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : InstructionOperandConverter(gen, instr) {}
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Operand InputOperand(size_t index, int extra = 0) {
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return ToOperand(instr_->InputAt(index), extra);
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Immediate InputImmediate(size_t index) {
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return ToImmediate(instr_->InputAt(index));
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Operand OutputOperand() { return ToOperand(instr_->Output()); }
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Operand ToOperand(InstructionOperand* op, int extra = 0) {
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (op->IsRegister()) {
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(extra == 0);
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Operand(ToRegister(op));
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
45bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(op->IsStackSlot() || op->IsFPStackSlot());
463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return SlotToOperand(AllocatedOperand::cast(op)->index(), extra);
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Operand SlotToOperand(int slot, int extra = 0) {
503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    FrameOffset offset = frame_access_state()->GetFrameOffset(slot);
513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return Operand(offset.from_stack_pointer() ? esp : ebp,
523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                   offset.offset() + extra);
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Operand HighOperand(InstructionOperand* op) {
56bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(op->IsFPStackSlot());
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return ToOperand(op, kPointerSize);
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Immediate ToImmediate(InstructionOperand* operand) {
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Constant constant = ToConstant(operand);
62bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (constant.type() == Constant::kInt32 &&
6362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        RelocInfo::IsWasmReference(constant.rmode())) {
64bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return Immediate(reinterpret_cast<Address>(constant.ToInt32()),
65bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                       constant.rmode());
66bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (constant.type()) {
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Constant::kInt32:
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Immediate(constant.ToInt32());
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Constant::kFloat32:
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Immediate(
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Constant::kFloat64:
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Immediate(
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Constant::kExternalReference:
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Immediate(constant.ToExternalReference());
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Constant::kHeapObject:
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Immediate(constant.ToHeapObject());
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Constant::kInt64:
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Constant::kRpoNumber:
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Immediate::CodeRelativeOffset(ToLabel(operand));
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UNREACHABLE();
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Immediate(-1);
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static size_t NextOffset(size_t* offset) {
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t i = *offset;
91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    (*offset)++;
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return i;
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static ScaleFactor ScaleFor(AddressingMode one, AddressingMode mode) {
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    STATIC_ASSERT(0 == static_cast<int>(times_1));
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    STATIC_ASSERT(1 == static_cast<int>(times_2));
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    STATIC_ASSERT(2 == static_cast<int>(times_4));
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    STATIC_ASSERT(3 == static_cast<int>(times_8));
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int scale = static_cast<int>(mode - one);
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(scale >= 0 && scale < 4);
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<ScaleFactor>(scale);
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Operand MemoryOperand(size_t* offset) {
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AddressingMode mode = AddressingModeField::decode(instr_->opcode());
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (mode) {
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_MR: {
109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register base = InputRegister(NextOffset(offset));
110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int32_t disp = 0;
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Operand(base, disp);
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_MRI: {
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register base = InputRegister(NextOffset(offset));
11513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Constant ctant = ToConstant(instr_->InputAt(NextOffset(offset)));
11613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        return Operand(base, ctant.ToInt32(), ctant.rmode());
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_MR1:
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_MR2:
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_MR4:
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_MR8: {
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register base = InputRegister(NextOffset(offset));
123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register index = InputRegister(NextOffset(offset));
124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ScaleFactor scale = ScaleFor(kMode_MR1, mode);
125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int32_t disp = 0;
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Operand(base, index, scale, disp);
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_MR1I:
129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_MR2I:
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_MR4I:
131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_MR8I: {
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register base = InputRegister(NextOffset(offset));
133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register index = InputRegister(NextOffset(offset));
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ScaleFactor scale = ScaleFor(kMode_MR1I, mode);
13513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Constant ctant = ToConstant(instr_->InputAt(NextOffset(offset)));
13613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        return Operand(base, index, scale, ctant.ToInt32(), ctant.rmode());
137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_M1:
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_M2:
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_M4:
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_M8: {
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register index = InputRegister(NextOffset(offset));
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ScaleFactor scale = ScaleFor(kMode_M1, mode);
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int32_t disp = 0;
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Operand(index, scale, disp);
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_M1I:
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_M2I:
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_M4I:
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_M8I: {
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register index = InputRegister(NextOffset(offset));
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ScaleFactor scale = ScaleFor(kMode_M1I, mode);
15313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Constant ctant = ToConstant(instr_->InputAt(NextOffset(offset)));
15413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        return Operand(index, scale, ctant.ToInt32(), ctant.rmode());
155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_MI: {
15713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        Constant ctant = ToConstant(instr_->InputAt(NextOffset(offset)));
15813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        return Operand(ctant.ToInt32(), ctant.rmode());
159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMode_None:
161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNREACHABLE();
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Operand(no_reg, 0);
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UNREACHABLE();
165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Operand(no_reg, 0);
166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Operand MemoryOperand(size_t first_input = 0) {
169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return MemoryOperand(&first_input);
170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace {
175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool HasImmediateInput(Instruction* instr, size_t index) {
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return instr->InputAt(index)->IsImmediate();
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineLoadInteger final : public OutOfLineCode {
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OutOfLineLoadInteger(CodeGenerator* gen, Register result)
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : OutOfLineCode(gen), result_(result) {}
185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Generate() final { __ xor_(result_, result_); }
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const result_;
190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass OutOfLineLoadFloat32NaN final : public OutOfLineCode {
193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  OutOfLineLoadFloat32NaN(CodeGenerator* gen, X87Register result)
195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : OutOfLineCode(gen), result_(result) {}
196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void Generate() final {
198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK(result_.code() == 0);
199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    USE(result_);
200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    __ fstp(0);
201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    __ push(Immediate(0xffc00000));
202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    __ fld_s(MemOperand(esp, 0));
203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    __ lea(esp, Operand(esp, kFloatSize));
204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  X87Register const result_;
208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass OutOfLineLoadFloat64NaN final : public OutOfLineCode {
211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  OutOfLineLoadFloat64NaN(CodeGenerator* gen, X87Register result)
213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : OutOfLineCode(gen), result_(result) {}
214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Generate() final {
216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(result_.code() == 0);
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    USE(result_);
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ fstp(0);
219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    __ push(Immediate(0xfff80000));
220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    __ push(Immediate(0x00000000));
221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ fld_d(MemOperand(esp, 0));
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ lea(esp, Operand(esp, kDoubleSize));
223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X87Register const result_;
227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineTruncateDoubleToI final : public OutOfLineCode {
230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result,
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             X87Register input)
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : OutOfLineCode(gen), result_(result), input_(input) {}
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Generate() final {
236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UNIMPLEMENTED();
237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    USE(result_);
238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    USE(input_);
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const result_;
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X87Register const input_;
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineRecordWrite final : public OutOfLineCode {
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OutOfLineRecordWrite(CodeGenerator* gen, Register object, Operand operand,
250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       Register value, Register scratch0, Register scratch1,
251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       RecordWriteMode mode)
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : OutOfLineCode(gen),
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        object_(object),
254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        operand_(operand),
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        value_(value),
256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        scratch0_(scratch0),
257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        scratch1_(scratch1),
258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        mode_(mode) {}
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Generate() final {
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (mode_ > RecordWriteMode::kValueIsPointer) {
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ JumpIfSmi(value_, exit());
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
264109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ CheckPageFlag(value_, scratch0_,
265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                     MemoryChunk::kPointersToHereAreInterestingMask, zero,
266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                     exit());
267109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    RememberedSetAction const remembered_set_action =
268109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET
269109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                             : OMIT_REMEMBERED_SET;
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SaveFPRegsMode const save_fp_mode =
271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
273109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                         remembered_set_action, save_fp_mode);
274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ lea(scratch1_, operand_);
275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CallStub(&stub);
276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const object_;
280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Operand const operand_;
281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const value_;
282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const scratch0_;
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const scratch1_;
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RecordWriteMode const mode_;
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace
288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
289f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr, OutOfLineLoadNaN)      \
290f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  do {                                                                \
291f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    auto result = i.OutputDoubleRegister();                           \
292f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    auto offset = i.InputRegister(0);                                 \
293f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK(result.code() == 0);                                       \
294f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (instr->InputAt(1)->IsRegister()) {                            \
295f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ cmp(offset, i.InputRegister(1));                             \
296f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    } else {                                                          \
297f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ cmp(offset, i.InputImmediate(1));                            \
298f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }                                                                 \
299f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    OutOfLineCode* ool = new (zone()) OutOfLineLoadNaN(this, result); \
300f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    __ j(above_equal, ool->entry());                                  \
301f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    __ fstp(0);                                                       \
302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    __ asm_instr(i.MemoryOperand(2));                                 \
303f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    __ bind(ool->exit());                                             \
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } while (false)
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr)                          \
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  do {                                                                    \
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto result = i.OutputRegister();                                     \
309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto offset = i.InputRegister(0);                                     \
310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr->InputAt(1)->IsRegister()) {                                \
311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ cmp(offset, i.InputRegister(1));                                 \
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {                                                              \
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ cmp(offset, i.InputImmediate(1));                                \
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }                                                                     \
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    OutOfLineCode* ool = new (zone()) OutOfLineLoadInteger(this, result); \
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ j(above_equal, ool->entry());                                      \
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ asm_instr(result, i.MemoryOperand(2));                             \
318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bind(ool->exit());                                                 \
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } while (false)
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr)   \
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  do {                                            \
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto offset = i.InputRegister(0);             \
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr->InputAt(1)->IsRegister()) {        \
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ cmp(offset, i.InputRegister(1));         \
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {                                      \
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ cmp(offset, i.InputImmediate(1));        \
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }                                             \
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Label done;                                   \
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(i.InputDoubleRegister(2).code() == 0); \
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ j(above_equal, &done, Label::kNear);       \
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ asm_instr(i.MemoryOperand(3));             \
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bind(&done);                               \
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } while (false)
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr)            \
339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  do {                                                       \
340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto offset = i.InputRegister(0);                        \
341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr->InputAt(1)->IsRegister()) {                   \
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ cmp(offset, i.InputRegister(1));                    \
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {                                                 \
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ cmp(offset, i.InputImmediate(1));                   \
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }                                                        \
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Label done;                                              \
347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ j(above_equal, &done, Label::kNear);                  \
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr->InputAt(2)->IsRegister()) {                   \
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ asm_instr(i.MemoryOperand(3), i.InputRegister(2));  \
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {                                                 \
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }                                                        \
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bind(&done);                                          \
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } while (false)
355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#define ASSEMBLE_COMPARE(asm_instr)                                   \
3573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  do {                                                                \
3583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (AddressingModeField::decode(instr->opcode()) != kMode_None) { \
3593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      size_t index = 0;                                               \
3603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Operand left = i.MemoryOperand(&index);                         \
3613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (HasImmediateInput(instr, index)) {                          \
3623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ asm_instr(left, i.InputImmediate(index));                  \
3633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {                                                        \
3643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ asm_instr(left, i.InputRegister(index));                   \
3653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }                                                               \
3663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    } else {                                                          \
3673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (HasImmediateInput(instr, 1)) {                              \
3683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (instr->InputAt(0)->IsRegister()) {                        \
3693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          __ asm_instr(i.InputRegister(0), i.InputImmediate(1));      \
3703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        } else {                                                      \
3713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          __ asm_instr(i.InputOperand(0), i.InputImmediate(1));       \
3723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }                                                             \
3733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {                                                        \
3743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (instr->InputAt(1)->IsRegister()) {                        \
3753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          __ asm_instr(i.InputRegister(0), i.InputRegister(1));       \
3763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        } else {                                                      \
3773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          __ asm_instr(i.InputRegister(0), i.InputOperand(1));        \
3783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }                                                             \
3793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }                                                               \
3803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }                                                                 \
3813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } while (0)
3823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
38313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define ASSEMBLE_IEEE754_BINOP(name)                                          \
38413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  do {                                                                        \
38513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Saves the esp into ebx */                                              \
38613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ push(ebx);                                                             \
38713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ mov(ebx, esp);                                                         \
38813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Pass one double as argument on the stack. */                           \
38913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ PrepareCallCFunction(4, eax);                                          \
39013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ fstp(0);                                                               \
39113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Load first operand from original stack */                              \
39213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ fld_d(MemOperand(ebx, 4 + kDoubleSize));                               \
39313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Put first operand into stack for function call */                      \
39413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ fstp_d(Operand(esp, 0 * kDoubleSize));                                 \
39513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Load second operand from original stack */                             \
39613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ fld_d(MemOperand(ebx, 4));                                             \
39713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Put second operand into stack for function call */                     \
39813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ fstp_d(Operand(esp, 1 * kDoubleSize));                                 \
39913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \
40013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                     4);                                                      \
40113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Restore the ebx */                                                     \
40213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ pop(ebx);                                                              \
40313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Return value is in st(0) on x87. */                                    \
40413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ lea(esp, Operand(esp, 2 * kDoubleSize));                               \
40513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } while (false)
40613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
40713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define ASSEMBLE_IEEE754_UNOP(name)                                           \
40813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  do {                                                                        \
40913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Saves the esp into ebx */                                              \
41013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ push(ebx);                                                             \
41113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ mov(ebx, esp);                                                         \
41213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Pass one double as argument on the stack. */                           \
41313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ PrepareCallCFunction(2, eax);                                          \
41413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ fstp(0);                                                               \
41513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Load operand from original stack */                                    \
41613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ fld_d(MemOperand(ebx, 4));                                             \
41713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Put operand into stack for function call */                            \
41813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ fstp_d(Operand(esp, 0));                                               \
41913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \
42013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                     2);                                                      \
42113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Restore the ebx */                                                     \
42213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ pop(ebx);                                                              \
42313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Return value is in st(0) on x87. */                                    \
42413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ lea(esp, Operand(esp, kDoubleSize));                                   \
42513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } while (false)
42613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
4273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid CodeGenerator::AssembleDeconstructFrame() {
4283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ mov(esp, ebp);
4293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ pop(ebp);
4303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
4313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
432f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssemblePrepareTailCall() {
4333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (frame_access_state()->has_frame()) {
434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ mov(ebp, MemOperand(ebp, 0));
435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frame_access_state()->SetFrameAccessToSP();
437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
4403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                     Register, Register,
4413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                     Register) {
4423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // There are not enough temp registers left on ia32 for a call instruction
4433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // so we pick some scratch registers and save/restore them manually here.
4443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int scratch_count = 3;
4453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Register scratch1 = ebx;
4463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Register scratch2 = ecx;
4473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Register scratch3 = edx;
4483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
4493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Label done;
4503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Check if current frame is an arguments adaptor frame.
4523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ cmp(Operand(ebp, StandardFrameConstants::kContextOffset),
4533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch         Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
4543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ j(not_equal, &done, Label::kNear);
4553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ push(scratch1);
4573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ push(scratch2);
4583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ push(scratch3);
4593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Load arguments count from current arguments adaptor frame (note, it
4613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // does not include receiver).
4623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Register caller_args_count_reg = scratch1;
4633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ mov(caller_args_count_reg,
4643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch         Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset));
4653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ SmiUntag(caller_args_count_reg);
4663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  ParameterCount callee_args_count(args_reg);
4683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
4693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                        scratch3, ReturnAddressState::kOnStack, scratch_count);
4703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ pop(scratch3);
4713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ pop(scratch2);
4723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ pop(scratch1);
4733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
4743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ bind(&done);
4753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
477f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace {
478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid AdjustStackPointerForTailCall(MacroAssembler* masm,
480f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                   FrameAccessState* state,
481f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                   int new_slot_above_sp,
482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                   bool allow_shrinkage = true) {
483f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int current_sp_offset = state->GetSPToFPSlotCount() +
484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                          StandardFrameConstants::kFixedSlotCountAboveFp;
485f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int stack_slot_delta = new_slot_above_sp - current_sp_offset;
486f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (stack_slot_delta > 0) {
487f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    masm->sub(esp, Immediate(stack_slot_delta * kPointerSize));
488f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    state->IncreaseSPDelta(stack_slot_delta);
489f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else if (allow_shrinkage && stack_slot_delta < 0) {
490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    masm->add(esp, Immediate(-stack_slot_delta * kPointerSize));
491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    state->IncreaseSPDelta(stack_slot_delta);
492f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
493f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
495f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace
496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
497f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssembleTailCallBeforeGap(Instruction* instr,
498f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                              int first_unused_stack_slot) {
499f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CodeGenerator::PushTypeFlags flags(kImmediatePush | kScalarPush);
500f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ZoneVector<MoveOperands*> pushes(zone());
501f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  GetPushCompatibleMoves(instr, flags, &pushes);
502f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
503f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!pushes.empty() &&
504f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      (LocationOperand::cast(pushes.back()->destination()).index() + 1 ==
505f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch       first_unused_stack_slot)) {
506f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    X87OperandConverter g(this, instr);
507f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    for (auto move : pushes) {
508f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      LocationOperand destination_location(
509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          LocationOperand::cast(move->destination()));
510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InstructionOperand source(move->source());
511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      AdjustStackPointerForTailCall(masm(), frame_access_state(),
512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                    destination_location.index());
513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (source.IsStackSlot()) {
514f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        LocationOperand source_location(LocationOperand::cast(source));
515f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ push(g.SlotToOperand(source_location.index()));
516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else if (source.IsRegister()) {
517f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        LocationOperand source_location(LocationOperand::cast(source));
518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ push(source_location.GetRegister());
519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else if (source.IsImmediate()) {
520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ push(Immediate(ImmediateOperand::cast(source).inline_value()));
521f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // Pushes of non-scalar data types is not supported.
523f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        UNIMPLEMENTED();
524f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
525f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      frame_access_state()->IncreaseSPDelta(1);
526f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      move->Eliminate();
527f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
528f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  AdjustStackPointerForTailCall(masm(), frame_access_state(),
530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                first_unused_stack_slot, false);
531f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                             int first_unused_stack_slot) {
535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  AdjustStackPointerForTailCall(masm(), frame_access_state(),
536f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                first_unused_stack_slot);
537f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
538f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Assembles an instruction after register allocation, producing machine code.
540bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
541bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Instruction* instr) {
542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X87OperandConverter i(this, instr);
5433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  InstructionCode opcode = instr->opcode();
5443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
5453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
5463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  switch (arch_opcode) {
547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchCallCodeObject: {
548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      EnsureSpaceForLazyDeopt();
553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 0)) {
554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ call(code, RelocInfo::CODE_TARGET);
556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register reg = i.InputRegister(0);
558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ call(reg);
560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RecordCallPosition(instr);
562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool double_result =
563bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          instr->HasOutput() && instr->Output()->IsFPRegister();
564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (double_result) {
565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ lea(esp, Operand(esp, -kDoubleSize));
566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp_d(Operand(esp, 0));
567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fninit();
569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (double_result) {
570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(Operand(esp, 0));
571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ lea(esp, Operand(esp, kDoubleSize));
572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld1();
574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kArchTailCallCodeObjectFromJSFunction:
579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchTailCallCodeObject: {
580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
5843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
5853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
5863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                         no_reg, no_reg, no_reg);
5873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 0)) {
589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ jmp(code, RelocInfo::CODE_TARGET);
591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register reg = i.InputRegister(0);
593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ jmp(reg);
595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
597f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      frame_access_state()->SetFrameAccessToDefault();
598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
600bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kArchTailCallAddress: {
601bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CHECK(!HasImmediateInput(instr, 0));
602bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Register reg = i.InputRegister(0);
603bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ jmp(reg);
604bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      frame_access_state()->ClearSPDelta();
605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      frame_access_state()->SetFrameAccessToDefault();
606bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
607bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchCallJSFunction: {
609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      EnsureSpaceForLazyDeopt();
610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register func = i.InputRegister(0);
611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code) {
612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Check the function's context matches the context argument.
613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Assert(equal, kWrongFunctionContext);
615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ call(FieldOperand(func, JSFunction::kCodeEntryOffset));
621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RecordCallPosition(instr);
622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool double_result =
623bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          instr->HasOutput() && instr->Output()->IsFPRegister();
624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (double_result) {
625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ lea(esp, Operand(esp, -kDoubleSize));
626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp_d(Operand(esp, 0));
627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fninit();
629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (double_result) {
630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(Operand(esp, 0));
631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ lea(esp, Operand(esp, kDoubleSize));
632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld1();
634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
638c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case kArchTailCallJSFunctionFromJSFunction: {
639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register func = i.InputRegister(0);
640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code) {
641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Check the function's context matches the context argument.
642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Assert(equal, kWrongFunctionContext);
644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
649c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, no_reg,
650c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                       no_reg, no_reg);
651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset));
652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
653f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      frame_access_state()->SetFrameAccessToDefault();
654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchPrepareCallCFunction: {
657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Frame alignment requires using FP-relative frame addressing.
658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->SetFrameAccessToFP();
659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int const num_parameters = MiscField::decode(instr->opcode());
660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ PrepareCallCFunction(num_parameters, i.TempRegister(0));
661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchPrepareTailCall:
664f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      AssemblePrepareTailCall();
665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchCallCFunction: {
667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int const num_parameters = MiscField::decode(instr->opcode());
672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 0)) {
673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ExternalReference ref = i.InputExternalReference(0);
674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ CallCFunction(ref, num_parameters);
675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register func = i.InputRegister(0);
677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ CallCFunction(func, num_parameters);
678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool double_result =
680bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          instr->HasOutput() && instr->Output()->IsFPRegister();
681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (double_result) {
682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ lea(esp, Operand(esp, -kDoubleSize));
683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp_d(Operand(esp, 0));
684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fninit();
686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (double_result) {
687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(Operand(esp, 0));
688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ lea(esp, Operand(esp, kDoubleSize));
689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld1();
691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->SetFrameAccessToDefault();
693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchJmp:
697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AssembleArchJump(i.InputRpo(0));
698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchLookupSwitch:
700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AssembleArchLookupSwitch(instr);
701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchTableSwitch:
703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AssembleArchTableSwitch(instr);
704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
70513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kArchComment: {
70613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Address comment_string = i.InputExternalReference(0).address();
70713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ RecordComment(reinterpret_cast<const char*>(comment_string));
70813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
70913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
71013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kArchDebugBreak:
71113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ int3();
71213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchNop:
714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchThrowTerminator:
715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // don't emit code for nops.
716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchDeoptimize: {
718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int deopt_state_id =
719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int double_register_param_count = 0;
721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int x87_layout = 0;
722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (size_t i = 0; i < instr->InputCount(); i++) {
723bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        if (instr->InputAt(i)->IsFPRegister()) {
724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          double_register_param_count++;
725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Currently we use only one X87 register. If double_register_param_count
728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // is bigger than 1, it means duplicated double register is added to input
729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // of this instruction.
730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (double_register_param_count > 0) {
731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        x87_layout = (0 << 3) | 1;
732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The layout of x87 register stack is loaded on the top of FPU register
734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // stack for deoptimization.
735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ push(Immediate(x87_layout));
736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fild_s(MemOperand(esp, 0));
737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, kPointerSize));
738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
73962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      CodeGenResult result =
74062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          AssembleDeoptimizerCall(deopt_state_id, current_source_position_);
741bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (result != kSuccess) return result;
742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchRet:
745c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      AssembleReturn(instr->InputAt(0));
746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchFramePointer:
748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mov(i.OutputRegister(), ebp);
749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchStackPointer:
751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mov(i.OutputRegister(), esp);
752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
753109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kArchParentFramePointer:
7543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (frame_access_state()->has_frame()) {
755109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ mov(i.OutputRegister(), Operand(ebp, 0));
756109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
757109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ mov(i.OutputRegister(), ebp);
758109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
759109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchTruncateDoubleToI: {
761bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!instr->InputAt(0)->IsFPRegister()) {
762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(i.InputOperand(0));
763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ TruncateX87TOSToI(i.OutputRegister());
765bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!instr->InputAt(0)->IsFPRegister()) {
766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp(0);
767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchStoreWithWriteBarrier: {
771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RecordWriteMode mode =
772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<RecordWriteMode>(MiscField::decode(instr->opcode()));
773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register object = i.InputRegister(0);
774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_t index = 0;
775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Operand operand = i.MemoryOperand(&index);
776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register value = i.InputRegister(index);
777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register scratch0 = i.TempRegister(0);
778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register scratch1 = i.TempRegister(1);
779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      auto ool = new (zone()) OutOfLineRecordWrite(this, object, operand, value,
780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   scratch0, scratch1, mode);
781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mov(operand, value);
782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ CheckPageFlag(object, scratch0,
783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       MemoryChunk::kPointersFromHereAreInterestingMask,
784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       not_zero, ool->entry());
785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ bind(ool->exit());
786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
788109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kArchStackSlot: {
789109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      FrameOffset offset =
790109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          frame_access_state()->GetFrameOffset(i.InputInt32(0));
791109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Register base;
792109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (offset.from_stack_pointer()) {
793109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        base = esp;
794109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
795109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        base = ebp;
796109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
797109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ lea(i.OutputRegister(), Operand(base, offset.offset()));
798109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
799109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
800f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Acos:
801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(acos);
802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Acosh:
804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(acosh);
805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Asin:
807f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(asin);
808f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
809f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Asinh:
810f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(asinh);
811f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
81213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Atan:
81313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(atan);
81413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Atanh:
816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(atanh);
817f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
81813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Atan2:
81913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_BINOP(atan2);
82013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
82113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Cbrt:
82213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(cbrt);
82313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
82413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Cos:
82513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ X87SetFPUCW(0x027F);
82613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(cos);
82713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ X87SetFPUCW(0x037F);
82813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Cosh:
830f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(cosh);
831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
83213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Expm1:
83313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ X87SetFPUCW(0x027F);
83413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(expm1);
83513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ X87SetFPUCW(0x037F);
83613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
83713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Exp:
83813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(exp);
83913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
84013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Log:
84113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(log);
84213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
84313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Log1p:
84413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(log1p);
84513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
84613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Log2:
84713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(log2);
84813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
84913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Log10:
85013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(log10);
85113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
852f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Pow: {
853f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Keep the x87 FPU stack empty before calling stub code
854f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fstp(0);
855f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Call the MathStub and put return value in stX_0
856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MathPowStub stub(isolate(), MathPowStub::DOUBLE);
857f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ CallStub(&stub);
858f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      /* Return value is in st(0) on x87. */
859f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ lea(esp, Operand(esp, 2 * kDoubleSize));
860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
861f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
86213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Sin:
86313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ X87SetFPUCW(0x027F);
86413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(sin);
86513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ X87SetFPUCW(0x037F);
86613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Sinh:
868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(sinh);
869f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
87013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Tan:
87113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ X87SetFPUCW(0x027F);
87213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(tan);
87313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ X87SetFPUCW(0x037F);
87413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Tanh:
876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(tanh);
877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Add:
879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 1)) {
880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ add(i.InputOperand(0), i.InputImmediate(1));
881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ add(i.InputRegister(0), i.InputOperand(1));
883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87And:
886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 1)) {
887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ and_(i.InputOperand(0), i.InputImmediate(1));
888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ and_(i.InputRegister(0), i.InputOperand(1));
890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Cmp:
8933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ASSEMBLE_COMPARE(cmp);
8943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
8953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kX87Cmp16:
8963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ASSEMBLE_COMPARE(cmpw);
8973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
8983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kX87Cmp8:
8993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ASSEMBLE_COMPARE(cmpb);
900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Test:
9023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ASSEMBLE_COMPARE(test);
9033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
9043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kX87Test16:
9053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ASSEMBLE_COMPARE(test_w);
9063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
9073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kX87Test8:
9083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ASSEMBLE_COMPARE(test_b);
909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Imul:
911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 1)) {
912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ imul(i.OutputRegister(), i.InputOperand(0), i.InputInt32(1));
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ imul(i.OutputRegister(), i.InputOperand(1));
915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87ImulHigh:
918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ imul(i.InputRegister(1));
919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87UmulHigh:
921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mul(i.InputRegister(1));
922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Idiv:
924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ cdq();
925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ idiv(i.InputOperand(1));
926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Udiv:
928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Move(edx, Immediate(0));
929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ div(i.InputOperand(1));
930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Not:
932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ not_(i.OutputOperand());
933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Neg:
935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ neg(i.OutputOperand());
936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Or:
938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 1)) {
939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ or_(i.InputOperand(0), i.InputImmediate(1));
940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ or_(i.InputRegister(0), i.InputOperand(1));
942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Xor:
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 1)) {
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ xor_(i.InputOperand(0), i.InputImmediate(1));
947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ xor_(i.InputRegister(0), i.InputOperand(1));
949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Sub:
952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 1)) {
953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sub(i.InputOperand(0), i.InputImmediate(1));
954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sub(i.InputRegister(0), i.InputOperand(1));
956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Shl:
959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 1)) {
960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ shl(i.OutputOperand(), i.InputInt5(1));
961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ shl_cl(i.OutputOperand());
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Shr:
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 1)) {
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ shr(i.OutputOperand(), i.InputInt5(1));
968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ shr_cl(i.OutputOperand());
970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Sar:
973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 1)) {
974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sar(i.OutputOperand(), i.InputInt5(1));
975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sar_cl(i.OutputOperand());
977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
9793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kX87AddPair: {
9803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // i.OutputRegister(0) == i.InputRegister(0) ... left low word.
9813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // i.InputRegister(1) ... left high word.
9823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // i.InputRegister(2) ... right low word.
9833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // i.InputRegister(3) ... right high word.
9843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      bool use_temp = false;
9853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (i.OutputRegister(0).code() == i.InputRegister(1).code() ||
9863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          i.OutputRegister(0).code() == i.InputRegister(3).code()) {
9873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // We cannot write to the output register directly, because it would
9883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // overwrite an input for adc. We have to use the temp register.
9893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        use_temp = true;
9903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ Move(i.TempRegister(0), i.InputRegister(0));
9913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ add(i.TempRegister(0), i.InputRegister(2));
9923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {
9933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ add(i.OutputRegister(0), i.InputRegister(2));
9943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
9953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (i.OutputRegister(1).code() != i.InputRegister(1).code()) {
9963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ Move(i.OutputRegister(1), i.InputRegister(1));
9973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
99862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      __ adc(i.OutputRegister(1), Operand(i.InputRegister(3)));
9993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (use_temp) {
10003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ Move(i.OutputRegister(0), i.TempRegister(0));
10013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
10023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
10033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
10043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kX87SubPair: {
10053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // i.OutputRegister(0) == i.InputRegister(0) ... left low word.
10063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // i.InputRegister(1) ... left high word.
10073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // i.InputRegister(2) ... right low word.
10083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // i.InputRegister(3) ... right high word.
10093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      bool use_temp = false;
10103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (i.OutputRegister(0).code() == i.InputRegister(1).code() ||
10113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          i.OutputRegister(0).code() == i.InputRegister(3).code()) {
10123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // We cannot write to the output register directly, because it would
10133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // overwrite an input for adc. We have to use the temp register.
10143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        use_temp = true;
10153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ Move(i.TempRegister(0), i.InputRegister(0));
10163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ sub(i.TempRegister(0), i.InputRegister(2));
10173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {
10183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ sub(i.OutputRegister(0), i.InputRegister(2));
10193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
10203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (i.OutputRegister(1).code() != i.InputRegister(1).code()) {
10213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ Move(i.OutputRegister(1), i.InputRegister(1));
10223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
102362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      __ sbb(i.OutputRegister(1), Operand(i.InputRegister(3)));
10243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (use_temp) {
10253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ Move(i.OutputRegister(0), i.TempRegister(0));
10263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
10273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
10283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
10293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kX87MulPair: {
10303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ imul(i.OutputRegister(1), i.InputOperand(0));
10313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ mov(i.TempRegister(0), i.InputOperand(1));
10323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ imul(i.TempRegister(0), i.InputOperand(2));
10333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ add(i.OutputRegister(1), i.TempRegister(0));
10343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ mov(i.OutputRegister(0), i.InputOperand(0));
10353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // Multiplies the low words and stores them in eax and edx.
10363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ mul(i.InputRegister(2));
10373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ add(i.OutputRegister(1), i.TempRegister(0));
10383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
10393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
10403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
10413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kX87ShlPair:
10423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (HasImmediateInput(instr, 2)) {
10433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ ShlPair(i.InputRegister(1), i.InputRegister(0), i.InputInt6(2));
10443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {
10453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // Shift has been loaded into CL by the register allocator.
10463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ ShlPair_cl(i.InputRegister(1), i.InputRegister(0));
10473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
10483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
10493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kX87ShrPair:
10503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (HasImmediateInput(instr, 2)) {
10513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ ShrPair(i.InputRegister(1), i.InputRegister(0), i.InputInt6(2));
10523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {
10533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // Shift has been loaded into CL by the register allocator.
10543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ ShrPair_cl(i.InputRegister(1), i.InputRegister(0));
10553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
10563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
10573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kX87SarPair:
10583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (HasImmediateInput(instr, 2)) {
10593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ SarPair(i.InputRegister(1), i.InputRegister(0), i.InputInt6(2));
10603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {
10613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // Shift has been loaded into CL by the register allocator.
10623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ SarPair_cl(i.InputRegister(1), i.InputRegister(0));
10633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
10643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Ror:
1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 1)) {
1067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ ror(i.OutputOperand(), i.InputInt5(1));
1068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ ror_cl(i.OutputOperand());
1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Lzcnt:
1073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Lzcnt(i.OutputRegister(), i.InputOperand(0));
1074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Popcnt:
1076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Popcnt(i.OutputRegister(), i.InputOperand(0));
1077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87LoadFloat64Constant: {
1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* source = instr->InputAt(0);
1080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* destination = instr->Output();
1081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(source->IsConstant());
1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      X87OperandConverter g(this, nullptr);
1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Constant src_constant = g.ToConstant(source);
1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_EQ(Constant::kFloat64, src_constant.type());
1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64());
1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t lower = static_cast<uint32_t>(src);
1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t upper = static_cast<uint32_t>(src >> 32);
1089bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (destination->IsFPRegister()) {
1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sub(esp, Immediate(kDoubleSize));
1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(MemOperand(esp, 0), Immediate(lower));
1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(MemOperand(esp, kInt32Size), Immediate(upper));
1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp(0);
1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(MemOperand(esp, 0));
1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ add(esp, Immediate(kDoubleSize));
1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNREACHABLE();
1098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float32Cmp: {
1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_s(MemOperand(esp, kFloatSize));
1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_s(MemOperand(esp, 0));
1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ FCmp();
1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, 2 * kFloatSize));
1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float32Add: {
1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x027F);
1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_s(MemOperand(esp, 0));
1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_s(MemOperand(esp, kFloatSize));
1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ faddp();
1117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Clear stack.
1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, 2 * kFloatSize));
1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Restore the default value of control word.
1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x037F);
1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float32Sub: {
1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x027F);
1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_s(MemOperand(esp, kFloatSize));
1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_s(MemOperand(esp, 0));
1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fsubp();
1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Clear stack.
1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, 2 * kFloatSize));
1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Restore the default value of control word.
1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x037F);
1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float32Mul: {
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x027F);
1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_s(MemOperand(esp, kFloatSize));
1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_s(MemOperand(esp, 0));
1146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fmulp();
1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Clear stack.
1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, 2 * kFloatSize));
1149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Restore the default value of control word.
1150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x037F);
1151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float32Div: {
1154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x027F);
1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_s(MemOperand(esp, kFloatSize));
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_s(MemOperand(esp, 0));
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fdivp();
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Clear stack.
1163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, 2 * kFloatSize));
1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Restore the default value of control word.
1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x037F);
1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kX87Float32Sqrt: {
1170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_s(MemOperand(esp, 0));
1175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fsqrt();
1176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ lea(esp, Operand(esp, kFloatSize));
1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kX87Float32Abs: {
1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_s(MemOperand(esp, 0));
1185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fabs();
1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, kFloatSize));
1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kX87Float32Neg: {
1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_s(MemOperand(esp, 0));
1195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fchs();
1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, kFloatSize));
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float32Round: {
1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RoundingMode mode =
1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Set the correct round mode in x87 control register
1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetRC((mode << 10));
1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1205bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!instr->InputAt(0)->IsFPRegister()) {
1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand* input = instr->InputAt(0);
1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        USE(input);
1208bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(input->IsFPStackSlot());
1209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ VerifyX87StackDepth(1);
1211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp(0);
1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_s(i.InputOperand(0));
1214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ frndint();
1216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetRC(0x0000);
1217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64Add: {
1220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x027F);
1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, 0));
1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, kDoubleSize));
1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ faddp();
1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Clear stack.
1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, 2 * kDoubleSize));
1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Restore the default value of control word.
1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x037F);
1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64Sub: {
1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x027F);
1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, kDoubleSize));
1241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fsub_d(MemOperand(esp, 0));
1242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Clear stack.
1243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, 2 * kDoubleSize));
1244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Restore the default value of control word.
1245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x037F);
1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64Mul: {
1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x027F);
1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, kDoubleSize));
1255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fmul_d(MemOperand(esp, 0));
1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Clear stack.
1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, 2 * kDoubleSize));
1258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Restore the default value of control word.
1259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x037F);
1260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64Div: {
1263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x027F);
1267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, kDoubleSize));
1269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fdiv_d(MemOperand(esp, 0));
1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Clear stack.
1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, 2 * kDoubleSize));
1272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Restore the default value of control word.
1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x037F);
1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64Mod: {
1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FrameScope frame_scope(&masm_, StackFrame::MANUAL);
1278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mov(eax, esp);
1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ PrepareCallCFunction(4, eax);
1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(eax, 0));
1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp_d(Operand(esp, 1 * kDoubleSize));
1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(eax, kDoubleSize));
1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp_d(Operand(esp, 0));
1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()),
1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       4);
1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, 2 * kDoubleSize));
1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1293f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kX87Float32Max: {
1294f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Label compare_swap, done_compare;
1295f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1296f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ VerifyX87StackDepth(1);
1297f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
1298f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fstp(0);
1299f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fld_s(MemOperand(esp, kFloatSize));
1300f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fld_s(MemOperand(esp, 0));
1301f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fld(1);
1302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fld(1);
1303f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ FCmp();
1304f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1305f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      auto ool =
1306f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          new (zone()) OutOfLineLoadFloat32NaN(this, i.OutputDoubleRegister());
1307f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(parity_even, ool->entry());
1308f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(below, &done_compare, Label::kNear);
1309f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(above, &compare_swap, Label::kNear);
1310f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ push(eax);
1311f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ lea(esp, Operand(esp, -kFloatSize));
1312f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fld(1);
1313f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fstp_s(Operand(esp, 0));
1314f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ mov(eax, MemOperand(esp, 0));
1315f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ and_(eax, Immediate(0x80000000));
1316f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ lea(esp, Operand(esp, kFloatSize));
1317f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ pop(eax);
1318f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(zero, &done_compare, Label::kNear);
1319f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1320f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&compare_swap);
1321f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(ool->exit());
1322f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fxch(1);
1323f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1324f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&done_compare);
1325f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fstp(0);
1326f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ lea(esp, Operand(esp, 2 * kFloatSize));
1327f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1328f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64Max: {
1330f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Label compare_swap, done_compare;
1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, kDoubleSize));
1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, 0));
1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld(1);
1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld(1);
1339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ FCmp();
1340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      auto ool =
1342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          new (zone()) OutOfLineLoadFloat64NaN(this, i.OutputDoubleRegister());
1343f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(parity_even, ool->entry());
1344f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(below, &done_compare, Label::kNear);
1345f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(above, &compare_swap, Label::kNear);
1346f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ push(eax);
1347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ lea(esp, Operand(esp, -kDoubleSize));
1348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fld(1);
1349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fstp_d(Operand(esp, 0));
1350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ mov(eax, MemOperand(esp, 4));
1351f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ and_(eax, Immediate(0x80000000));
1352f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ lea(esp, Operand(esp, kDoubleSize));
1353f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ pop(eax);
1354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(zero, &done_compare, Label::kNear);
1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&compare_swap);
1357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(ool->exit());
1358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fxch(1);
1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1360f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&done_compare);
1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, 2 * kDoubleSize));
1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1365f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kX87Float32Min: {
1366f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Label compare_swap, done_compare;
1367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ VerifyX87StackDepth(1);
1369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
1370f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fstp(0);
1371f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fld_s(MemOperand(esp, kFloatSize));
1372f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fld_s(MemOperand(esp, 0));
1373f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fld(1);
1374f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fld(1);
1375f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ FCmp();
1376f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1377f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      auto ool =
1378f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          new (zone()) OutOfLineLoadFloat32NaN(this, i.OutputDoubleRegister());
1379f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(parity_even, ool->entry());
1380f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(above, &done_compare, Label::kNear);
1381f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(below, &compare_swap, Label::kNear);
1382f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ push(eax);
1383f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ lea(esp, Operand(esp, -kFloatSize));
1384f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fld(0);
1385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fstp_s(Operand(esp, 0));
1386f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ mov(eax, MemOperand(esp, 0));
1387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ and_(eax, Immediate(0x80000000));
1388f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ lea(esp, Operand(esp, kFloatSize));
1389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ pop(eax);
1390f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(zero, &done_compare, Label::kNear);
1391f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1392f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&compare_swap);
1393f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(ool->exit());
1394f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fxch(1);
1395f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1396f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&done_compare);
1397f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fstp(0);
1398f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ lea(esp, Operand(esp, 2 * kFloatSize));
1399f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1400f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64Min: {
1402f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Label compare_swap, done_compare;
1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, kDoubleSize));
1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, 0));
1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld(1);
1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld(1);
1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ FCmp();
1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1413f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      auto ool =
1414f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          new (zone()) OutOfLineLoadFloat64NaN(this, i.OutputDoubleRegister());
1415f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(parity_even, ool->entry());
1416f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(above, &done_compare, Label::kNear);
1417f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(below, &compare_swap, Label::kNear);
1418f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ push(eax);
1419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ lea(esp, Operand(esp, -kDoubleSize));
1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld(0);
1421f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fstp_d(Operand(esp, 0));
1422f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ mov(eax, MemOperand(esp, 4));
1423f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ and_(eax, Immediate(0x80000000));
1424f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ lea(esp, Operand(esp, kDoubleSize));
1425f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ pop(eax);
1426f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(zero, &done_compare, Label::kNear);
1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1428f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&compare_swap);
1429f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(ool->exit());
1430f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fxch(1);
1431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1432f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&done_compare);
1433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, 2 * kDoubleSize));
1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64Abs: {
1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, 0));
1443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fabs();
1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, kDoubleSize));
1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1447f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kX87Float64Neg: {
1448f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1449f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ VerifyX87StackDepth(1);
1450f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
1451f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fstp(0);
1452f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fld_d(MemOperand(esp, 0));
1453f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fchs();
1454f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ lea(esp, Operand(esp, kDoubleSize));
1455f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1456f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1457109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kX87Int32ToFloat32: {
1458109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      InstructionOperand* input = instr->InputAt(0);
1459109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      DCHECK(input->IsRegister() || input->IsStackSlot());
1460109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1461109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ VerifyX87StackDepth(1);
1462109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
1463109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ fstp(0);
1464109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (input->IsRegister()) {
1465109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        Register input_reg = i.InputRegister(0);
1466109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ push(input_reg);
1467109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ fild_s(Operand(esp, 0));
1468109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ pop(input_reg);
1469109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
1470109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ fild_s(i.InputOperand(0));
1471109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
1472109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
1473109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
1474109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kX87Uint32ToFloat32: {
1475109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      InstructionOperand* input = instr->InputAt(0);
1476109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      DCHECK(input->IsRegister() || input->IsStackSlot());
1477109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1478109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ VerifyX87StackDepth(1);
1479109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
1480109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ fstp(0);
1481109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Label msb_set_src;
1482109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Label jmp_return;
1483109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Put input integer into eax(tmporarilly)
1484109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ push(eax);
1485109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (input->IsRegister())
1486109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ mov(eax, i.InputRegister(0));
1487109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      else
1488109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ mov(eax, i.InputOperand(0));
1489109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1490109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ test(eax, eax);
1491109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ j(sign, &msb_set_src, Label::kNear);
1492109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ push(eax);
1493109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ fild_s(Operand(esp, 0));
1494109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ pop(eax);
1495109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1496109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ jmp(&jmp_return, Label::kNear);
1497109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ bind(&msb_set_src);
1498109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Need another temp reg
1499109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ push(ebx);
1500109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ mov(ebx, eax);
1501109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ shr(eax, 1);
1502109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Recover the least significant bit to avoid rounding errors.
1503109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ and_(ebx, Immediate(1));
1504109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ or_(eax, ebx);
1505109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ push(eax);
1506109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ fild_s(Operand(esp, 0));
1507109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ pop(eax);
1508109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ fld(0);
1509109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ faddp();
1510109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Restore the ebx
1511109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ pop(ebx);
1512109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ bind(&jmp_return);
1513109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Restore the eax
1514109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ pop(eax);
1515109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
1516109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Int32ToFloat64: {
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* input = instr->InputAt(0);
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(input->IsRegister() || input->IsStackSlot());
1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (input->IsRegister()) {
1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register input_reg = i.InputRegister(0);
1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ push(input_reg);
1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fild_s(Operand(esp, 0));
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ pop(input_reg);
1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fild_s(i.InputOperand(0));
1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float32ToFloat64: {
1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* input = instr->InputAt(0);
1536bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (input->IsFPRegister()) {
1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sub(esp, Immediate(kDoubleSize));
15383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ fstp_s(MemOperand(esp, 0));
15393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ fld_s(MemOperand(esp, 0));
1540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ add(esp, Immediate(kDoubleSize));
1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1542bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(input->IsFPStackSlot());
1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ VerifyX87StackDepth(1);
1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp(0);
1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_s(i.InputOperand(0));
1548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Uint32ToFloat64: {
1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ LoadUint32NoSSE2(i.InputRegister(0));
1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kX87Float32ToInt32: {
1560bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!instr->InputAt(0)->IsFPRegister()) {
1561109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ fld_s(i.InputOperand(0));
1562109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
1563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ TruncateX87TOSToI(i.OutputRegister(0));
1564bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!instr->InputAt(0)->IsFPRegister()) {
1565109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ fstp(0);
1566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
1567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
1568109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
1569109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kX87Float32ToUint32: {
1570bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!instr->InputAt(0)->IsFPRegister()) {
1571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ fld_s(i.InputOperand(0));
1572109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
1573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Label success;
1574109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ TruncateX87TOSToI(i.OutputRegister(0));
1575109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ test(i.OutputRegister(0), i.OutputRegister(0));
1576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ j(positive, &success);
1577f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Need to reserve the input float32 data.
1578f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fld(0);
1579109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ push(Immediate(INT32_MIN));
1580109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ fild_s(Operand(esp, 0));
1581109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ lea(esp, Operand(esp, kPointerSize));
1582109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ faddp();
1583109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ TruncateX87TOSToI(i.OutputRegister(0));
1584109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ or_(i.OutputRegister(0), Immediate(0x80000000));
1585f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Only keep input float32 data in x87 stack when return.
1586f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ fstp(0);
1587109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ bind(&success);
1588bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!instr->InputAt(0)->IsFPRegister()) {
1589109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ fstp(0);
1590109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
1591109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
1592109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64ToInt32: {
1594bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!instr->InputAt(0)->IsFPRegister()) {
1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(i.InputOperand(0));
1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ TruncateX87TOSToI(i.OutputRegister(0));
1598bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!instr->InputAt(0)->IsFPRegister()) {
1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp(0);
1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64ToFloat32: {
1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* input = instr->InputAt(0);
1605bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (input->IsFPRegister()) {
1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sub(esp, Immediate(kDoubleSize));
1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp_s(MemOperand(esp, 0));
1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_s(MemOperand(esp, 0));
1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ add(esp, Immediate(kDoubleSize));
1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1611bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(input->IsFPStackSlot());
1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ VerifyX87StackDepth(1);
1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp(0);
1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(i.InputOperand(0));
1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sub(esp, Immediate(kDoubleSize));
1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp_s(MemOperand(esp, 0));
1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_s(MemOperand(esp, 0));
1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ add(esp, Immediate(kDoubleSize));
1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64ToUint32: {
1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ push_imm32(-2147483648);
1626bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!instr->InputAt(0)->IsFPRegister()) {
1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(i.InputOperand(0));
1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fild_s(Operand(esp, 0));
16303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ fld(1);
16313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ faddp();
1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ TruncateX87TOSToI(i.OutputRegister(0));
1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ add(esp, Immediate(kInt32Size));
1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ add(i.OutputRegister(), Immediate(0x80000000));
16353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ fstp(0);
1636bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!instr->InputAt(0)->IsFPRegister()) {
1637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp(0);
1638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64ExtractHighWord32: {
1642bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sub(esp, Immediate(kDoubleSize));
1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fst_d(MemOperand(esp, 0));
1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(i.OutputRegister(), MemOperand(esp, kDoubleSize / 2));
1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ add(esp, Immediate(kDoubleSize));
1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand* input = instr->InputAt(0);
1649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        USE(input);
1650bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(input->IsFPStackSlot());
1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(i.OutputRegister(), i.InputOperand(0, kDoubleSize / 2));
1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64ExtractLowWord32: {
1656bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sub(esp, Immediate(kDoubleSize));
1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fst_d(MemOperand(esp, 0));
1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(i.OutputRegister(), MemOperand(esp, 0));
1660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ add(esp, Immediate(kDoubleSize));
1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand* input = instr->InputAt(0);
1663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        USE(input);
1664bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(input->IsFPStackSlot());
1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(i.OutputRegister(), i.InputOperand(0));
1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64InsertHighWord32: {
1670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ sub(esp, Immediate(kDoubleSize));
1671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp_d(MemOperand(esp, 0));
1672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mov(MemOperand(esp, kDoubleSize / 2), i.InputRegister(1));
1673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, 0));
1674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ add(esp, Immediate(kDoubleSize));
1675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64InsertLowWord32: {
1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ sub(esp, Immediate(kDoubleSize));
1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp_d(MemOperand(esp, 0));
1680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mov(MemOperand(esp, 0), i.InputRegister(1));
1681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, 0));
1682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ add(esp, Immediate(kDoubleSize));
1683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64Sqrt: {
1686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x027F);
1690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, 0));
1692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fsqrt();
1693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, kDoubleSize));
1694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetFPUCW(0x037F);
1695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64Round: {
1698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RoundingMode mode =
1699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
1700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Set the correct round mode in x87 control register
1701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetRC((mode << 10));
1702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1703bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!instr->InputAt(0)->IsFPRegister()) {
1704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand* input = instr->InputAt(0);
1705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        USE(input);
1706bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(input->IsFPStackSlot());
1707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ VerifyX87StackDepth(1);
1709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp(0);
1711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(i.InputOperand(0));
1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ frndint();
1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ X87SetRC(0x0000);
1715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Float64Cmp: {
1718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, kDoubleSize));
1719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fld_d(MemOperand(esp, 0));
1720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ FCmp();
1721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, 2 * kDoubleSize));
1722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
172413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kX87Float64SilenceNaN: {
172513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Label end, return_qnan;
172613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ fstp(0);
172713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ push(ebx);
172813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // Load Half word of HoleNan(SNaN) into ebx
172913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ mov(ebx, MemOperand(esp, 2 * kInt32Size));
173013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ cmp(ebx, Immediate(kHoleNanUpper32));
173113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // Check input is HoleNaN(SNaN)?
173213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ j(equal, &return_qnan, Label::kNear);
173313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // If input isn't HoleNaN(SNaN), just load it and return
173413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ fld_d(MemOperand(esp, 1 * kInt32Size));
173513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ jmp(&end);
173613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ bind(&return_qnan);
173713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // If input is HoleNaN(SNaN), Return QNaN
173813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ push(Immediate(0xffffffff));
173913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ push(Immediate(0xfff7ffff));
174013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ fld_d(MemOperand(esp, 0));
174113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ lea(esp, Operand(esp, kDoubleSize));
174213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ bind(&end);
174313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ pop(ebx);
174413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // Clear stack.
174513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ lea(esp, Operand(esp, 1 * kDoubleSize));
174613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
174713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
1748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Movsxbl:
1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ movsx_b(i.OutputRegister(), i.MemoryOperand());
1750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Movzxbl:
1752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ movzx_b(i.OutputRegister(), i.MemoryOperand());
1753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Movb: {
1755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_t index = 0;
1756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Operand operand = i.MemoryOperand(&index);
1757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, index)) {
1758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov_b(operand, i.InputInt8(index));
1759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov_b(operand, i.InputRegister(index));
1761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Movsxwl:
1765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ movsx_w(i.OutputRegister(), i.MemoryOperand());
1766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Movzxwl:
1768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ movzx_w(i.OutputRegister(), i.MemoryOperand());
1769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Movw: {
1771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_t index = 0;
1772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Operand operand = i.MemoryOperand(&index);
1773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, index)) {
1774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov_w(operand, i.InputInt16(index));
1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov_w(operand, i.InputRegister(index));
1777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Movl:
1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->HasOutput()) {
1782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(i.OutputRegister(), i.MemoryOperand());
1783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        size_t index = 0;
1785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Operand operand = i.MemoryOperand(&index);
1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (HasImmediateInput(instr, index)) {
1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ mov(operand, i.InputImmediate(index));
1788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
1789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ mov(operand, i.InputRegister(index));
1790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Movsd: {
1794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->HasOutput()) {
1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        X87Register output = i.OutputDoubleRegister();
1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        USE(output);
1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(output.code() == 0);
1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ VerifyX87StackDepth(1);
1800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp(0);
1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(i.MemoryOperand());
1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        size_t index = 0;
1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Operand operand = i.MemoryOperand(&index);
1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fst_d(operand);
1807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Movss: {
1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->HasOutput()) {
1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        X87Register output = i.OutputDoubleRegister();
1813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        USE(output);
1814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(output.code() == 0);
1815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ VerifyX87StackDepth(1);
1817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp(0);
1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_s(i.MemoryOperand());
1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        size_t index = 0;
1822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Operand operand = i.MemoryOperand(&index);
1823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fst_s(operand);
1824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87BitcastFI: {
1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mov(i.OutputRegister(), MemOperand(esp, 0));
1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, kFloatSize));
1830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87BitcastIF: {
1833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
1834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ VerifyX87StackDepth(1);
1835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
1837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
1838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ lea(esp, Operand(esp, -kFloatSize));
1839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(MemOperand(esp, 0), i.InputRegister(0));
1840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_s(MemOperand(esp, 0));
1841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ lea(esp, Operand(esp, kFloatSize));
1842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_s(i.InputOperand(0));
1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Lea: {
1848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AddressingMode mode = AddressingModeField::decode(instr->opcode());
1849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Shorten "leal" to "addl", "subl" or "shll" if the register allocation
1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // and addressing mode just happens to work out. The "addl"/"subl" forms
1851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // in these cases are faster based on measurements.
1852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (mode == kMode_MI) {
1853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Move(i.OutputRegister(), Immediate(i.InputInt32(0)));
1854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if (i.InputRegister(0).is(i.OutputRegister())) {
1855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (mode == kMode_MRI) {
1856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          int32_t constant_summand = i.InputInt32(1);
1857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (constant_summand > 0) {
1858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            __ add(i.OutputRegister(), Immediate(constant_summand));
1859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          } else if (constant_summand < 0) {
1860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            __ sub(i.OutputRegister(), Immediate(-constant_summand));
1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else if (mode == kMode_MR1) {
1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (i.InputRegister(1).is(i.OutputRegister())) {
1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            __ shl(i.OutputRegister(), 1);
1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          } else {
1866c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            __ add(i.OutputRegister(), i.InputRegister(1));
1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
1868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else if (mode == kMode_M2) {
1869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ shl(i.OutputRegister(), 1);
1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else if (mode == kMode_M4) {
1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ shl(i.OutputRegister(), 2);
1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else if (mode == kMode_M8) {
1873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ shl(i.OutputRegister(), 3);
1874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
1875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ lea(i.OutputRegister(), i.MemoryOperand());
1876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1877c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      } else if (mode == kMode_MR1 &&
1878c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                 i.InputRegister(1).is(i.OutputRegister())) {
1879c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ add(i.OutputRegister(), i.InputRegister(0));
1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ lea(i.OutputRegister(), i.MemoryOperand());
1882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Push:
1886bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        auto allocated = AllocatedOperand::cast(*instr->InputAt(0));
1888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (allocated.representation() == MachineRepresentation::kFloat32) {
188913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          __ sub(esp, Immediate(kFloatSize));
1890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ fst_s(Operand(esp, 0));
189113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize);
1892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DCHECK(allocated.representation() == MachineRepresentation::kFloat64);
1894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ sub(esp, Immediate(kDoubleSize));
1895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ fst_d(Operand(esp, 0));
1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
189713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        }
1898bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      } else if (instr->InputAt(0)->IsFPStackSlot()) {
1899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        auto allocated = AllocatedOperand::cast(*instr->InputAt(0));
1900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (allocated.representation() == MachineRepresentation::kFloat32) {
190113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          __ sub(esp, Immediate(kFloatSize));
1902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ fld_s(i.InputOperand(0));
1903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ fstp_s(MemOperand(esp, 0));
190413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize);
1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
1906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DCHECK(allocated.representation() == MachineRepresentation::kFloat64);
1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ sub(esp, Immediate(kDoubleSize));
1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ fld_d(i.InputOperand(0));
1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ fstp_d(MemOperand(esp, 0));
1910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
191113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        }
1912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if (HasImmediateInput(instr, 0)) {
1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ push(i.InputImmediate(0));
1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame_access_state()->IncreaseSPDelta(1);
1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ push(i.InputOperand(0));
1917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame_access_state()->IncreaseSPDelta(1);
1918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87Poke: {
1921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int const slot = MiscField::decode(instr->opcode());
1922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 0)) {
1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(Operand(esp, slot * kPointerSize), i.InputImmediate(0));
1924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(Operand(esp, slot * kPointerSize), i.InputRegister(0));
1926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1929bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kX87Xchgb: {
1930bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      size_t index = 0;
1931bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Operand operand = i.MemoryOperand(&index);
1932bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ xchg_b(i.InputRegister(index), operand);
1933bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1934bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
1935bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kX87Xchgw: {
1936bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      size_t index = 0;
1937bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Operand operand = i.MemoryOperand(&index);
1938bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ xchg_w(i.InputRegister(index), operand);
1939bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1940bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
1941bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kX87Xchgl: {
1942bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      size_t index = 0;
1943bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Operand operand = i.MemoryOperand(&index);
1944bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ xchg(i.InputRegister(index), operand);
1945bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1946bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
1947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87PushFloat32:
1948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, -kFloatSize));
1949bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPStackSlot()) {
1950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_s(i.InputOperand(0));
1951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp_s(MemOperand(esp, 0));
1952bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      } else if (instr->InputAt(0)->IsFPRegister()) {
1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fst_s(MemOperand(esp, 0));
1954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNREACHABLE();
1956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87PushFloat64:
1959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ lea(esp, Operand(esp, -kDoubleSize));
1960bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPStackSlot()) {
1961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(i.InputOperand(0));
1962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp_d(MemOperand(esp, 0));
1963bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      } else if (instr->InputAt(0)->IsFPRegister()) {
1964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fst_d(MemOperand(esp, 0));
1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNREACHABLE();
1967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedLoadInt8:
1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_b);
1971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedLoadUint8:
1973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_LOAD_INTEGER(movzx_b);
1974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedLoadInt16:
1976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_w);
1977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedLoadUint16:
1979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_LOAD_INTEGER(movzx_w);
1980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedLoadWord32:
1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_LOAD_INTEGER(mov);
1983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedLoadFloat32:
1985f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_CHECKED_LOAD_FLOAT(fld_s, OutOfLineLoadFloat32NaN);
1986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedLoadFloat64:
1988f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_CHECKED_LOAD_FLOAT(fld_d, OutOfLineLoadFloat64NaN);
1989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedStoreWord8:
1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_STORE_INTEGER(mov_b);
1992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedStoreWord16:
1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_STORE_INTEGER(mov_w);
1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedStoreWord32:
1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_STORE_INTEGER(mov);
1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedStoreFloat32:
2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_STORE_FLOAT(fst_s);
2001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedStoreFloat64:
2003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_STORE_FLOAT(fst_d);
2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX87StackCheck: {
2006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ExternalReference const stack_limit =
2007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          ExternalReference::address_of_stack_limit(isolate());
2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ cmp(esp, Operand::StaticVariable(stack_limit));
2009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedLoadWord64:
2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedStoreWord64:
2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();  // currently unsupported checked int64 load/store.
2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2015bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadInt8:
2016bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadUint8:
2017bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadInt16:
2018bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadUint16:
2019bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadWord32:
2020bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicStoreWord8:
2021bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicStoreWord16:
2022bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicStoreWord32:
2023bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      UNREACHABLE();  // Won't be generated by instruction selector.
2024bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2026bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return kSuccess;
2027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // NOLINT(readability/fn_size)
2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
202962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstatic Condition FlagsConditionToCondition(FlagsCondition condition) {
203062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  switch (condition) {
2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnorderedEqual:
2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kEqual:
203362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return equal;
2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnorderedNotEqual:
2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kNotEqual:
203762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return not_equal;
2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSignedLessThan:
204062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return less;
2041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSignedGreaterThanOrEqual:
204362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return greater_equal;
2044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSignedLessThanOrEqual:
204662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return less_equal;
2047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSignedGreaterThan:
204962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return greater;
2050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedLessThan:
205262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return below;
2053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedGreaterThanOrEqual:
205562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return above_equal;
2056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedLessThanOrEqual:
205862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return below_equal;
2059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedGreaterThan:
206162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return above;
2062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kOverflow:
206462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return overflow;
2065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kNotOverflow:
206762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return no_overflow;
2068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
2070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
207162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return no_condition;
2072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
207462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
207562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
207662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Assembles a branch after an instruction.
207762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
207862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label::Distance flabel_distance =
207962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      branch->fallthru ? Label::kNear : Label::kFar;
208062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
208162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label done;
208262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label tlabel_tmp;
208362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label flabel_tmp;
208462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label* tlabel = &tlabel_tmp;
208562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label* flabel = &flabel_tmp;
208662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
208762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label* tlabel_dst = branch->true_label;
208862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label* flabel_dst = branch->false_label;
208962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
209062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (branch->condition == kUnorderedEqual) {
209162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ j(parity_even, flabel, flabel_distance);
209262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (branch->condition == kUnorderedNotEqual) {
209362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ j(parity_even, tlabel);
209462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
209562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  __ j(FlagsConditionToCondition(branch->condition), tlabel);
209662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Add a jump if not falling through to the next block.
2098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!branch->fallthru) __ jmp(flabel);
20993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
21003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ jmp(&done);
21013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ bind(&tlabel_tmp);
21023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsMode mode = FlagsModeField::decode(instr->opcode());
21033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (mode == kFlags_deoptimize) {
21043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    int double_register_param_count = 0;
21053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    int x87_layout = 0;
21063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    for (size_t i = 0; i < instr->InputCount(); i++) {
2107bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(i)->IsFPRegister()) {
21083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        double_register_param_count++;
21093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
21103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
21113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Currently we use only one X87 register. If double_register_param_count
21123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // is bigger than 1, it means duplicated double register is added to input
21133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // of this instruction.
21143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (double_register_param_count > 0) {
21153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      x87_layout = (0 << 3) | 1;
21163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
21173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // The layout of x87 register stack is loaded on the top of FPU register
21183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // stack for deoptimization.
21193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    __ push(Immediate(x87_layout));
21203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    __ fild_s(MemOperand(esp, 0));
21213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    __ lea(esp, Operand(esp, kPointerSize));
21223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
21233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ jmp(tlabel_dst);
21243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ bind(&flabel_tmp);
21253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ jmp(flabel_dst);
21263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ bind(&done);
2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchJump(RpoNumber target) {
2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target));
2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
213462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid CodeGenerator::AssembleArchTrap(Instruction* instr,
213562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                     FlagsCondition condition) {
213662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  class OutOfLineTrap final : public OutOfLineCode {
213762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch   public:
213862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    OutOfLineTrap(CodeGenerator* gen, bool frame_elided, Instruction* instr)
213962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        : OutOfLineCode(gen),
214062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          frame_elided_(frame_elided),
214162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          instr_(instr),
214262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          gen_(gen) {}
214362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
214462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    void Generate() final {
214562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      X87OperandConverter i(gen_, instr_);
214662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
214762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Runtime::FunctionId trap_id = static_cast<Runtime::FunctionId>(
214862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          i.InputInt32(instr_->InputCount() - 1));
214962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      bool old_has_frame = __ has_frame();
215062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (frame_elided_) {
215162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ set_has_frame(true);
215262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ EnterFrame(StackFrame::WASM_COMPILED);
215362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
215462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      GenerateCallToTrap(trap_id);
215562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (frame_elided_) {
215662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        ReferenceMap* reference_map =
215762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            new (gen_->zone()) ReferenceMap(gen_->zone());
215862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0,
215962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              Safepoint::kNoLazyDeopt);
216062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ set_has_frame(old_has_frame);
216162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
216262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (FLAG_debug_code) {
216362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ ud2();
216462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
216562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
216662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
216762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch   private:
216862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    void GenerateCallToTrap(Runtime::FunctionId trap_id) {
216962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (trap_id == Runtime::kNumFunctions) {
217062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        // We cannot test calls to the runtime in cctest/test-run-wasm.
217162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        // Therefore we emit a call to C here instead of a call to the runtime.
217262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ PrepareCallCFunction(0, esi);
217362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ CallCFunction(
217462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            ExternalReference::wasm_call_trap_callback_for_testing(isolate()),
217562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            0);
217662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else {
217762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ Move(esi, isolate()->native_context());
217862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        gen_->AssembleSourcePosition(instr_);
217962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ CallRuntime(trap_id);
218062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
218162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
218262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
218362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool frame_elided_;
218462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Instruction* instr_;
218562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CodeGenerator* gen_;
218662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  };
218762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool frame_elided = !frame_access_state()->has_frame();
218862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  auto ool = new (zone()) OutOfLineTrap(this, frame_elided, instr);
218962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label* tlabel = ool->entry();
219062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label end;
219162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (condition == kUnorderedEqual) {
219262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ j(parity_even, &end);
219362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (condition == kUnorderedNotEqual) {
219462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ j(parity_even, tlabel);
219562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
219662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  __ j(FlagsConditionToCondition(condition), tlabel);
219762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  __ bind(&end);
219862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
2199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Assembles boolean materializations after an instruction.
2201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchBoolean(Instruction* instr,
2202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        FlagsCondition condition) {
2203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X87OperandConverter i(this, instr);
2204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label done;
2205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Materialize a full 32-bit 1 or 0 value. The result register is always the
2207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // last output of the instruction.
2208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label check;
2209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NE(0u, instr->OutputCount());
2210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register reg = i.OutputRegister(instr->OutputCount() - 1);
221162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (condition == kUnorderedEqual) {
221262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ j(parity_odd, &check, Label::kNear);
221362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ Move(reg, Immediate(0));
221462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ jmp(&done, Label::kNear);
221562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (condition == kUnorderedNotEqual) {
221662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ j(parity_odd, &check, Label::kNear);
221762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ mov(reg, Immediate(1));
221862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ jmp(&done, Label::kNear);
2219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
222062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Condition cc = FlagsConditionToCondition(condition);
222162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ bind(&check);
2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (reg.is_byte_register()) {
2224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // setcc for byte registers (al, bl, cl, dl).
2225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ setcc(cc, reg);
2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ movzx_b(reg, reg);
2227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Emit a branch to set a register to either 1 or 0.
2229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Label set;
2230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ j(cc, &set, Label::kNear);
2231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Move(reg, Immediate(0));
2232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ jmp(&done, Label::kNear);
2233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bind(&set);
2234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ mov(reg, Immediate(1));
2235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ bind(&done);
2237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
2241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X87OperandConverter i(this, instr);
2242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register input = i.InputRegister(0);
2243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t index = 2; index < instr->InputCount(); index += 2) {
2244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ cmp(input, Immediate(i.InputInt32(index + 0)));
2245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ j(equal, GetLabel(i.InputRpo(index + 1)));
2246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AssembleArchJump(i.InputRpo(1));
2248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
2252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X87OperandConverter i(this, instr);
2253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register input = i.InputRegister(0);
2254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t const case_count = instr->InputCount() - 2;
2255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label** cases = zone()->NewArray<Label*>(case_count);
2256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t index = 0; index < case_count; ++index) {
2257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cases[index] = GetLabel(i.InputRpo(index + 2));
2258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label* const table = AddJumpTable(cases, case_count);
2260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ cmp(input, Immediate(case_count));
2261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ j(above_equal, GetLabel(i.InputRpo(1)));
2262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ jmp(Operand::JumpTable(input, times_4, table));
2263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2265bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
226662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int deoptimization_id, SourcePosition pos) {
226762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeoptimizeKind deoptimization_kind = GetDeoptimizationKind(deoptimization_id);
226862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeoptimizeReason deoptimization_reason =
226962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      GetDeoptimizationReason(deoptimization_id);
227062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Deoptimizer::BailoutType bailout_type =
227162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      deoptimization_kind == DeoptimizeKind::kSoft ? Deoptimizer::SOFT
227262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                   : Deoptimizer::EAGER;
2273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
2274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate(), deoptimization_id, bailout_type);
2275bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts;
2276c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  __ RecordDeoptReason(deoptimization_reason, pos, deoptimization_id);
2277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
2278bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return kSuccess;
2279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// The calling convention for JSFunctions on X87 passes arguments on the
2283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// stack and the JSFunction and context in EDI and ESI, respectively, thus
2284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// the steps of the call look as follows:
2285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ before the call instruction }--------------------------------------------
2287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                                         |  caller frame |
2288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                                         ^ esp           ^ ebp
2289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ push arguments and setup ESI, EDI }--------------------------------------
2291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                       | args + receiver |  caller frame |
2292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                       ^ esp                             ^ ebp
2293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                 [edi = JSFunction, esi = context]
2294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ call [edi + kCodeEntryOffset] }------------------------------------------
2296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                 | RET | args + receiver |  caller frame |
2297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                 ^ esp                                   ^ ebp
2298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =={ prologue of called function }============================================
2300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ push ebp }---------------------------------------------------------------
2301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                            | FP | RET | args + receiver |  caller frame |
2302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                            ^ esp                                        ^ ebp
2303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ mov ebp, esp }-----------------------------------------------------------
2305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                            | FP | RET | args + receiver |  caller frame |
2306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                            ^ ebp,esp
2307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ push esi }---------------------------------------------------------------
2309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                      | CTX | FP | RET | args + receiver |  caller frame |
2310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                      ^esp  ^ ebp
2311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ push edi }---------------------------------------------------------------
2313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                | FNC | CTX | FP | RET | args + receiver |  caller frame |
2314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                ^esp        ^ ebp
2315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ subi esp, #N }-----------------------------------------------------------
2317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | callee frame | FNC | CTX | FP | RET | args + receiver |  caller frame |
2318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^esp                       ^ ebp
2319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =={ body of called function }================================================
2321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =={ epilogue of called function }============================================
2323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ mov esp, ebp }-----------------------------------------------------------
2324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                            | FP | RET | args + receiver |  caller frame |
2325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                            ^ esp,ebp
2326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ pop ebp }-----------------------------------------------------------
2328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// |                               | RET | args + receiver |  caller frame |
2329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                 ^ esp                                   ^ ebp
2330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ ret #A+1 }-----------------------------------------------------------
2332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// |                                                       |  caller frame |
2333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                                         ^ esp           ^ ebp
2334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Runtime function calls are accomplished by doing a stub call to the
2337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// CEntryStub (a real code object). On X87 passes arguments on the
2338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// stack, the number of arguments in EAX, the address of the runtime function
2339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// in EBX, and the context in ESI.
2340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ before the call instruction }--------------------------------------------
2342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                                         |  caller frame |
2343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                                         ^ esp           ^ ebp
2344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ push arguments and setup EAX, EBX, and ESI }-----------------------------
2346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                       | args + receiver |  caller frame |
2347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                       ^ esp                             ^ ebp
2348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//              [eax = #args, ebx = runtime function, esi = context]
2349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ call #CEntryStub }-------------------------------------------------------
2351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                 | RET | args + receiver |  caller frame |
2352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                 ^ esp                                   ^ ebp
2353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =={ body of runtime function }===============================================
2355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ runtime returns }--------------------------------------------------------
2357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                                         |  caller frame |
2358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                                         ^ esp           ^ ebp
2359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Other custom linkages (e.g. for calling directly into and out of C++) may
2361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// need to save callee-saved registers on the stack, which is done in the
2362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// function prologue of generated code.
2363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ before the call instruction }--------------------------------------------
2365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                                         |  caller frame |
2366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                                         ^ esp           ^ ebp
2367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ set up arguments in registers on stack }---------------------------------
2369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                                  | args |  caller frame |
2370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                                  ^ esp                  ^ ebp
2371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                  [r0 = arg0, r1 = arg1, ...]
2372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ call code }--------------------------------------------------------------
2374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                            | RET | args |  caller frame |
2375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                            ^ esp                        ^ ebp
2376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =={ prologue of called function }============================================
2378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ push ebp }---------------------------------------------------------------
2379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                       | FP | RET | args |  caller frame |
2380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                       ^ esp                             ^ ebp
2381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ mov ebp, esp }-----------------------------------------------------------
2383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                       | FP | RET | args |  caller frame |
2384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                       ^ ebp,esp
2385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ save registers }---------------------------------------------------------
2387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                | regs | FP | RET | args |  caller frame |
2388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                ^ esp  ^ ebp
2389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ subi esp, #N }-----------------------------------------------------------
2391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                 | callee frame | regs | FP | RET | args |  caller frame |
2392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                 ^esp                  ^ ebp
2393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =={ body of called function }================================================
2395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =={ epilogue of called function }============================================
2397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ restore registers }------------------------------------------------------
2398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                | regs | FP | RET | args |  caller frame |
2399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                ^ esp  ^ ebp
2400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ mov esp, ebp }-----------------------------------------------------------
2402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                       | FP | RET | args |  caller frame |
2403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                       ^ esp,ebp
2404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ pop ebp }----------------------------------------------------------------
2406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                            | RET | args |  caller frame |
2407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//                                            ^ esp                        ^ ebp
2408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2409bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeGenerator::FinishFrame(Frame* frame) {
2410bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
2411bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  const RegList saves = descriptor->CalleeSavedRegisters();
2412bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (saves != 0) {  // Save callee-saved registers.
2413bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(!info()->is_osr());
2414bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    int pushed = 0;
2415bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
2416bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (!((1 << i) & saves)) continue;
2417bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      ++pushed;
2418bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
2419bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    frame->AllocateSavedCalleeRegisterSlots(pushed);
2420bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
2421bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2422bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Initailize FPU state.
2423bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  __ fninit();
2424bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  __ fld1();
2425bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
2426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2427bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeGenerator::AssembleConstructFrame() {
2428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
24293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (frame_access_state()->has_frame()) {
24303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (descriptor->IsCFunctionCall()) {
24313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ push(ebp);
24323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ mov(ebp, esp);
24333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    } else if (descriptor->IsJSFunctionCall()) {
24343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ Prologue(this->info()->GeneratePreagedPrologue());
2435c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (descriptor->PushArgumentCount()) {
2436c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ push(kJavaScriptCallArgCountRegister);
2437c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
24383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    } else {
24393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ StubPrologue(info()->GetOutputStackFrameType());
24403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
2441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2442bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2443c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int shrink_slots =
2444c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      frame()->GetTotalFrameSlotCount() - descriptor->CalculateFixedFrameSize();
2445bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (info()->is_osr()) {
2447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // TurboFan OSR-compiled functions cannot be entered directly.
2448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Abort(kShouldNotDirectlyEnterOsrFunction);
2449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Unoptimized code jumps directly to this entrypoint while the unoptimized
2451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // frame is still on the stack. Optimized code uses OSR values directly from
2452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // the unoptimized frame. Thus, all that needs to be done is to allocate the
2453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // remaining stack slots.
2454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
2455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    osr_pc_offset_ = __ pc_offset();
2456bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
24573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
24583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Initailize FPU state.
24593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    __ fninit();
24603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    __ fld1();
2461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RegList saves = descriptor->CalleeSavedRegisters();
2464bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (shrink_slots > 0) {
2465bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    __ sub(esp, Immediate(shrink_slots * kPointerSize));
2466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (saves != 0) {  // Save callee-saved registers.
2469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!info()->is_osr());
2470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int pushed = 0;
2471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
2472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!((1 << i) & saves)) continue;
2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ push(Register::from_code(i));
2474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ++pushed;
2475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2479c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid CodeGenerator::AssembleReturn(InstructionOperand* pop) {
2480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
2481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Clear the FPU stack only if there is no return value in the stack.
2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_debug_code && FLAG_enable_slow_asserts) {
2484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ VerifyX87StackDepth(1);
2485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool clear_stack = true;
2487c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  for (size_t i = 0; i < descriptor->ReturnCount(); i++) {
2488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MachineRepresentation rep = descriptor->GetReturnType(i).representation();
2489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LinkageLocation loc = descriptor->GetReturnLocation(i);
2490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (IsFloatingPoint(rep) && loc == LinkageLocation::ForRegister(0)) {
2491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      clear_stack = false;
2492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (clear_stack) __ fstp(0);
2496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RegList saves = descriptor->CalleeSavedRegisters();
2498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Restore registers.
2499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (saves != 0) {
2500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < Register::kNumRegisters; i++) {
2501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!((1 << i) & saves)) continue;
2502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ pop(Register::from_code(i));
2503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2506c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Might need ecx for scratch if pop_size is too big or if there is a variable
2507c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // pop count.
2508c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & ecx.bit());
2509c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  size_t pop_size = descriptor->StackParameterCount() * kPointerSize;
2510c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  X87OperandConverter g(this, nullptr);
2511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (descriptor->IsCFunctionCall()) {
25123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    AssembleDeconstructFrame();
25133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (frame_access_state()->has_frame()) {
2514c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // Canonicalize JSFunction return sites for now if they always have the same
2515c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // number of return args.
2516c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (pop->IsImmediate() && g.ToConstant(pop).ToInt32() == 0) {
2517c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (return_label_.is_bound()) {
2518c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ jmp(&return_label_);
2519c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        return;
2520c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      } else {
2521c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ bind(&return_label_);
2522c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        AssembleDeconstructFrame();
2523c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
2524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
25253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      AssembleDeconstructFrame();
2526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2528c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & edx.bit());
2529c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & ecx.bit());
2530c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (pop->IsImmediate()) {
2531c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DCHECK_EQ(Constant::kInt32, g.ToConstant(pop).type());
2532c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    pop_size += g.ToConstant(pop).ToInt32() * kPointerSize;
2533c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    __ Ret(static_cast<int>(pop_size), ecx);
2534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2535c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Register pop_reg = g.ToRegister(pop);
2536c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Register scratch_reg = pop_reg.is(ecx) ? edx : ecx;
2537c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    __ pop(scratch_reg);
2538c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    __ lea(esp, Operand(esp, pop_reg, times_4, static_cast<int>(pop_size)));
2539c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    __ jmp(scratch_reg);
2540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleMove(InstructionOperand* source,
2545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 InstructionOperand* destination) {
2546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X87OperandConverter g(this, nullptr);
2547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Dispatch on the source and destination operand kinds.  Not all
2548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // combinations are possible.
2549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (source->IsRegister()) {
2550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(destination->IsRegister() || destination->IsStackSlot());
2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register src = g.ToRegister(source);
2552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Operand dst = g.ToOperand(destination);
2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ mov(dst, src);
2554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (source->IsStackSlot()) {
2555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(destination->IsRegister() || destination->IsStackSlot());
2556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Operand src = g.ToOperand(source);
2557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (destination->IsRegister()) {
2558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register dst = g.ToRegister(destination);
2559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mov(dst, src);
2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Operand dst = g.ToOperand(destination);
2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ push(src);
2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ pop(dst);
2564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (source->IsConstant()) {
2566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Constant src_constant = g.ToConstant(source);
2567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (src_constant.type() == Constant::kHeapObject) {
2568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<HeapObject> src = src_constant.ToHeapObject();
2569f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (destination->IsRegister()) {
2570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register dst = g.ToRegister(destination);
2571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ LoadHeapObject(dst, src);
2572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(destination->IsStackSlot());
2574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Operand dst = g.ToOperand(destination);
2575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        AllowDeferredHandleDereference embedding_raw_address;
2576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (isolate()->heap()->InNewSpace(*src)) {
2577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ PushHeapObject(src);
2578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ pop(dst);
2579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
2580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ mov(dst, src);
2581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (destination->IsRegister()) {
2584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register dst = g.ToRegister(destination);
2585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Move(dst, g.ToImmediate(source));
2586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (destination->IsStackSlot()) {
2587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Operand dst = g.ToOperand(destination);
2588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Move(dst, g.ToImmediate(source));
2589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (src_constant.type() == Constant::kFloat32) {
2590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(turbofan): Can we do better here?
259162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      uint32_t src = src_constant.ToFloat32AsInt();
2592bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (destination->IsFPRegister()) {
2593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sub(esp, Immediate(kInt32Size));
2594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(MemOperand(esp, 0), Immediate(src));
2595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // always only push one value into the x87 stack.
2596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp(0);
2597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_s(MemOperand(esp, 0));
2598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ add(esp, Immediate(kInt32Size));
2599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2600bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(destination->IsFPStackSlot());
2601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Operand dst = g.ToOperand(destination);
2602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Move(dst, Immediate(src));
2603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
2605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_EQ(Constant::kFloat64, src_constant.type());
260662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      uint64_t src = src_constant.ToFloat64AsInt();
2607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t lower = static_cast<uint32_t>(src);
2608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t upper = static_cast<uint32_t>(src >> 32);
2609bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (destination->IsFPRegister()) {
2610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sub(esp, Immediate(kDoubleSize));
2611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(MemOperand(esp, 0), Immediate(lower));
2612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(MemOperand(esp, kInt32Size), Immediate(upper));
2613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // always only push one value into the x87 stack.
2614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp(0);
2615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(MemOperand(esp, 0));
2616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ add(esp, Immediate(kDoubleSize));
2617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2618bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(destination->IsFPStackSlot());
2619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Operand dst0 = g.ToOperand(destination);
2620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Operand dst1 = g.HighOperand(destination);
2621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Move(dst0, Immediate(lower));
2622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Move(dst1, Immediate(upper));
2623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2625bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (source->IsFPRegister()) {
2626bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(destination->IsFPStackSlot());
2627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Operand dst = g.ToOperand(destination);
2628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto allocated = AllocatedOperand::cast(*source);
2629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (allocated.representation()) {
2630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kFloat32:
2631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fst_s(dst);
2632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
2633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kFloat64:
2634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fst_d(dst);
2635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
2636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      default:
2637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNREACHABLE();
2638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2639bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (source->IsFPStackSlot()) {
2640bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot());
2641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Operand src = g.ToOperand(source);
2642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto allocated = AllocatedOperand::cast(*source);
2643bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (destination->IsFPRegister()) {
2644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // always only push one value into the x87 stack.
2645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ fstp(0);
2646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      switch (allocated.representation()) {
2647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MachineRepresentation::kFloat32:
2648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ fld_s(src);
2649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
2650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MachineRepresentation::kFloat64:
2651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ fld_d(src);
2652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
2653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        default:
2654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          UNREACHABLE();
2655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
2657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Operand dst = g.ToOperand(destination);
2658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      switch (allocated.representation()) {
2659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MachineRepresentation::kFloat32:
2660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ fld_s(src);
2661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ fstp_s(dst);
2662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
2663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MachineRepresentation::kFloat64:
2664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ fld_d(src);
2665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ fstp_d(dst);
2666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
2667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        default:
2668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          UNREACHABLE();
2669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UNREACHABLE();
2673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleSwap(InstructionOperand* source,
2678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 InstructionOperand* destination) {
2679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X87OperandConverter g(this, nullptr);
2680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Dispatch on the source and destination operand kinds.  Not all
2681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // combinations are possible.
2682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (source->IsRegister() && destination->IsRegister()) {
2683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Register-register.
2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register src = g.ToRegister(source);
2685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register dst = g.ToRegister(destination);
2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ xchg(dst, src);
2687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (source->IsRegister() && destination->IsStackSlot()) {
2688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Register-memory.
2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ xchg(g.ToRegister(source), g.ToOperand(destination));
2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (source->IsStackSlot() && destination->IsStackSlot()) {
2691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Memory-memory.
2692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Operand dst1 = g.ToOperand(destination);
2693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ push(dst1);
2694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    frame_access_state()->IncreaseSPDelta(1);
2695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Operand src1 = g.ToOperand(source);
2696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ push(src1);
2697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Operand dst2 = g.ToOperand(destination);
2698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ pop(dst2);
2699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    frame_access_state()->IncreaseSPDelta(-1);
2700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Operand src2 = g.ToOperand(source);
2701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ pop(src2);
2702bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (source->IsFPRegister() && destination->IsFPRegister()) {
2703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UNREACHABLE();
2704bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (source->IsFPRegister() && destination->IsFPStackSlot()) {
2705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto allocated = AllocatedOperand::cast(*source);
2706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (allocated.representation()) {
2707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kFloat32:
2708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_s(g.ToOperand(destination));
2709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fxch();
2710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp_s(g.ToOperand(destination));
2711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
2712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kFloat64:
2713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(g.ToOperand(destination));
2714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fxch();
2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp_d(g.ToOperand(destination));
2716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
2717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      default:
2718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNREACHABLE();
2719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2720bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (source->IsFPStackSlot() && destination->IsFPStackSlot()) {
2721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto allocated = AllocatedOperand::cast(*source);
2722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (allocated.representation()) {
2723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kFloat32:
2724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_s(g.ToOperand(source));
2725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_s(g.ToOperand(destination));
2726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp_s(g.ToOperand(source));
2727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp_s(g.ToOperand(destination));
2728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
2729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kFloat64:
2730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(g.ToOperand(source));
2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fld_d(g.ToOperand(destination));
2732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp_d(g.ToOperand(source));
2733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ fstp_d(g.ToOperand(destination));
2734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
2735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      default:
2736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNREACHABLE();
2737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // No other combinations are possible.
2740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UNREACHABLE();
2741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
2746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t index = 0; index < target_count; ++index) {
2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ dd(targets[index]);
2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::EnsureSpaceForLazyDeopt() {
2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!info()->ShouldEnsureSpaceForLazyDeopt()) {
2754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
2755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int space_needed = Deoptimizer::patch_size();
2758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Ensure that we have enough space after the previous lazy-bailout
2759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // instruction for patching the code here.
2760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int current_pc = masm()->pc_offset();
2761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (current_pc < last_lazy_deopt_pc_ + space_needed) {
2762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Nop(padding_size);
2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef __
2768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace compiler
2770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
2771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
2772