17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2013 the V8 project authors. All rights reserved. 27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file. 47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/code-generator.h" 67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/code-generator-impl.h" 87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/gap-resolver.h" 97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/node-matchers.h" 107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/node-properties-inl.h" 117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/ia32/assembler-ia32.h" 127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/ia32/macro-assembler-ia32.h" 137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/scopes.h" 147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace v8 { 167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace internal { 177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace compiler { 187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define __ masm()-> 207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Adds IA-32 specific methods for decoding operands. 237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass IA32OperandConverter : public InstructionOperandConverter { 247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org IA32OperandConverter(CodeGenerator* gen, Instruction* instr) 267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : InstructionOperandConverter(gen, instr) {} 277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand InputOperand(int index) { return ToOperand(instr_->InputAt(index)); } 297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Immediate InputImmediate(int index) { 317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return ToImmediate(instr_->InputAt(index)); 327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand OutputOperand() { return ToOperand(instr_->Output()); } 357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand TempOperand(int index) { return ToOperand(instr_->TempAt(index)); } 377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand ToOperand(InstructionOperand* op, int extra = 0) { 397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (op->IsRegister()) { 40e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(extra == 0); 417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return Operand(ToRegister(op)); 427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else if (op->IsDoubleRegister()) { 43e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(extra == 0); 447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return Operand(ToDoubleRegister(op)); 457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 46e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); 477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // The linkage computes where all spill slots are located. 487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), extra); 497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return Operand(offset.from_stack_pointer() ? esp : ebp, offset.offset()); 507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand HighOperand(InstructionOperand* op) { 53e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(op->IsDoubleStackSlot()); 547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return ToOperand(op, kPointerSize); 557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Immediate ToImmediate(InstructionOperand* operand) { 587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Constant constant = ToConstant(operand); 597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org switch (constant.type()) { 607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case Constant::kInt32: 617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return Immediate(constant.ToInt32()); 627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case Constant::kFloat64: 637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return Immediate( 647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED)); 657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case Constant::kExternalReference: 667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return Immediate(constant.ToExternalReference()); 677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case Constant::kHeapObject: 687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return Immediate(constant.ToHeapObject()); 697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case Constant::kInt64: 707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UNREACHABLE(); 737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return Immediate(-1); 747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand MemoryOperand(int* first_input) { 777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org const int offset = *first_input; 787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org switch (AddressingModeField::decode(instr_->opcode())) { 797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kMode_MR1I: 807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *first_input += 2; 817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return Operand(InputRegister(offset + 0), InputRegister(offset + 1), 827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org times_1, 837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 0); // TODO(dcarney): K != 0 847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kMode_MRI: 857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *first_input += 2; 867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return Operand::ForRegisterPlusImmediate(InputRegister(offset + 0), 877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InputImmediate(offset + 1)); 887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kMode_MI: 897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *first_input += 1; 907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return Operand(InputImmediate(offset + 0)); 917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org default: 927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UNREACHABLE(); 937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return Operand(no_reg); 947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand MemoryOperand() { 987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int first_input = 0; 997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return MemoryOperand(&first_input); 1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 1027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic bool HasImmediateInput(Instruction* instr, int index) { 1057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return instr->InputAt(index)->IsImmediate(); 1067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Assembles an instruction after register allocation, producing machine code. 1107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid CodeGenerator::AssembleArchInstruction(Instruction* instr) { 1117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org IA32OperandConverter i(this, instr); 1127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org switch (ArchOpcodeField::decode(instr->opcode())) { 1147b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org case kArchCallCodeObject: { 11506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org EnsureSpaceForLazyDeopt(); 1167b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org if (HasImmediateInput(instr, 0)) { 1177b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); 1187b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org __ call(code, RelocInfo::CODE_TARGET); 1197b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org } else { 1207b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org Register reg = i.InputRegister(0); 1217b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org __ call(Operand(reg, Code::kHeaderSize - kHeapObjectTag)); 1227b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org } 1237b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org AddSafepointAndDeopt(instr); 1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 1257b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org } 1267b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org case kArchCallJSFunction: { 12706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org EnsureSpaceForLazyDeopt(); 1287b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org Register func = i.InputRegister(0); 1299aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org if (FLAG_debug_code) { 1309aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org // Check the function's context matches the context argument. 1319aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); 1329aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org __ Assert(equal, kWrongFunctionContext); 1339aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 1347b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org __ call(FieldOperand(func, JSFunction::kCodeEntryOffset)); 1357b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org AddSafepointAndDeopt(instr); 1367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 1377b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org } 1387b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org case kArchJmp: 1397b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org __ jmp(code()->GetLabel(i.InputBlock(0))); 1407b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org break; 1417b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org case kArchNop: 1427b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org // don't emit code for nops. 1437b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org break; 1447b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org case kArchRet: 1457b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org AssembleReturn(); 1467b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org break; 1477dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org case kArchTruncateDoubleToI: 1487dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); 1497dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org break; 1507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32Add: 1517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (HasImmediateInput(instr, 1)) { 1527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ add(i.InputOperand(0), i.InputImmediate(1)); 1537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 1547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ add(i.InputRegister(0), i.InputOperand(1)); 1557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 1577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32And: 1587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (HasImmediateInput(instr, 1)) { 1597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ and_(i.InputOperand(0), i.InputImmediate(1)); 1607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 1617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ and_(i.InputRegister(0), i.InputOperand(1)); 1627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 1647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32Cmp: 1657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (HasImmediateInput(instr, 1)) { 1667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ cmp(i.InputOperand(0), i.InputImmediate(1)); 1677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 1687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ cmp(i.InputRegister(0), i.InputOperand(1)); 1697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 1717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32Test: 1727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (HasImmediateInput(instr, 1)) { 1737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ test(i.InputOperand(0), i.InputImmediate(1)); 1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 1757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ test(i.InputRegister(0), i.InputOperand(1)); 1767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 1787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32Imul: 1797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (HasImmediateInput(instr, 1)) { 1807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ imul(i.OutputRegister(), i.InputOperand(0), i.InputInt32(1)); 1817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 1827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ imul(i.OutputRegister(), i.InputOperand(1)); 1837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 1857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32Idiv: 1867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ cdq(); 1877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ idiv(i.InputOperand(1)); 1887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 1897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32Udiv: 1907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ xor_(edx, edx); 1917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ div(i.InputOperand(1)); 1927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 1937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32Not: 1947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ not_(i.OutputOperand()); 1957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 1967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32Neg: 1977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ neg(i.OutputOperand()); 1987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 1997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32Or: 2007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (HasImmediateInput(instr, 1)) { 2017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ or_(i.InputOperand(0), i.InputImmediate(1)); 2027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 2037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ or_(i.InputRegister(0), i.InputOperand(1)); 2047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 2067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32Xor: 2077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (HasImmediateInput(instr, 1)) { 2087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ xor_(i.InputOperand(0), i.InputImmediate(1)); 2097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 2107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ xor_(i.InputRegister(0), i.InputOperand(1)); 2117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 2137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32Sub: 2147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (HasImmediateInput(instr, 1)) { 2157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ sub(i.InputOperand(0), i.InputImmediate(1)); 2167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 2177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ sub(i.InputRegister(0), i.InputOperand(1)); 2187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 2207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32Shl: 2217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (HasImmediateInput(instr, 1)) { 2227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ shl(i.OutputRegister(), i.InputInt5(1)); 2237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 2247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ shl_cl(i.OutputRegister()); 2257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 2277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32Shr: 2287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (HasImmediateInput(instr, 1)) { 2297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ shr(i.OutputRegister(), i.InputInt5(1)); 2307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 2317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ shr_cl(i.OutputRegister()); 2327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 2347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32Sar: 2357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (HasImmediateInput(instr, 1)) { 2367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ sar(i.OutputRegister(), i.InputInt5(1)); 2377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 2387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ sar_cl(i.OutputRegister()); 2397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 2415e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org case kIA32Ror: 2425e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (HasImmediateInput(instr, 1)) { 2435e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ ror(i.OutputRegister(), i.InputInt5(1)); 2445e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org } else { 2455e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ ror_cl(i.OutputRegister()); 2465e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org } 2475e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org break; 2487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSSEFloat64Cmp: 2497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ ucomisd(i.InputDoubleRegister(0), i.InputOperand(1)); 2507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 2517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSSEFloat64Add: 2527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ addsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 2537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 2547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSSEFloat64Sub: 2557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ subsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 2567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 2577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSSEFloat64Mul: 2587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mulsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 2597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 2607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSSEFloat64Div: 2617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ divsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 2627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 2637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSSEFloat64Mod: { 2647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // TODO(dcarney): alignment is wrong. 2657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ sub(esp, Immediate(kDoubleSize)); 2667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Move values to st(0) and st(1). 2677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movsd(Operand(esp, 0), i.InputDoubleRegister(1)); 2687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ fld_d(Operand(esp, 0)); 2697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movsd(Operand(esp, 0), i.InputDoubleRegister(0)); 2707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ fld_d(Operand(esp, 0)); 2717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Loop while fprem isn't done. 2727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Label mod_loop; 2737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ bind(&mod_loop); 2747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // This instructions traps on all kinds inputs, but we are assuming the 2757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // floating point control word is set to ignore them all. 2767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ fprem(); 2777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // The following 2 instruction implicitly use eax. 2787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ fnstsw_ax(); 2797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ sahf(); 2807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(parity_even, &mod_loop); 2817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Move output to stack and clean up. 2827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ fstp(1); 2837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ fstp_d(Operand(esp, 0)); 2847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movsd(i.OutputDoubleRegister(), Operand(esp, 0)); 2857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ add(esp, Immediate(kDoubleSize)); 2867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 2877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 288b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org case kSSEFloat64Sqrt: 289b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org __ sqrtsd(i.OutputDoubleRegister(), i.InputOperand(0)); 290b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org break; 2917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSSEFloat64ToInt32: 2927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ cvttsd2si(i.OutputRegister(), i.InputOperand(0)); 2937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 2947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSSEFloat64ToUint32: { 2957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org XMMRegister scratch = xmm0; 2967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ Move(scratch, -2147483648.0); 297a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ addsd(scratch, i.InputOperand(0)); 2987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ cvttsd2si(i.OutputRegister(), scratch); 2997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ add(i.OutputRegister(), Immediate(0x80000000)); 3007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSSEInt32ToFloat64: 3037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ cvtsi2sd(i.OutputDoubleRegister(), i.InputOperand(0)); 3047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSSEUint32ToFloat64: 3067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // TODO(turbofan): IA32 SSE LoadUint32() should take an operand. 3077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ LoadUint32(i.OutputDoubleRegister(), i.InputRegister(0)); 3087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3096474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kIA32Movsxbl: 3106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movsx_b(i.OutputRegister(), i.MemoryOperand()); 3117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3126474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kIA32Movzxbl: 3137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movzx_b(i.OutputRegister(), i.MemoryOperand()); 3147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kIA32Movb: { 3167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int index = 0; 3177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand operand = i.MemoryOperand(&index); 3186474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (HasImmediateInput(instr, index)) { 3196474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov_b(operand, i.InputInt8(index)); 3206474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } else { 3216474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov_b(operand, i.InputRegister(index)); 3226474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 3237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3256474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kIA32Movsxwl: 3266474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movsx_w(i.OutputRegister(), i.MemoryOperand()); 3277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3286474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kIA32Movzxwl: 3297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movzx_w(i.OutputRegister(), i.MemoryOperand()); 3307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kIA32Movw: { 3327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int index = 0; 3337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand operand = i.MemoryOperand(&index); 3346474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (HasImmediateInput(instr, index)) { 3356474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov_w(operand, i.InputInt16(index)); 3366474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } else { 3376474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov_w(operand, i.InputRegister(index)); 3386474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 3397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3416474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kIA32Movl: 3426474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (instr->HasOutput()) { 3436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov(i.OutputRegister(), i.MemoryOperand()); 3446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } else { 3456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org int index = 0; 3466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Operand operand = i.MemoryOperand(&index); 3476474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (HasImmediateInput(instr, index)) { 3486474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov(operand, i.InputImmediate(index)); 3496474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } else { 3506474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ mov(operand, i.InputRegister(index)); 3516474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 3526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 3537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3546474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org case kIA32Movsd: 3556474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (instr->HasOutput()) { 3566474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movsd(i.OutputDoubleRegister(), i.MemoryOperand()); 3576474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } else { 3586474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org int index = 0; 3596474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Operand operand = i.MemoryOperand(&index); 3606474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ movsd(operand, i.InputDoubleRegister(index)); 3616474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 3627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 363fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org case kIA32Movss: 364fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org if (instr->HasOutput()) { 365fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org __ movss(i.OutputDoubleRegister(), i.MemoryOperand()); 366fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org __ cvtss2sd(i.OutputDoubleRegister(), i.OutputDoubleRegister()); 367fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org } else { 368fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org int index = 0; 369fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org Operand operand = i.MemoryOperand(&index); 370fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org __ cvtsd2ss(xmm0, i.InputDoubleRegister(index)); 371fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org __ movss(operand, xmm0); 372fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org } 373fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org break; 3747b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org case kIA32Push: 3757b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org if (HasImmediateInput(instr, 0)) { 3767b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org __ push(i.InputImmediate(0)); 3777b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org } else { 3787b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org __ push(i.InputOperand(0)); 3797b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org } 3807b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org break; 3817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kIA32StoreWriteBarrier: { 3827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register object = i.InputRegister(0); 3837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register index = i.InputRegister(1); 3847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register value = i.InputRegister(2); 3857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(Operand(object, index, times_1, 0), value); 3867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ lea(index, Operand(object, index, times_1, 0)); 3877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org SaveFPRegsMode mode = code_->frame()->DidAllocateDoubleRegisters() 3887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ? kSaveFPRegs 3897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : kDontSaveFPRegs; 3907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ RecordWrite(object, index, value, mode); 3917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 3927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 3957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Assembles branches after an instruction. 3987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid CodeGenerator::AssembleArchBranch(Instruction* instr, 3997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FlagsCondition condition) { 4007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org IA32OperandConverter i(this, instr); 4017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Label done; 4027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Emit a branch. The true and false targets are always the last two inputs 4047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // to the instruction. 4057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BasicBlock* tblock = i.InputBlock(instr->InputCount() - 2); 4067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BasicBlock* fblock = i.InputBlock(instr->InputCount() - 1); 4077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool fallthru = IsNextInAssemblyOrder(fblock); 4087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Label* tlabel = code()->GetLabel(tblock); 4097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Label* flabel = fallthru ? &done : code()->GetLabel(fblock); 4107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Label::Distance flabel_distance = fallthru ? Label::kNear : Label::kFar; 4117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org switch (condition) { 4127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnorderedEqual: 4137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(parity_even, flabel, flabel_distance); 4147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Fall through. 4157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kEqual: 4167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(equal, tlabel); 4177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 4187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnorderedNotEqual: 4197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(parity_even, tlabel); 4207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Fall through. 4217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kNotEqual: 4227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(not_equal, tlabel); 4237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 4247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSignedLessThan: 4257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(less, tlabel); 4267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 4277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSignedGreaterThanOrEqual: 4287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(greater_equal, tlabel); 4297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 4307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSignedLessThanOrEqual: 4317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(less_equal, tlabel); 4327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 4337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSignedGreaterThan: 4347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(greater, tlabel); 4357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 4367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnorderedLessThan: 4377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(parity_even, flabel, flabel_distance); 4387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Fall through. 4397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnsignedLessThan: 4407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(below, tlabel); 4417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 4427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnorderedGreaterThanOrEqual: 4437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(parity_even, tlabel); 4447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Fall through. 4457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnsignedGreaterThanOrEqual: 4467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(above_equal, tlabel); 4477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 4487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnorderedLessThanOrEqual: 4497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(parity_even, flabel, flabel_distance); 4507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Fall through. 4517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnsignedLessThanOrEqual: 4527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(below_equal, tlabel); 4537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 4547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnorderedGreaterThan: 4557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(parity_even, tlabel); 4567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Fall through. 4577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnsignedGreaterThan: 4587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(above, tlabel); 4597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 460aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org case kOverflow: 461aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org __ j(overflow, tlabel); 462aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org break; 463aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org case kNotOverflow: 464aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org __ j(no_overflow, tlabel); 465aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org break; 4667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (!fallthru) __ jmp(flabel, flabel_distance); // no fallthru to flabel. 4687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ bind(&done); 4697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 4707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Assembles boolean materializations after an instruction. 4737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid CodeGenerator::AssembleArchBoolean(Instruction* instr, 4747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FlagsCondition condition) { 4757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org IA32OperandConverter i(this, instr); 4767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Label done; 4777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 478aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org // Materialize a full 32-bit 1 or 0 value. The result register is always the 479aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org // last output of the instruction. 4807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Label check; 481e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_NE(0, instr->OutputCount()); 482aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org Register reg = i.OutputRegister(instr->OutputCount() - 1); 4837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Condition cc = no_condition; 4847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org switch (condition) { 4857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnorderedEqual: 4867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(parity_odd, &check, Label::kNear); 4877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(reg, Immediate(0)); 4887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ jmp(&done, Label::kNear); 4897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Fall through. 4907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kEqual: 4917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org cc = equal; 4927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 4937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnorderedNotEqual: 4947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(parity_odd, &check, Label::kNear); 4957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(reg, Immediate(1)); 4967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ jmp(&done, Label::kNear); 4977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Fall through. 4987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kNotEqual: 4997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org cc = not_equal; 5007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 5017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSignedLessThan: 5027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org cc = less; 5037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 5047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSignedGreaterThanOrEqual: 5057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org cc = greater_equal; 5067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 5077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSignedLessThanOrEqual: 5087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org cc = less_equal; 5097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 5107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kSignedGreaterThan: 5117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org cc = greater; 5127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 5137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnorderedLessThan: 5147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(parity_odd, &check, Label::kNear); 5157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(reg, Immediate(0)); 5167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ jmp(&done, Label::kNear); 5177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Fall through. 5187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnsignedLessThan: 5197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org cc = below; 5207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 5217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnorderedGreaterThanOrEqual: 5227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(parity_odd, &check, Label::kNear); 5237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(reg, Immediate(1)); 5247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ jmp(&done, Label::kNear); 5257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Fall through. 5267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnsignedGreaterThanOrEqual: 5277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org cc = above_equal; 5287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 5297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnorderedLessThanOrEqual: 5307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(parity_odd, &check, Label::kNear); 5317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(reg, Immediate(0)); 5327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ jmp(&done, Label::kNear); 5337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Fall through. 5347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnsignedLessThanOrEqual: 5357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org cc = below_equal; 5367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 5377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnorderedGreaterThan: 5387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(parity_odd, &check, Label::kNear); 5397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(reg, Immediate(1)); 5407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ jmp(&done, Label::kNear); 5417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Fall through. 5427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org case kUnsignedGreaterThan: 5437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org cc = above; 5447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org break; 545aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org case kOverflow: 546aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org cc = overflow; 547aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org break; 548aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org case kNotOverflow: 549aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org cc = no_overflow; 550aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org break; 5517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ bind(&check); 5537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (reg.is_byte_register()) { 5547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // setcc for byte registers (al, bl, cl, dl). 5557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ setcc(cc, reg); 5567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movzx_b(reg, reg); 5577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 5587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Emit a branch to set a register to either 1 or 0. 5597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Label set; 5607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(cc, &set, Label::kNear); 5617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(reg, Immediate(0)); 5627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ jmp(&done, Label::kNear); 5637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ bind(&set); 5647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(reg, Immediate(1)); 5657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ bind(&done); 5677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 5687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 570ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgvoid CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { 571ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( 572ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org isolate(), deoptimization_id, Deoptimizer::LAZY); 573ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY); 574ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org} 575ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org 576ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org 5777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// The calling convention for JSFunctions on IA32 passes arguments on the 5787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// stack and the JSFunction and context in EDI and ESI, respectively, thus 5797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// the steps of the call look as follows: 5807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ before the call instruction }-------------------------------------------- 5827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | caller frame | 5837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 5847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ push arguments and setup ESI, EDI }-------------------------------------- 5867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | args + receiver | caller frame | 5877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 5887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// [edi = JSFunction, esi = context] 5897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ call [edi + kCodeEntryOffset] }------------------------------------------ 5917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | RET | args + receiver | caller frame | 5927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 5937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// =={ prologue of called function }============================================ 5957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ push ebp }--------------------------------------------------------------- 5967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | FP | RET | args + receiver | caller frame | 5977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 5987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ mov ebp, esp }----------------------------------------------------------- 6007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | FP | RET | args + receiver | caller frame | 6017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ ebp,esp 6027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ push esi }--------------------------------------------------------------- 6047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | CTX | FP | RET | args + receiver | caller frame | 6057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^esp ^ ebp 6067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ push edi }--------------------------------------------------------------- 6087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | FNC | CTX | FP | RET | args + receiver | caller frame | 6097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^esp ^ ebp 6107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ subi esp, #N }----------------------------------------------------------- 6127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | callee frame | FNC | CTX | FP | RET | args + receiver | caller frame | 6137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^esp ^ ebp 6147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// =={ body of called function }================================================ 6167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// =={ epilogue of called function }============================================ 6187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ mov esp, ebp }----------------------------------------------------------- 6197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | FP | RET | args + receiver | caller frame | 6207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp,ebp 6217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ pop ebp }----------------------------------------------------------- 6237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | | RET | args + receiver | caller frame | 6247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 6257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ ret #A+1 }----------------------------------------------------------- 6277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | | caller frame | 6287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 6297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Runtime function calls are accomplished by doing a stub call to the 6327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// CEntryStub (a real code object). On IA32 passes arguments on the 6337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// stack, the number of arguments in EAX, the address of the runtime function 6347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// in EBX, and the context in ESI. 6357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ before the call instruction }-------------------------------------------- 6377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | caller frame | 6387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 6397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ push arguments and setup EAX, EBX, and ESI }----------------------------- 6417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | args + receiver | caller frame | 6427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 6437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// [eax = #args, ebx = runtime function, esi = context] 6447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ call #CEntryStub }------------------------------------------------------- 6467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | RET | args + receiver | caller frame | 6477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 6487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// =={ body of runtime function }=============================================== 6507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ runtime returns }-------------------------------------------------------- 6527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | caller frame | 6537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 6547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Other custom linkages (e.g. for calling directly into and out of C++) may 6567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// need to save callee-saved registers on the stack, which is done in the 6577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// function prologue of generated code. 6587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ before the call instruction }-------------------------------------------- 6607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | caller frame | 6617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 6627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ set up arguments in registers on stack }--------------------------------- 6647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | args | caller frame | 6657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 6667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// [r0 = arg0, r1 = arg1, ...] 6677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ call code }-------------------------------------------------------------- 6697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | RET | args | caller frame | 6707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 6717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// =={ prologue of called function }============================================ 6737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ push ebp }--------------------------------------------------------------- 6747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | FP | RET | args | caller frame | 6757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 6767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ mov ebp, esp }----------------------------------------------------------- 6787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | FP | RET | args | caller frame | 6797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ ebp,esp 6807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ save registers }--------------------------------------------------------- 6827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | regs | FP | RET | args | caller frame | 6837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 6847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ subi esp, #N }----------------------------------------------------------- 6867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | callee frame | regs | FP | RET | args | caller frame | 6877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^esp ^ ebp 6887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// =={ body of called function }================================================ 6907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// =={ epilogue of called function }============================================ 6927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ restore registers }------------------------------------------------------ 6937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | regs | FP | RET | args | caller frame | 6947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 6957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ mov esp, ebp }----------------------------------------------------------- 6977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | FP | RET | args | caller frame | 6987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp,ebp 6997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// --{ pop ebp }---------------------------------------------------------------- 7017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// | RET | args | caller frame | 7027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// ^ esp ^ ebp 7037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid CodeGenerator::AssemblePrologue() { 7067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 7077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Frame* frame = code_->frame(); 7087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int stack_slots = frame->GetSpillSlotCount(); 7097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (descriptor->kind() == CallDescriptor::kCallAddress) { 7107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Assemble a prologue similar the to cdecl calling convention. 7117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ push(ebp); 7127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(ebp, esp); 7137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org const RegList saves = descriptor->CalleeSavedRegisters(); 7147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (saves != 0) { // Save callee-saved registers. 7157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int register_save_area_size = 0; 7167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org for (int i = Register::kNumRegisters - 1; i >= 0; i--) { 7177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (!((1 << i) & saves)) continue; 7187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ push(Register::from_code(i)); 7197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org register_save_area_size += kPointerSize; 7207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 7217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org frame->SetRegisterSaveAreaSize(register_save_area_size); 7227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 7237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else if (descriptor->IsJSFunctionCall()) { 7247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CompilationInfo* info = linkage()->info(); 7257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ Prologue(info->IsCodePreAgingActive()); 7267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org frame->SetRegisterSaveAreaSize( 7277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org StandardFrameConstants::kFixedFrameSizeFromFp); 7287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Sloppy mode functions and builtins need to replace the receiver with the 7307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // global proxy when called as functions (without an explicit receiver 7317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // object). 7327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? 7337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (info->strict_mode() == SLOPPY && !info->is_native()) { 7347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Label ok; 7357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // +2 for return address and saved frame pointer. 7367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int receiver_slot = info->scope()->num_parameters() + 2; 7377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(ecx, Operand(ebp, receiver_slot * kPointerSize)); 7387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ cmp(ecx, isolate()->factory()->undefined_value()); 7397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ j(not_equal, &ok, Label::kNear); 7407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(ecx, GlobalObjectOperand()); 7417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalProxyOffset)); 7427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(Operand(ebp, receiver_slot * kPointerSize), ecx); 7437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ bind(&ok); 7447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 7457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 7477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ StubPrologue(); 7487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org frame->SetRegisterSaveAreaSize( 7497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org StandardFrameConstants::kFixedFrameSizeFromFp); 7507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 7517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (stack_slots > 0) { 7527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ sub(esp, Immediate(stack_slots * kPointerSize)); 7537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 7547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 7557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid CodeGenerator::AssembleReturn() { 7587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 7597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (descriptor->kind() == CallDescriptor::kCallAddress) { 7607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org const RegList saves = descriptor->CalleeSavedRegisters(); 7617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (frame()->GetRegisterSaveAreaSize() > 0) { 7627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Remove this frame's spill slots first. 7637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int stack_slots = frame()->GetSpillSlotCount(); 7647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (stack_slots > 0) { 7657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ add(esp, Immediate(stack_slots * kPointerSize)); 7667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 7677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Restore registers. 7687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (saves != 0) { 7697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org for (int i = 0; i < Register::kNumRegisters; i++) { 7707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (!((1 << i) & saves)) continue; 7717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ pop(Register::from_code(i)); 7727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 7737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 7747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ pop(ebp); // Pop caller's frame pointer. 7757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ ret(0); 7767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 7777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // No saved registers. 7787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(esp, ebp); // Move stack pointer back to frame pointer. 7797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ pop(ebp); // Pop caller's frame pointer. 7807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ ret(0); 7817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 7827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 7837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(esp, ebp); // Move stack pointer back to frame pointer. 7847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ pop(ebp); // Pop caller's frame pointer. 7859aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org int pop_count = descriptor->IsJSFunctionCall() 7869aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org ? static_cast<int>(descriptor->JSParameterCount()) 7879aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org : 0; 7887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ ret(pop_count * kPointerSize); 7897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 7907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 7917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid CodeGenerator::AssembleMove(InstructionOperand* source, 7947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* destination) { 7957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org IA32OperandConverter g(this, NULL); 7967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Dispatch on the source and destination operand kinds. Not all 7977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // combinations are possible. 7987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (source->IsRegister()) { 799e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination->IsRegister() || destination->IsStackSlot()); 8007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register src = g.ToRegister(source); 8017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand dst = g.ToOperand(destination); 8027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(dst, src); 8037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else if (source->IsStackSlot()) { 804e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination->IsRegister() || destination->IsStackSlot()); 8057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand src = g.ToOperand(source); 8067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (destination->IsRegister()) { 8077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register dst = g.ToRegister(destination); 8087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(dst, src); 8097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 8107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand dst = g.ToOperand(destination); 8117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ push(src); 8127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ pop(dst); 8137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else if (source->IsConstant()) { 8157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Constant src_constant = g.ToConstant(source); 8167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (src_constant.type() == Constant::kHeapObject) { 8177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<HeapObject> src = src_constant.ToHeapObject(); 8187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (destination->IsRegister()) { 8197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register dst = g.ToRegister(destination); 8207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ LoadHeapObject(dst, src); 8217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 822e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination->IsStackSlot()); 8237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand dst = g.ToOperand(destination); 8247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org AllowDeferredHandleDereference embedding_raw_address; 8257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (isolate()->heap()->InNewSpace(*src)) { 8267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ PushHeapObject(src); 8277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ pop(dst); 8287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 8297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(dst, src); 8307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else if (destination->IsRegister()) { 8337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register dst = g.ToRegister(destination); 8347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(dst, g.ToImmediate(source)); 8357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else if (destination->IsStackSlot()) { 8367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand dst = g.ToOperand(destination); 8377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(dst, g.ToImmediate(source)); 8387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 8397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org double v = g.ToDouble(source); 840e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org uint64_t int_val = bit_cast<uint64_t, double>(v); 8417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int32_t lower = static_cast<int32_t>(int_val); 8427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt); 8437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (destination->IsDoubleRegister()) { 8447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org XMMRegister dst = g.ToDoubleRegister(destination); 8457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ Move(dst, v); 8467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 847e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination->IsDoubleStackSlot()); 8487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand dst0 = g.ToOperand(destination); 8497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand dst1 = g.HighOperand(destination); 8507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(dst0, Immediate(lower)); 8517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ mov(dst1, Immediate(upper)); 8527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else if (source->IsDoubleRegister()) { 8557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org XMMRegister src = g.ToDoubleRegister(source); 8567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (destination->IsDoubleRegister()) { 8577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org XMMRegister dst = g.ToDoubleRegister(destination); 8587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movaps(dst, src); 8597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 860e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination->IsDoubleStackSlot()); 8617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand dst = g.ToOperand(destination); 8627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movsd(dst, src); 8637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else if (source->IsDoubleStackSlot()) { 865e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot()); 8667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand src = g.ToOperand(source); 8677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (destination->IsDoubleRegister()) { 8687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org XMMRegister dst = g.ToDoubleRegister(destination); 8697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movsd(dst, src); 8707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 8717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // We rely on having xmm0 available as a fixed scratch register. 8727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand dst = g.ToOperand(destination); 8737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movsd(xmm0, src); 8747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movsd(dst, xmm0); 8757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 8777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UNREACHABLE(); 8787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 8807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid CodeGenerator::AssembleSwap(InstructionOperand* source, 8837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* destination) { 8847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org IA32OperandConverter g(this, NULL); 8857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Dispatch on the source and destination operand kinds. Not all 8867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // combinations are possible. 8877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (source->IsRegister() && destination->IsRegister()) { 8887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Register-register. 8897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register src = g.ToRegister(source); 8907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Register dst = g.ToRegister(destination); 8917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ xchg(dst, src); 8927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else if (source->IsRegister() && destination->IsStackSlot()) { 8937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Register-memory. 8947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ xchg(g.ToRegister(source), g.ToOperand(destination)); 8957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else if (source->IsStackSlot() && destination->IsStackSlot()) { 8967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Memory-memory. 8977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand src = g.ToOperand(source); 8987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand dst = g.ToOperand(destination); 8997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ push(dst); 9007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ push(src); 9017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ pop(dst); 9027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ pop(src); 9037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else if (source->IsDoubleRegister() && destination->IsDoubleRegister()) { 9047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // XMM register-register swap. We rely on having xmm0 9057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // available as a fixed scratch register. 9067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org XMMRegister src = g.ToDoubleRegister(source); 9077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org XMMRegister dst = g.ToDoubleRegister(destination); 9087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movaps(xmm0, src); 9097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movaps(src, dst); 9107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movaps(dst, xmm0); 9117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else if (source->IsDoubleRegister() && source->IsDoubleStackSlot()) { 9127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // XMM register-memory swap. We rely on having xmm0 9137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // available as a fixed scratch register. 9147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org XMMRegister reg = g.ToDoubleRegister(source); 9157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand other = g.ToOperand(destination); 9167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movsd(xmm0, other); 9177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movsd(other, reg); 9187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movaps(reg, xmm0); 9197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else if (source->IsDoubleStackSlot() && destination->IsDoubleStackSlot()) { 9207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Double-width memory-to-memory. 9217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand src0 = g.ToOperand(source); 9227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand src1 = g.HighOperand(source); 9237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand dst0 = g.ToOperand(destination); 9247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Operand dst1 = g.HighOperand(destination); 9257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movsd(xmm0, dst0); // Save destination in xmm0. 9267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ push(src0); // Then use stack to copy source to destination. 9277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ pop(dst0); 9287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ push(src1); 9297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ pop(dst1); 9307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org __ movsd(src0, xmm0); 9317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } else { 9327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // No other combinations are possible. 9337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UNREACHABLE(); 9347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 9357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} 9367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 9377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 9387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid CodeGenerator::AddNopForSmiCodeInlining() { __ nop(); } 9397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 94006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 94106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgvoid CodeGenerator::EnsureSpaceForLazyDeopt() { 94206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org int space_needed = Deoptimizer::patch_size(); 94306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (!linkage()->info()->IsStub()) { 94406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Ensure that we have enough space after the previous lazy-bailout 94506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // instruction for patching the code here. 94606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org int current_pc = masm()->pc_offset(); 94706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (current_pc < last_lazy_deopt_pc_ + space_needed) { 94806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 94906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ Nop(padding_size); 95006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 95106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 95206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org MarkLazyDeoptSite(); 95306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org} 95406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 9557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#undef __ 9567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 957d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.org} // namespace compiler 958d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.org} // namespace internal 959d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.org} // namespace v8 960