| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
| 9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 return ToImmediate(instr_->InputAt(index)); | 35 return ToImmediate(instr_->InputAt(index)); |
| 36 } | 36 } |
| 37 | 37 |
| 38 Operand OutputOperand() { return ToOperand(instr_->Output()); } | 38 Operand OutputOperand() { return ToOperand(instr_->Output()); } |
| 39 | 39 |
| 40 Operand ToOperand(InstructionOperand* op, int extra = 0) { | 40 Operand ToOperand(InstructionOperand* op, int extra = 0) { |
| 41 if (op->IsRegister()) { | 41 if (op->IsRegister()) { |
| 42 DCHECK(extra == 0); | 42 DCHECK(extra == 0); |
| 43 return Operand(ToRegister(op)); | 43 return Operand(ToRegister(op)); |
| 44 } | 44 } |
| 45 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); | 45 DCHECK(op->IsStackSlot() || op->IsFPStackSlot()); |
| 46 return SlotToOperand(AllocatedOperand::cast(op)->index(), extra); | 46 return SlotToOperand(AllocatedOperand::cast(op)->index(), extra); |
| 47 } | 47 } |
| 48 | 48 |
| 49 Operand SlotToOperand(int slot, int extra = 0) { | 49 Operand SlotToOperand(int slot, int extra = 0) { |
| 50 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); | 50 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); |
| 51 return Operand(offset.from_stack_pointer() ? esp : ebp, | 51 return Operand(offset.from_stack_pointer() ? esp : ebp, |
| 52 offset.offset() + extra); | 52 offset.offset() + extra); |
| 53 } | 53 } |
| 54 | 54 |
| 55 Operand HighOperand(InstructionOperand* op) { | 55 Operand HighOperand(InstructionOperand* op) { |
| 56 DCHECK(op->IsDoubleStackSlot()); | 56 DCHECK(op->IsFPStackSlot()); |
| 57 return ToOperand(op, kPointerSize); | 57 return ToOperand(op, kPointerSize); |
| 58 } | 58 } |
| 59 | 59 |
| 60 Immediate ToImmediate(InstructionOperand* operand) { | 60 Immediate ToImmediate(InstructionOperand* operand) { |
| 61 Constant constant = ToConstant(operand); | 61 Constant constant = ToConstant(operand); |
| 62 if (constant.type() == Constant::kInt32 && | 62 if (constant.type() == Constant::kInt32 && |
| 63 (constant.rmode() == RelocInfo::WASM_MEMORY_REFERENCE || | 63 (constant.rmode() == RelocInfo::WASM_MEMORY_REFERENCE || |
| 64 constant.rmode() == RelocInfo::WASM_MEMORY_SIZE_REFERENCE)) { | 64 constant.rmode() == RelocInfo::WASM_MEMORY_SIZE_REFERENCE)) { |
| 65 return Immediate(reinterpret_cast<Address>(constant.ToInt32()), | 65 return Immediate(reinterpret_cast<Address>(constant.ToInt32()), |
| 66 constant.rmode()); | 66 constant.rmode()); |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 if (HasImmediateInput(instr, 0)) { | 451 if (HasImmediateInput(instr, 0)) { |
| 452 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 452 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
| 453 __ call(code, RelocInfo::CODE_TARGET); | 453 __ call(code, RelocInfo::CODE_TARGET); |
| 454 } else { | 454 } else { |
| 455 Register reg = i.InputRegister(0); | 455 Register reg = i.InputRegister(0); |
| 456 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 456 __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 457 __ call(reg); | 457 __ call(reg); |
| 458 } | 458 } |
| 459 RecordCallPosition(instr); | 459 RecordCallPosition(instr); |
| 460 bool double_result = | 460 bool double_result = |
| 461 instr->HasOutput() && instr->Output()->IsDoubleRegister(); | 461 instr->HasOutput() && instr->Output()->IsFPRegister(); |
| 462 if (double_result) { | 462 if (double_result) { |
| 463 __ lea(esp, Operand(esp, -kDoubleSize)); | 463 __ lea(esp, Operand(esp, -kDoubleSize)); |
| 464 __ fstp_d(Operand(esp, 0)); | 464 __ fstp_d(Operand(esp, 0)); |
| 465 } | 465 } |
| 466 __ fninit(); | 466 __ fninit(); |
| 467 if (double_result) { | 467 if (double_result) { |
| 468 __ fld_d(Operand(esp, 0)); | 468 __ fld_d(Operand(esp, 0)); |
| 469 __ lea(esp, Operand(esp, kDoubleSize)); | 469 __ lea(esp, Operand(esp, kDoubleSize)); |
| 470 } else { | 470 } else { |
| 471 __ fld1(); | 471 __ fld1(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); | 513 __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); |
| 514 __ Assert(equal, kWrongFunctionContext); | 514 __ Assert(equal, kWrongFunctionContext); |
| 515 } | 515 } |
| 516 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 516 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
| 517 __ VerifyX87StackDepth(1); | 517 __ VerifyX87StackDepth(1); |
| 518 } | 518 } |
| 519 __ fstp(0); | 519 __ fstp(0); |
| 520 __ call(FieldOperand(func, JSFunction::kCodeEntryOffset)); | 520 __ call(FieldOperand(func, JSFunction::kCodeEntryOffset)); |
| 521 RecordCallPosition(instr); | 521 RecordCallPosition(instr); |
| 522 bool double_result = | 522 bool double_result = |
| 523 instr->HasOutput() && instr->Output()->IsDoubleRegister(); | 523 instr->HasOutput() && instr->Output()->IsFPRegister(); |
| 524 if (double_result) { | 524 if (double_result) { |
| 525 __ lea(esp, Operand(esp, -kDoubleSize)); | 525 __ lea(esp, Operand(esp, -kDoubleSize)); |
| 526 __ fstp_d(Operand(esp, 0)); | 526 __ fstp_d(Operand(esp, 0)); |
| 527 } | 527 } |
| 528 __ fninit(); | 528 __ fninit(); |
| 529 if (double_result) { | 529 if (double_result) { |
| 530 __ fld_d(Operand(esp, 0)); | 530 __ fld_d(Operand(esp, 0)); |
| 531 __ lea(esp, Operand(esp, kDoubleSize)); | 531 __ lea(esp, Operand(esp, kDoubleSize)); |
| 532 } else { | 532 } else { |
| 533 __ fld1(); | 533 __ fld1(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 __ fstp(0); | 574 __ fstp(0); |
| 575 int const num_parameters = MiscField::decode(instr->opcode()); | 575 int const num_parameters = MiscField::decode(instr->opcode()); |
| 576 if (HasImmediateInput(instr, 0)) { | 576 if (HasImmediateInput(instr, 0)) { |
| 577 ExternalReference ref = i.InputExternalReference(0); | 577 ExternalReference ref = i.InputExternalReference(0); |
| 578 __ CallCFunction(ref, num_parameters); | 578 __ CallCFunction(ref, num_parameters); |
| 579 } else { | 579 } else { |
| 580 Register func = i.InputRegister(0); | 580 Register func = i.InputRegister(0); |
| 581 __ CallCFunction(func, num_parameters); | 581 __ CallCFunction(func, num_parameters); |
| 582 } | 582 } |
| 583 bool double_result = | 583 bool double_result = |
| 584 instr->HasOutput() && instr->Output()->IsDoubleRegister(); | 584 instr->HasOutput() && instr->Output()->IsFPRegister(); |
| 585 if (double_result) { | 585 if (double_result) { |
| 586 __ lea(esp, Operand(esp, -kDoubleSize)); | 586 __ lea(esp, Operand(esp, -kDoubleSize)); |
| 587 __ fstp_d(Operand(esp, 0)); | 587 __ fstp_d(Operand(esp, 0)); |
| 588 } | 588 } |
| 589 __ fninit(); | 589 __ fninit(); |
| 590 if (double_result) { | 590 if (double_result) { |
| 591 __ fld_d(Operand(esp, 0)); | 591 __ fld_d(Operand(esp, 0)); |
| 592 __ lea(esp, Operand(esp, kDoubleSize)); | 592 __ lea(esp, Operand(esp, kDoubleSize)); |
| 593 } else { | 593 } else { |
| 594 __ fld1(); | 594 __ fld1(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 609 case kArchNop: | 609 case kArchNop: |
| 610 case kArchThrowTerminator: | 610 case kArchThrowTerminator: |
| 611 // don't emit code for nops. | 611 // don't emit code for nops. |
| 612 break; | 612 break; |
| 613 case kArchDeoptimize: { | 613 case kArchDeoptimize: { |
| 614 int deopt_state_id = | 614 int deopt_state_id = |
| 615 BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); | 615 BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); |
| 616 int double_register_param_count = 0; | 616 int double_register_param_count = 0; |
| 617 int x87_layout = 0; | 617 int x87_layout = 0; |
| 618 for (size_t i = 0; i < instr->InputCount(); i++) { | 618 for (size_t i = 0; i < instr->InputCount(); i++) { |
| 619 if (instr->InputAt(i)->IsDoubleRegister()) { | 619 if (instr->InputAt(i)->IsFPRegister()) { |
| 620 double_register_param_count++; | 620 double_register_param_count++; |
| 621 } | 621 } |
| 622 } | 622 } |
| 623 // Currently we use only one X87 register. If double_register_param_count | 623 // Currently we use only one X87 register. If double_register_param_count |
| 624 // is bigger than 1, it means duplicated double register is added to input | 624 // is bigger than 1, it means duplicated double register is added to input |
| 625 // of this instruction. | 625 // of this instruction. |
| 626 if (double_register_param_count > 0) { | 626 if (double_register_param_count > 0) { |
| 627 x87_layout = (0 << 3) | 1; | 627 x87_layout = (0 << 3) | 1; |
| 628 } | 628 } |
| 629 // The layout of x87 register stack is loaded on the top of FPU register | 629 // The layout of x87 register stack is loaded on the top of FPU register |
| (...skipping 19 matching lines...) Expand all Loading... |
| 649 __ mov(i.OutputRegister(), esp); | 649 __ mov(i.OutputRegister(), esp); |
| 650 break; | 650 break; |
| 651 case kArchParentFramePointer: | 651 case kArchParentFramePointer: |
| 652 if (frame_access_state()->has_frame()) { | 652 if (frame_access_state()->has_frame()) { |
| 653 __ mov(i.OutputRegister(), Operand(ebp, 0)); | 653 __ mov(i.OutputRegister(), Operand(ebp, 0)); |
| 654 } else { | 654 } else { |
| 655 __ mov(i.OutputRegister(), ebp); | 655 __ mov(i.OutputRegister(), ebp); |
| 656 } | 656 } |
| 657 break; | 657 break; |
| 658 case kArchTruncateDoubleToI: { | 658 case kArchTruncateDoubleToI: { |
| 659 if (!instr->InputAt(0)->IsDoubleRegister()) { | 659 if (!instr->InputAt(0)->IsFPRegister()) { |
| 660 __ fld_d(i.InputOperand(0)); | 660 __ fld_d(i.InputOperand(0)); |
| 661 } | 661 } |
| 662 __ TruncateX87TOSToI(i.OutputRegister()); | 662 __ TruncateX87TOSToI(i.OutputRegister()); |
| 663 if (!instr->InputAt(0)->IsDoubleRegister()) { | 663 if (!instr->InputAt(0)->IsFPRegister()) { |
| 664 __ fstp(0); | 664 __ fstp(0); |
| 665 } | 665 } |
| 666 break; | 666 break; |
| 667 } | 667 } |
| 668 case kArchStoreWithWriteBarrier: { | 668 case kArchStoreWithWriteBarrier: { |
| 669 RecordWriteMode mode = | 669 RecordWriteMode mode = |
| 670 static_cast<RecordWriteMode>(MiscField::decode(instr->opcode())); | 670 static_cast<RecordWriteMode>(MiscField::decode(instr->opcode())); |
| 671 Register object = i.InputRegister(0); | 671 Register object = i.InputRegister(0); |
| 672 size_t index = 0; | 672 size_t index = 0; |
| 673 Operand operand = i.MemoryOperand(&index); | 673 Operand operand = i.MemoryOperand(&index); |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 InstructionOperand* source = instr->InputAt(0); | 899 InstructionOperand* source = instr->InputAt(0); |
| 900 InstructionOperand* destination = instr->Output(); | 900 InstructionOperand* destination = instr->Output(); |
| 901 DCHECK(source->IsConstant()); | 901 DCHECK(source->IsConstant()); |
| 902 X87OperandConverter g(this, nullptr); | 902 X87OperandConverter g(this, nullptr); |
| 903 Constant src_constant = g.ToConstant(source); | 903 Constant src_constant = g.ToConstant(source); |
| 904 | 904 |
| 905 DCHECK_EQ(Constant::kFloat64, src_constant.type()); | 905 DCHECK_EQ(Constant::kFloat64, src_constant.type()); |
| 906 uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64()); | 906 uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64()); |
| 907 uint32_t lower = static_cast<uint32_t>(src); | 907 uint32_t lower = static_cast<uint32_t>(src); |
| 908 uint32_t upper = static_cast<uint32_t>(src >> 32); | 908 uint32_t upper = static_cast<uint32_t>(src >> 32); |
| 909 if (destination->IsDoubleRegister()) { | 909 if (destination->IsFPRegister()) { |
| 910 __ sub(esp, Immediate(kDoubleSize)); | 910 __ sub(esp, Immediate(kDoubleSize)); |
| 911 __ mov(MemOperand(esp, 0), Immediate(lower)); | 911 __ mov(MemOperand(esp, 0), Immediate(lower)); |
| 912 __ mov(MemOperand(esp, kInt32Size), Immediate(upper)); | 912 __ mov(MemOperand(esp, kInt32Size), Immediate(upper)); |
| 913 __ fstp(0); | 913 __ fstp(0); |
| 914 __ fld_d(MemOperand(esp, 0)); | 914 __ fld_d(MemOperand(esp, 0)); |
| 915 __ add(esp, Immediate(kDoubleSize)); | 915 __ add(esp, Immediate(kDoubleSize)); |
| 916 } else { | 916 } else { |
| 917 UNREACHABLE(); | 917 UNREACHABLE(); |
| 918 } | 918 } |
| 919 break; | 919 break; |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 __ fabs(); | 1091 __ fabs(); |
| 1092 __ lea(esp, Operand(esp, kFloatSize)); | 1092 __ lea(esp, Operand(esp, kFloatSize)); |
| 1093 break; | 1093 break; |
| 1094 } | 1094 } |
| 1095 case kX87Float32Round: { | 1095 case kX87Float32Round: { |
| 1096 RoundingMode mode = | 1096 RoundingMode mode = |
| 1097 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); | 1097 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); |
| 1098 // Set the correct round mode in x87 control register | 1098 // Set the correct round mode in x87 control register |
| 1099 __ X87SetRC((mode << 10)); | 1099 __ X87SetRC((mode << 10)); |
| 1100 | 1100 |
| 1101 if (!instr->InputAt(0)->IsDoubleRegister()) { | 1101 if (!instr->InputAt(0)->IsFPRegister()) { |
| 1102 InstructionOperand* input = instr->InputAt(0); | 1102 InstructionOperand* input = instr->InputAt(0); |
| 1103 USE(input); | 1103 USE(input); |
| 1104 DCHECK(input->IsDoubleStackSlot()); | 1104 DCHECK(input->IsFPStackSlot()); |
| 1105 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 1105 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
| 1106 __ VerifyX87StackDepth(1); | 1106 __ VerifyX87StackDepth(1); |
| 1107 } | 1107 } |
| 1108 __ fstp(0); | 1108 __ fstp(0); |
| 1109 __ fld_s(i.InputOperand(0)); | 1109 __ fld_s(i.InputOperand(0)); |
| 1110 } | 1110 } |
| 1111 __ frndint(); | 1111 __ frndint(); |
| 1112 __ X87SetRC(0x0000); | 1112 __ X87SetRC(0x0000); |
| 1113 break; | 1113 break; |
| 1114 } | 1114 } |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1332 __ push(input_reg); | 1332 __ push(input_reg); |
| 1333 __ fild_s(Operand(esp, 0)); | 1333 __ fild_s(Operand(esp, 0)); |
| 1334 __ pop(input_reg); | 1334 __ pop(input_reg); |
| 1335 } else { | 1335 } else { |
| 1336 __ fild_s(i.InputOperand(0)); | 1336 __ fild_s(i.InputOperand(0)); |
| 1337 } | 1337 } |
| 1338 break; | 1338 break; |
| 1339 } | 1339 } |
| 1340 case kX87Float32ToFloat64: { | 1340 case kX87Float32ToFloat64: { |
| 1341 InstructionOperand* input = instr->InputAt(0); | 1341 InstructionOperand* input = instr->InputAt(0); |
| 1342 if (input->IsDoubleRegister()) { | 1342 if (input->IsFPRegister()) { |
| 1343 __ sub(esp, Immediate(kDoubleSize)); | 1343 __ sub(esp, Immediate(kDoubleSize)); |
| 1344 __ fstp_s(MemOperand(esp, 0)); | 1344 __ fstp_s(MemOperand(esp, 0)); |
| 1345 __ fld_s(MemOperand(esp, 0)); | 1345 __ fld_s(MemOperand(esp, 0)); |
| 1346 __ add(esp, Immediate(kDoubleSize)); | 1346 __ add(esp, Immediate(kDoubleSize)); |
| 1347 } else { | 1347 } else { |
| 1348 DCHECK(input->IsDoubleStackSlot()); | 1348 DCHECK(input->IsFPStackSlot()); |
| 1349 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 1349 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
| 1350 __ VerifyX87StackDepth(1); | 1350 __ VerifyX87StackDepth(1); |
| 1351 } | 1351 } |
| 1352 __ fstp(0); | 1352 __ fstp(0); |
| 1353 __ fld_s(i.InputOperand(0)); | 1353 __ fld_s(i.InputOperand(0)); |
| 1354 } | 1354 } |
| 1355 break; | 1355 break; |
| 1356 } | 1356 } |
| 1357 case kX87Uint32ToFloat64: { | 1357 case kX87Uint32ToFloat64: { |
| 1358 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 1358 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
| 1359 __ VerifyX87StackDepth(1); | 1359 __ VerifyX87StackDepth(1); |
| 1360 } | 1360 } |
| 1361 __ fstp(0); | 1361 __ fstp(0); |
| 1362 __ LoadUint32NoSSE2(i.InputRegister(0)); | 1362 __ LoadUint32NoSSE2(i.InputRegister(0)); |
| 1363 break; | 1363 break; |
| 1364 } | 1364 } |
| 1365 case kX87Float32ToInt32: { | 1365 case kX87Float32ToInt32: { |
| 1366 if (!instr->InputAt(0)->IsDoubleRegister()) { | 1366 if (!instr->InputAt(0)->IsFPRegister()) { |
| 1367 __ fld_s(i.InputOperand(0)); | 1367 __ fld_s(i.InputOperand(0)); |
| 1368 } | 1368 } |
| 1369 __ TruncateX87TOSToI(i.OutputRegister(0)); | 1369 __ TruncateX87TOSToI(i.OutputRegister(0)); |
| 1370 if (!instr->InputAt(0)->IsDoubleRegister()) { | 1370 if (!instr->InputAt(0)->IsFPRegister()) { |
| 1371 __ fstp(0); | 1371 __ fstp(0); |
| 1372 } | 1372 } |
| 1373 break; | 1373 break; |
| 1374 } | 1374 } |
| 1375 case kX87Float32ToUint32: { | 1375 case kX87Float32ToUint32: { |
| 1376 if (!instr->InputAt(0)->IsDoubleRegister()) { | 1376 if (!instr->InputAt(0)->IsFPRegister()) { |
| 1377 __ fld_s(i.InputOperand(0)); | 1377 __ fld_s(i.InputOperand(0)); |
| 1378 } | 1378 } |
| 1379 Label success; | 1379 Label success; |
| 1380 __ TruncateX87TOSToI(i.OutputRegister(0)); | 1380 __ TruncateX87TOSToI(i.OutputRegister(0)); |
| 1381 __ test(i.OutputRegister(0), i.OutputRegister(0)); | 1381 __ test(i.OutputRegister(0), i.OutputRegister(0)); |
| 1382 __ j(positive, &success); | 1382 __ j(positive, &success); |
| 1383 __ push(Immediate(INT32_MIN)); | 1383 __ push(Immediate(INT32_MIN)); |
| 1384 __ fild_s(Operand(esp, 0)); | 1384 __ fild_s(Operand(esp, 0)); |
| 1385 __ lea(esp, Operand(esp, kPointerSize)); | 1385 __ lea(esp, Operand(esp, kPointerSize)); |
| 1386 __ faddp(); | 1386 __ faddp(); |
| 1387 __ TruncateX87TOSToI(i.OutputRegister(0)); | 1387 __ TruncateX87TOSToI(i.OutputRegister(0)); |
| 1388 __ or_(i.OutputRegister(0), Immediate(0x80000000)); | 1388 __ or_(i.OutputRegister(0), Immediate(0x80000000)); |
| 1389 __ bind(&success); | 1389 __ bind(&success); |
| 1390 if (!instr->InputAt(0)->IsDoubleRegister()) { | 1390 if (!instr->InputAt(0)->IsFPRegister()) { |
| 1391 __ fstp(0); | 1391 __ fstp(0); |
| 1392 } | 1392 } |
| 1393 break; | 1393 break; |
| 1394 } | 1394 } |
| 1395 case kX87Float64ToInt32: { | 1395 case kX87Float64ToInt32: { |
| 1396 if (!instr->InputAt(0)->IsDoubleRegister()) { | 1396 if (!instr->InputAt(0)->IsFPRegister()) { |
| 1397 __ fld_d(i.InputOperand(0)); | 1397 __ fld_d(i.InputOperand(0)); |
| 1398 } | 1398 } |
| 1399 __ TruncateX87TOSToI(i.OutputRegister(0)); | 1399 __ TruncateX87TOSToI(i.OutputRegister(0)); |
| 1400 if (!instr->InputAt(0)->IsDoubleRegister()) { | 1400 if (!instr->InputAt(0)->IsFPRegister()) { |
| 1401 __ fstp(0); | 1401 __ fstp(0); |
| 1402 } | 1402 } |
| 1403 break; | 1403 break; |
| 1404 } | 1404 } |
| 1405 case kX87Float64ToFloat32: { | 1405 case kX87Float64ToFloat32: { |
| 1406 InstructionOperand* input = instr->InputAt(0); | 1406 InstructionOperand* input = instr->InputAt(0); |
| 1407 if (input->IsDoubleRegister()) { | 1407 if (input->IsFPRegister()) { |
| 1408 __ sub(esp, Immediate(kDoubleSize)); | 1408 __ sub(esp, Immediate(kDoubleSize)); |
| 1409 __ fstp_s(MemOperand(esp, 0)); | 1409 __ fstp_s(MemOperand(esp, 0)); |
| 1410 __ fld_s(MemOperand(esp, 0)); | 1410 __ fld_s(MemOperand(esp, 0)); |
| 1411 __ add(esp, Immediate(kDoubleSize)); | 1411 __ add(esp, Immediate(kDoubleSize)); |
| 1412 } else { | 1412 } else { |
| 1413 DCHECK(input->IsDoubleStackSlot()); | 1413 DCHECK(input->IsFPStackSlot()); |
| 1414 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 1414 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
| 1415 __ VerifyX87StackDepth(1); | 1415 __ VerifyX87StackDepth(1); |
| 1416 } | 1416 } |
| 1417 __ fstp(0); | 1417 __ fstp(0); |
| 1418 __ fld_d(i.InputOperand(0)); | 1418 __ fld_d(i.InputOperand(0)); |
| 1419 __ sub(esp, Immediate(kDoubleSize)); | 1419 __ sub(esp, Immediate(kDoubleSize)); |
| 1420 __ fstp_s(MemOperand(esp, 0)); | 1420 __ fstp_s(MemOperand(esp, 0)); |
| 1421 __ fld_s(MemOperand(esp, 0)); | 1421 __ fld_s(MemOperand(esp, 0)); |
| 1422 __ add(esp, Immediate(kDoubleSize)); | 1422 __ add(esp, Immediate(kDoubleSize)); |
| 1423 } | 1423 } |
| 1424 break; | 1424 break; |
| 1425 } | 1425 } |
| 1426 case kX87Float64ToUint32: { | 1426 case kX87Float64ToUint32: { |
| 1427 __ push_imm32(-2147483648); | 1427 __ push_imm32(-2147483648); |
| 1428 if (!instr->InputAt(0)->IsDoubleRegister()) { | 1428 if (!instr->InputAt(0)->IsFPRegister()) { |
| 1429 __ fld_d(i.InputOperand(0)); | 1429 __ fld_d(i.InputOperand(0)); |
| 1430 } | 1430 } |
| 1431 __ fild_s(Operand(esp, 0)); | 1431 __ fild_s(Operand(esp, 0)); |
| 1432 __ fld(1); | 1432 __ fld(1); |
| 1433 __ faddp(); | 1433 __ faddp(); |
| 1434 __ TruncateX87TOSToI(i.OutputRegister(0)); | 1434 __ TruncateX87TOSToI(i.OutputRegister(0)); |
| 1435 __ add(esp, Immediate(kInt32Size)); | 1435 __ add(esp, Immediate(kInt32Size)); |
| 1436 __ add(i.OutputRegister(), Immediate(0x80000000)); | 1436 __ add(i.OutputRegister(), Immediate(0x80000000)); |
| 1437 __ fstp(0); | 1437 __ fstp(0); |
| 1438 if (!instr->InputAt(0)->IsDoubleRegister()) { | 1438 if (!instr->InputAt(0)->IsFPRegister()) { |
| 1439 __ fstp(0); | 1439 __ fstp(0); |
| 1440 } | 1440 } |
| 1441 break; | 1441 break; |
| 1442 } | 1442 } |
| 1443 case kX87Float64ExtractHighWord32: { | 1443 case kX87Float64ExtractHighWord32: { |
| 1444 if (instr->InputAt(0)->IsDoubleRegister()) { | 1444 if (instr->InputAt(0)->IsFPRegister()) { |
| 1445 __ sub(esp, Immediate(kDoubleSize)); | 1445 __ sub(esp, Immediate(kDoubleSize)); |
| 1446 __ fst_d(MemOperand(esp, 0)); | 1446 __ fst_d(MemOperand(esp, 0)); |
| 1447 __ mov(i.OutputRegister(), MemOperand(esp, kDoubleSize / 2)); | 1447 __ mov(i.OutputRegister(), MemOperand(esp, kDoubleSize / 2)); |
| 1448 __ add(esp, Immediate(kDoubleSize)); | 1448 __ add(esp, Immediate(kDoubleSize)); |
| 1449 } else { | 1449 } else { |
| 1450 InstructionOperand* input = instr->InputAt(0); | 1450 InstructionOperand* input = instr->InputAt(0); |
| 1451 USE(input); | 1451 USE(input); |
| 1452 DCHECK(input->IsDoubleStackSlot()); | 1452 DCHECK(input->IsFPStackSlot()); |
| 1453 __ mov(i.OutputRegister(), i.InputOperand(0, kDoubleSize / 2)); | 1453 __ mov(i.OutputRegister(), i.InputOperand(0, kDoubleSize / 2)); |
| 1454 } | 1454 } |
| 1455 break; | 1455 break; |
| 1456 } | 1456 } |
| 1457 case kX87Float64ExtractLowWord32: { | 1457 case kX87Float64ExtractLowWord32: { |
| 1458 if (instr->InputAt(0)->IsDoubleRegister()) { | 1458 if (instr->InputAt(0)->IsFPRegister()) { |
| 1459 __ sub(esp, Immediate(kDoubleSize)); | 1459 __ sub(esp, Immediate(kDoubleSize)); |
| 1460 __ fst_d(MemOperand(esp, 0)); | 1460 __ fst_d(MemOperand(esp, 0)); |
| 1461 __ mov(i.OutputRegister(), MemOperand(esp, 0)); | 1461 __ mov(i.OutputRegister(), MemOperand(esp, 0)); |
| 1462 __ add(esp, Immediate(kDoubleSize)); | 1462 __ add(esp, Immediate(kDoubleSize)); |
| 1463 } else { | 1463 } else { |
| 1464 InstructionOperand* input = instr->InputAt(0); | 1464 InstructionOperand* input = instr->InputAt(0); |
| 1465 USE(input); | 1465 USE(input); |
| 1466 DCHECK(input->IsDoubleStackSlot()); | 1466 DCHECK(input->IsFPStackSlot()); |
| 1467 __ mov(i.OutputRegister(), i.InputOperand(0)); | 1467 __ mov(i.OutputRegister(), i.InputOperand(0)); |
| 1468 } | 1468 } |
| 1469 break; | 1469 break; |
| 1470 } | 1470 } |
| 1471 case kX87Float64InsertHighWord32: { | 1471 case kX87Float64InsertHighWord32: { |
| 1472 __ sub(esp, Immediate(kDoubleSize)); | 1472 __ sub(esp, Immediate(kDoubleSize)); |
| 1473 __ fstp_d(MemOperand(esp, 0)); | 1473 __ fstp_d(MemOperand(esp, 0)); |
| 1474 __ mov(MemOperand(esp, kDoubleSize / 2), i.InputRegister(1)); | 1474 __ mov(MemOperand(esp, kDoubleSize / 2), i.InputRegister(1)); |
| 1475 __ fld_d(MemOperand(esp, 0)); | 1475 __ fld_d(MemOperand(esp, 0)); |
| 1476 __ add(esp, Immediate(kDoubleSize)); | 1476 __ add(esp, Immediate(kDoubleSize)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1495 __ lea(esp, Operand(esp, kDoubleSize)); | 1495 __ lea(esp, Operand(esp, kDoubleSize)); |
| 1496 __ X87SetFPUCW(0x037F); | 1496 __ X87SetFPUCW(0x037F); |
| 1497 break; | 1497 break; |
| 1498 } | 1498 } |
| 1499 case kX87Float64Round: { | 1499 case kX87Float64Round: { |
| 1500 RoundingMode mode = | 1500 RoundingMode mode = |
| 1501 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); | 1501 static_cast<RoundingMode>(MiscField::decode(instr->opcode())); |
| 1502 // Set the correct round mode in x87 control register | 1502 // Set the correct round mode in x87 control register |
| 1503 __ X87SetRC((mode << 10)); | 1503 __ X87SetRC((mode << 10)); |
| 1504 | 1504 |
| 1505 if (!instr->InputAt(0)->IsDoubleRegister()) { | 1505 if (!instr->InputAt(0)->IsFPRegister()) { |
| 1506 InstructionOperand* input = instr->InputAt(0); | 1506 InstructionOperand* input = instr->InputAt(0); |
| 1507 USE(input); | 1507 USE(input); |
| 1508 DCHECK(input->IsDoubleStackSlot()); | 1508 DCHECK(input->IsFPStackSlot()); |
| 1509 if (FLAG_debug_code && FLAG_enable_slow_asserts) { | 1509 if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
| 1510 __ VerifyX87StackDepth(1); | 1510 __ VerifyX87StackDepth(1); |
| 1511 } | 1511 } |
| 1512 __ fstp(0); | 1512 __ fstp(0); |
| 1513 __ fld_d(i.InputOperand(0)); | 1513 __ fld_d(i.InputOperand(0)); |
| 1514 } | 1514 } |
| 1515 __ frndint(); | 1515 __ frndint(); |
| 1516 __ X87SetRC(0x0000); | 1516 __ X87SetRC(0x0000); |
| 1517 break; | 1517 break; |
| 1518 } | 1518 } |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1651 __ shl(i.OutputRegister(), 3); | 1651 __ shl(i.OutputRegister(), 3); |
| 1652 } else { | 1652 } else { |
| 1653 __ lea(i.OutputRegister(), i.MemoryOperand()); | 1653 __ lea(i.OutputRegister(), i.MemoryOperand()); |
| 1654 } | 1654 } |
| 1655 } else { | 1655 } else { |
| 1656 __ lea(i.OutputRegister(), i.MemoryOperand()); | 1656 __ lea(i.OutputRegister(), i.MemoryOperand()); |
| 1657 } | 1657 } |
| 1658 break; | 1658 break; |
| 1659 } | 1659 } |
| 1660 case kX87Push: | 1660 case kX87Push: |
| 1661 if (instr->InputAt(0)->IsDoubleRegister()) { | 1661 if (instr->InputAt(0)->IsFPRegister()) { |
| 1662 auto allocated = AllocatedOperand::cast(*instr->InputAt(0)); | 1662 auto allocated = AllocatedOperand::cast(*instr->InputAt(0)); |
| 1663 if (allocated.representation() == MachineRepresentation::kFloat32) { | 1663 if (allocated.representation() == MachineRepresentation::kFloat32) { |
| 1664 __ sub(esp, Immediate(kDoubleSize)); | 1664 __ sub(esp, Immediate(kDoubleSize)); |
| 1665 __ fst_s(Operand(esp, 0)); | 1665 __ fst_s(Operand(esp, 0)); |
| 1666 } else { | 1666 } else { |
| 1667 DCHECK(allocated.representation() == MachineRepresentation::kFloat64); | 1667 DCHECK(allocated.representation() == MachineRepresentation::kFloat64); |
| 1668 __ sub(esp, Immediate(kDoubleSize)); | 1668 __ sub(esp, Immediate(kDoubleSize)); |
| 1669 __ fst_d(Operand(esp, 0)); | 1669 __ fst_d(Operand(esp, 0)); |
| 1670 } | 1670 } |
| 1671 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); | 1671 frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); |
| 1672 } else if (instr->InputAt(0)->IsDoubleStackSlot()) { | 1672 } else if (instr->InputAt(0)->IsFPStackSlot()) { |
| 1673 auto allocated = AllocatedOperand::cast(*instr->InputAt(0)); | 1673 auto allocated = AllocatedOperand::cast(*instr->InputAt(0)); |
| 1674 if (allocated.representation() == MachineRepresentation::kFloat32) { | 1674 if (allocated.representation() == MachineRepresentation::kFloat32) { |
| 1675 __ sub(esp, Immediate(kDoubleSize)); | 1675 __ sub(esp, Immediate(kDoubleSize)); |
| 1676 __ fld_s(i.InputOperand(0)); | 1676 __ fld_s(i.InputOperand(0)); |
| 1677 __ fstp_s(MemOperand(esp, 0)); | 1677 __ fstp_s(MemOperand(esp, 0)); |
| 1678 } else { | 1678 } else { |
| 1679 DCHECK(allocated.representation() == MachineRepresentation::kFloat64); | 1679 DCHECK(allocated.representation() == MachineRepresentation::kFloat64); |
| 1680 __ sub(esp, Immediate(kDoubleSize)); | 1680 __ sub(esp, Immediate(kDoubleSize)); |
| 1681 __ fld_d(i.InputOperand(0)); | 1681 __ fld_d(i.InputOperand(0)); |
| 1682 __ fstp_d(MemOperand(esp, 0)); | 1682 __ fstp_d(MemOperand(esp, 0)); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1712 break; | 1712 break; |
| 1713 } | 1713 } |
| 1714 case kX87Xchgl: { | 1714 case kX87Xchgl: { |
| 1715 size_t index = 0; | 1715 size_t index = 0; |
| 1716 Operand operand = i.MemoryOperand(&index); | 1716 Operand operand = i.MemoryOperand(&index); |
| 1717 __ xchg(i.InputRegister(index), operand); | 1717 __ xchg(i.InputRegister(index), operand); |
| 1718 break; | 1718 break; |
| 1719 } | 1719 } |
| 1720 case kX87PushFloat32: | 1720 case kX87PushFloat32: |
| 1721 __ lea(esp, Operand(esp, -kFloatSize)); | 1721 __ lea(esp, Operand(esp, -kFloatSize)); |
| 1722 if (instr->InputAt(0)->IsDoubleStackSlot()) { | 1722 if (instr->InputAt(0)->IsFPStackSlot()) { |
| 1723 __ fld_s(i.InputOperand(0)); | 1723 __ fld_s(i.InputOperand(0)); |
| 1724 __ fstp_s(MemOperand(esp, 0)); | 1724 __ fstp_s(MemOperand(esp, 0)); |
| 1725 } else if (instr->InputAt(0)->IsDoubleRegister()) { | 1725 } else if (instr->InputAt(0)->IsFPRegister()) { |
| 1726 __ fst_s(MemOperand(esp, 0)); | 1726 __ fst_s(MemOperand(esp, 0)); |
| 1727 } else { | 1727 } else { |
| 1728 UNREACHABLE(); | 1728 UNREACHABLE(); |
| 1729 } | 1729 } |
| 1730 break; | 1730 break; |
| 1731 case kX87PushFloat64: | 1731 case kX87PushFloat64: |
| 1732 __ lea(esp, Operand(esp, -kDoubleSize)); | 1732 __ lea(esp, Operand(esp, -kDoubleSize)); |
| 1733 if (instr->InputAt(0)->IsDoubleStackSlot()) { | 1733 if (instr->InputAt(0)->IsFPStackSlot()) { |
| 1734 __ fld_d(i.InputOperand(0)); | 1734 __ fld_d(i.InputOperand(0)); |
| 1735 __ fstp_d(MemOperand(esp, 0)); | 1735 __ fstp_d(MemOperand(esp, 0)); |
| 1736 } else if (instr->InputAt(0)->IsDoubleRegister()) { | 1736 } else if (instr->InputAt(0)->IsFPRegister()) { |
| 1737 __ fst_d(MemOperand(esp, 0)); | 1737 __ fst_d(MemOperand(esp, 0)); |
| 1738 } else { | 1738 } else { |
| 1739 UNREACHABLE(); | 1739 UNREACHABLE(); |
| 1740 } | 1740 } |
| 1741 break; | 1741 break; |
| 1742 case kCheckedLoadInt8: | 1742 case kCheckedLoadInt8: |
| 1743 ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_b); | 1743 ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_b); |
| 1744 break; | 1744 break; |
| 1745 case kCheckedLoadUint8: | 1745 case kCheckedLoadUint8: |
| 1746 ASSEMBLE_CHECKED_LOAD_INTEGER(movzx_b); | 1746 ASSEMBLE_CHECKED_LOAD_INTEGER(movzx_b); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1865 // Add a jump if not falling through to the next block. | 1865 // Add a jump if not falling through to the next block. |
| 1866 if (!branch->fallthru) __ jmp(flabel); | 1866 if (!branch->fallthru) __ jmp(flabel); |
| 1867 | 1867 |
| 1868 __ jmp(&done); | 1868 __ jmp(&done); |
| 1869 __ bind(&tlabel_tmp); | 1869 __ bind(&tlabel_tmp); |
| 1870 FlagsMode mode = FlagsModeField::decode(instr->opcode()); | 1870 FlagsMode mode = FlagsModeField::decode(instr->opcode()); |
| 1871 if (mode == kFlags_deoptimize) { | 1871 if (mode == kFlags_deoptimize) { |
| 1872 int double_register_param_count = 0; | 1872 int double_register_param_count = 0; |
| 1873 int x87_layout = 0; | 1873 int x87_layout = 0; |
| 1874 for (size_t i = 0; i < instr->InputCount(); i++) { | 1874 for (size_t i = 0; i < instr->InputCount(); i++) { |
| 1875 if (instr->InputAt(i)->IsDoubleRegister()) { | 1875 if (instr->InputAt(i)->IsFPRegister()) { |
| 1876 double_register_param_count++; | 1876 double_register_param_count++; |
| 1877 } | 1877 } |
| 1878 } | 1878 } |
| 1879 // Currently we use only one X87 register. If double_register_param_count | 1879 // Currently we use only one X87 register. If double_register_param_count |
| 1880 // is bigger than 1, it means duplicated double register is added to input | 1880 // is bigger than 1, it means duplicated double register is added to input |
| 1881 // of this instruction. | 1881 // of this instruction. |
| 1882 if (double_register_param_count > 0) { | 1882 if (double_register_param_count > 0) { |
| 1883 x87_layout = (0 << 3) | 1; | 1883 x87_layout = (0 << 3) | 1; |
| 1884 } | 1884 } |
| 1885 // The layout of x87 register stack is loaded on the top of FPU register | 1885 // The layout of x87 register stack is loaded on the top of FPU register |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2310 } | 2310 } |
| 2311 } else if (destination->IsRegister()) { | 2311 } else if (destination->IsRegister()) { |
| 2312 Register dst = g.ToRegister(destination); | 2312 Register dst = g.ToRegister(destination); |
| 2313 __ Move(dst, g.ToImmediate(source)); | 2313 __ Move(dst, g.ToImmediate(source)); |
| 2314 } else if (destination->IsStackSlot()) { | 2314 } else if (destination->IsStackSlot()) { |
| 2315 Operand dst = g.ToOperand(destination); | 2315 Operand dst = g.ToOperand(destination); |
| 2316 __ Move(dst, g.ToImmediate(source)); | 2316 __ Move(dst, g.ToImmediate(source)); |
| 2317 } else if (src_constant.type() == Constant::kFloat32) { | 2317 } else if (src_constant.type() == Constant::kFloat32) { |
| 2318 // TODO(turbofan): Can we do better here? | 2318 // TODO(turbofan): Can we do better here? |
| 2319 uint32_t src = bit_cast<uint32_t>(src_constant.ToFloat32()); | 2319 uint32_t src = bit_cast<uint32_t>(src_constant.ToFloat32()); |
| 2320 if (destination->IsDoubleRegister()) { | 2320 if (destination->IsFPRegister()) { |
| 2321 __ sub(esp, Immediate(kInt32Size)); | 2321 __ sub(esp, Immediate(kInt32Size)); |
| 2322 __ mov(MemOperand(esp, 0), Immediate(src)); | 2322 __ mov(MemOperand(esp, 0), Immediate(src)); |
| 2323 // always only push one value into the x87 stack. | 2323 // always only push one value into the x87 stack. |
| 2324 __ fstp(0); | 2324 __ fstp(0); |
| 2325 __ fld_s(MemOperand(esp, 0)); | 2325 __ fld_s(MemOperand(esp, 0)); |
| 2326 __ add(esp, Immediate(kInt32Size)); | 2326 __ add(esp, Immediate(kInt32Size)); |
| 2327 } else { | 2327 } else { |
| 2328 DCHECK(destination->IsDoubleStackSlot()); | 2328 DCHECK(destination->IsFPStackSlot()); |
| 2329 Operand dst = g.ToOperand(destination); | 2329 Operand dst = g.ToOperand(destination); |
| 2330 __ Move(dst, Immediate(src)); | 2330 __ Move(dst, Immediate(src)); |
| 2331 } | 2331 } |
| 2332 } else { | 2332 } else { |
| 2333 DCHECK_EQ(Constant::kFloat64, src_constant.type()); | 2333 DCHECK_EQ(Constant::kFloat64, src_constant.type()); |
| 2334 uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64()); | 2334 uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64()); |
| 2335 uint32_t lower = static_cast<uint32_t>(src); | 2335 uint32_t lower = static_cast<uint32_t>(src); |
| 2336 uint32_t upper = static_cast<uint32_t>(src >> 32); | 2336 uint32_t upper = static_cast<uint32_t>(src >> 32); |
| 2337 if (destination->IsDoubleRegister()) { | 2337 if (destination->IsFPRegister()) { |
| 2338 __ sub(esp, Immediate(kDoubleSize)); | 2338 __ sub(esp, Immediate(kDoubleSize)); |
| 2339 __ mov(MemOperand(esp, 0), Immediate(lower)); | 2339 __ mov(MemOperand(esp, 0), Immediate(lower)); |
| 2340 __ mov(MemOperand(esp, kInt32Size), Immediate(upper)); | 2340 __ mov(MemOperand(esp, kInt32Size), Immediate(upper)); |
| 2341 // always only push one value into the x87 stack. | 2341 // always only push one value into the x87 stack. |
| 2342 __ fstp(0); | 2342 __ fstp(0); |
| 2343 __ fld_d(MemOperand(esp, 0)); | 2343 __ fld_d(MemOperand(esp, 0)); |
| 2344 __ add(esp, Immediate(kDoubleSize)); | 2344 __ add(esp, Immediate(kDoubleSize)); |
| 2345 } else { | 2345 } else { |
| 2346 DCHECK(destination->IsDoubleStackSlot()); | 2346 DCHECK(destination->IsFPStackSlot()); |
| 2347 Operand dst0 = g.ToOperand(destination); | 2347 Operand dst0 = g.ToOperand(destination); |
| 2348 Operand dst1 = g.HighOperand(destination); | 2348 Operand dst1 = g.HighOperand(destination); |
| 2349 __ Move(dst0, Immediate(lower)); | 2349 __ Move(dst0, Immediate(lower)); |
| 2350 __ Move(dst1, Immediate(upper)); | 2350 __ Move(dst1, Immediate(upper)); |
| 2351 } | 2351 } |
| 2352 } | 2352 } |
| 2353 } else if (source->IsDoubleRegister()) { | 2353 } else if (source->IsFPRegister()) { |
| 2354 DCHECK(destination->IsDoubleStackSlot()); | 2354 DCHECK(destination->IsFPStackSlot()); |
| 2355 Operand dst = g.ToOperand(destination); | 2355 Operand dst = g.ToOperand(destination); |
| 2356 auto allocated = AllocatedOperand::cast(*source); | 2356 auto allocated = AllocatedOperand::cast(*source); |
| 2357 switch (allocated.representation()) { | 2357 switch (allocated.representation()) { |
| 2358 case MachineRepresentation::kFloat32: | 2358 case MachineRepresentation::kFloat32: |
| 2359 __ fst_s(dst); | 2359 __ fst_s(dst); |
| 2360 break; | 2360 break; |
| 2361 case MachineRepresentation::kFloat64: | 2361 case MachineRepresentation::kFloat64: |
| 2362 __ fst_d(dst); | 2362 __ fst_d(dst); |
| 2363 break; | 2363 break; |
| 2364 default: | 2364 default: |
| 2365 UNREACHABLE(); | 2365 UNREACHABLE(); |
| 2366 } | 2366 } |
| 2367 } else if (source->IsDoubleStackSlot()) { | 2367 } else if (source->IsFPStackSlot()) { |
| 2368 DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot()); | 2368 DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot()); |
| 2369 Operand src = g.ToOperand(source); | 2369 Operand src = g.ToOperand(source); |
| 2370 auto allocated = AllocatedOperand::cast(*source); | 2370 auto allocated = AllocatedOperand::cast(*source); |
| 2371 if (destination->IsDoubleRegister()) { | 2371 if (destination->IsFPRegister()) { |
| 2372 // always only push one value into the x87 stack. | 2372 // always only push one value into the x87 stack. |
| 2373 __ fstp(0); | 2373 __ fstp(0); |
| 2374 switch (allocated.representation()) { | 2374 switch (allocated.representation()) { |
| 2375 case MachineRepresentation::kFloat32: | 2375 case MachineRepresentation::kFloat32: |
| 2376 __ fld_s(src); | 2376 __ fld_s(src); |
| 2377 break; | 2377 break; |
| 2378 case MachineRepresentation::kFloat64: | 2378 case MachineRepresentation::kFloat64: |
| 2379 __ fld_d(src); | 2379 __ fld_d(src); |
| 2380 break; | 2380 break; |
| 2381 default: | 2381 default: |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2420 Operand dst1 = g.ToOperand(destination); | 2420 Operand dst1 = g.ToOperand(destination); |
| 2421 __ push(dst1); | 2421 __ push(dst1); |
| 2422 frame_access_state()->IncreaseSPDelta(1); | 2422 frame_access_state()->IncreaseSPDelta(1); |
| 2423 Operand src1 = g.ToOperand(source); | 2423 Operand src1 = g.ToOperand(source); |
| 2424 __ push(src1); | 2424 __ push(src1); |
| 2425 Operand dst2 = g.ToOperand(destination); | 2425 Operand dst2 = g.ToOperand(destination); |
| 2426 __ pop(dst2); | 2426 __ pop(dst2); |
| 2427 frame_access_state()->IncreaseSPDelta(-1); | 2427 frame_access_state()->IncreaseSPDelta(-1); |
| 2428 Operand src2 = g.ToOperand(source); | 2428 Operand src2 = g.ToOperand(source); |
| 2429 __ pop(src2); | 2429 __ pop(src2); |
| 2430 } else if (source->IsDoubleRegister() && destination->IsDoubleRegister()) { | 2430 } else if (source->IsFPRegister() && destination->IsFPRegister()) { |
| 2431 UNREACHABLE(); | 2431 UNREACHABLE(); |
| 2432 } else if (source->IsDoubleRegister() && destination->IsDoubleStackSlot()) { | 2432 } else if (source->IsFPRegister() && destination->IsFPStackSlot()) { |
| 2433 auto allocated = AllocatedOperand::cast(*source); | 2433 auto allocated = AllocatedOperand::cast(*source); |
| 2434 switch (allocated.representation()) { | 2434 switch (allocated.representation()) { |
| 2435 case MachineRepresentation::kFloat32: | 2435 case MachineRepresentation::kFloat32: |
| 2436 __ fld_s(g.ToOperand(destination)); | 2436 __ fld_s(g.ToOperand(destination)); |
| 2437 __ fxch(); | 2437 __ fxch(); |
| 2438 __ fstp_s(g.ToOperand(destination)); | 2438 __ fstp_s(g.ToOperand(destination)); |
| 2439 break; | 2439 break; |
| 2440 case MachineRepresentation::kFloat64: | 2440 case MachineRepresentation::kFloat64: |
| 2441 __ fld_d(g.ToOperand(destination)); | 2441 __ fld_d(g.ToOperand(destination)); |
| 2442 __ fxch(); | 2442 __ fxch(); |
| 2443 __ fstp_d(g.ToOperand(destination)); | 2443 __ fstp_d(g.ToOperand(destination)); |
| 2444 break; | 2444 break; |
| 2445 default: | 2445 default: |
| 2446 UNREACHABLE(); | 2446 UNREACHABLE(); |
| 2447 } | 2447 } |
| 2448 } else if (source->IsDoubleStackSlot() && destination->IsDoubleStackSlot()) { | 2448 } else if (source->IsFPStackSlot() && destination->IsFPStackSlot()) { |
| 2449 auto allocated = AllocatedOperand::cast(*source); | 2449 auto allocated = AllocatedOperand::cast(*source); |
| 2450 switch (allocated.representation()) { | 2450 switch (allocated.representation()) { |
| 2451 case MachineRepresentation::kFloat32: | 2451 case MachineRepresentation::kFloat32: |
| 2452 __ fld_s(g.ToOperand(source)); | 2452 __ fld_s(g.ToOperand(source)); |
| 2453 __ fld_s(g.ToOperand(destination)); | 2453 __ fld_s(g.ToOperand(destination)); |
| 2454 __ fstp_s(g.ToOperand(source)); | 2454 __ fstp_s(g.ToOperand(source)); |
| 2455 __ fstp_s(g.ToOperand(destination)); | 2455 __ fstp_s(g.ToOperand(destination)); |
| 2456 break; | 2456 break; |
| 2457 case MachineRepresentation::kFloat64: | 2457 case MachineRepresentation::kFloat64: |
| 2458 __ fld_d(g.ToOperand(source)); | 2458 __ fld_d(g.ToOperand(source)); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2490 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2490 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
| 2491 __ Nop(padding_size); | 2491 __ Nop(padding_size); |
| 2492 } | 2492 } |
| 2493 } | 2493 } |
| 2494 | 2494 |
| 2495 #undef __ | 2495 #undef __ |
| 2496 | 2496 |
| 2497 } // namespace compiler | 2497 } // namespace compiler |
| 2498 } // namespace internal | 2498 } // namespace internal |
| 2499 } // namespace v8 | 2499 } // namespace v8 |
| OLD | NEW |