diff options
Diffstat (limited to 'deps/v8/src/compiler/mips64/code-generator-mips64.cc')
-rw-r--r-- | deps/v8/src/compiler/mips64/code-generator-mips64.cc | 234 |
1 files changed, 187 insertions, 47 deletions
diff --git a/deps/v8/src/compiler/mips64/code-generator-mips64.cc b/deps/v8/src/compiler/mips64/code-generator-mips64.cc index 053434eec9..62fd2f5efc 100644 --- a/deps/v8/src/compiler/mips64/code-generator-mips64.cc +++ b/deps/v8/src/compiler/mips64/code-generator-mips64.cc @@ -53,6 +53,18 @@ class MipsOperandConverter final : public InstructionOperandConverter { return ToDoubleRegister(op); } + DoubleRegister InputOrZeroDoubleRegister(size_t index) { + if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero; + + return InputDoubleRegister(index); + } + + DoubleRegister InputOrZeroSingleRegister(size_t index) { + if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero; + + return InputSingleRegister(index); + } + Operand InputImmediate(size_t index) { Constant constant = ToConstant(instr_->InputAt(index)); switch (constant.type()) { @@ -201,6 +213,48 @@ class OutOfLineCeil final : public OutOfLineRound { }; +class OutOfLineRecordWrite final : public OutOfLineCode { + public: + OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register index, + Register value, Register scratch0, Register scratch1, + RecordWriteMode mode) + : OutOfLineCode(gen), + object_(object), + index_(index), + value_(value), + scratch0_(scratch0), + scratch1_(scratch1), + mode_(mode) {} + + void Generate() final { + if (mode_ > RecordWriteMode::kValueIsPointer) { + __ JumpIfSmi(value_, exit()); + } + if (mode_ > RecordWriteMode::kValueIsMap) { + __ CheckPageFlag(value_, scratch0_, + MemoryChunk::kPointersToHereAreInterestingMask, eq, + exit()); + } + SaveFPRegsMode const save_fp_mode = + frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; + // TODO(turbofan): Once we get frame elision working, we need to save + // and restore lr properly here if the frame was elided. + RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, + EMIT_REMEMBERED_SET, save_fp_mode); + __ Daddu(scratch1_, object_, index_); + __ CallStub(&stub); + } + + private: + Register const object_; + Register const index_; + Register const value_; + Register const scratch0_; + Register const scratch1_; + RecordWriteMode const mode_; +}; + + Condition FlagsConditionToConditionCmp(FlagsCondition condition) { switch (condition) { case kEqual: @@ -455,6 +509,11 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ Jump(at); break; } + case kArchLazyBailout: { + EnsureSpaceForLazyDeopt(); + RecordCallPosition(instr); + break; + } case kArchPrepareCallCFunction: { int const num_parameters = MiscField::decode(instr->opcode()); __ PrepareCallCFunction(num_parameters, kScratchReg); @@ -501,6 +560,24 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { case kArchTruncateDoubleToI: __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); break; + case kArchStoreWithWriteBarrier: { + RecordWriteMode mode = + static_cast<RecordWriteMode>(MiscField::decode(instr->opcode())); + Register object = i.InputRegister(0); + Register index = i.InputRegister(1); + Register value = i.InputRegister(2); + Register scratch0 = i.TempRegister(0); + Register scratch1 = i.TempRegister(1); + auto ool = new (zone()) OutOfLineRecordWrite(this, object, index, value, + scratch0, scratch1, mode); + __ Daddu(at, object, index); + __ sd(value, MemOperand(at)); + __ CheckPageFlag(object, scratch0, + MemoryChunk::kPointersFromHereAreInterestingMask, ne, + ool->entry()); + __ bind(ool->exit()); + break; + } case kMips64Add: __ Addu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); break; @@ -561,6 +638,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { case kMips64Clz: __ Clz(i.OutputRegister(), i.InputRegister(0)); break; + case kMips64Dclz: + __ dclz(i.OutputRegister(), i.InputRegister(0)); + break; case kMips64Shl: if (instr->InputAt(1)->IsRegister()) { __ sllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); @@ -769,6 +849,62 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d, Ceil); break; } + case kMips64Float64Max: { + // (b < a) ? a : b + if (kArchVariant == kMips64r6) { + __ cmp_d(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(1), + i.InputDoubleRegister(0)); + __ sel_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1), + i.InputDoubleRegister(0)); + } else { + __ c_d(OLT, i.InputDoubleRegister(0), i.InputDoubleRegister(1)); + // Left operand is result, passthrough if false. + __ movt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); + } + break; + } + case kMips64Float64Min: { + // (a < b) ? a : b + if (kArchVariant == kMips64r6) { + __ cmp_d(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(0), + i.InputDoubleRegister(1)); + __ sel_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1), + i.InputDoubleRegister(0)); + } else { + __ c_d(OLT, i.InputDoubleRegister(1), i.InputDoubleRegister(0)); + // Right operand is result, passthrough if false. + __ movt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); + } + break; + } + case kMips64Float32Max: { + // (b < a) ? a : b + if (kArchVariant == kMips64r6) { + __ cmp_s(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(1), + i.InputDoubleRegister(0)); + __ sel_s(i.OutputDoubleRegister(), i.InputDoubleRegister(1), + i.InputDoubleRegister(0)); + } else { + __ c_s(OLT, i.InputDoubleRegister(0), i.InputDoubleRegister(1)); + // Left operand is result, passthrough if false. + __ movt_s(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); + } + break; + } + case kMips64Float32Min: { + // (a < b) ? a : b + if (kArchVariant == kMips64r6) { + __ cmp_s(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(0), + i.InputDoubleRegister(1)); + __ sel_s(i.OutputDoubleRegister(), i.InputDoubleRegister(1), + i.InputDoubleRegister(0)); + } else { + __ c_s(OLT, i.InputDoubleRegister(1), i.InputDoubleRegister(0)); + // Right operand is result, passthrough if false. + __ movt_s(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); + } + break; + } case kMips64CvtSD: __ cvt_s_d(i.OutputSingleRegister(), i.InputDoubleRegister(0)); break; @@ -781,6 +917,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ cvt_d_w(i.OutputDoubleRegister(), scratch); break; } + case kMips64CvtSL: { + FPURegister scratch = kScratchDoubleReg; + __ dmtc1(i.InputRegister(0), scratch); + __ cvt_s_l(i.OutputDoubleRegister(), scratch); + break; + } + case kMips64CvtDL: { + FPURegister scratch = kScratchDoubleReg; + __ dmtc1(i.InputRegister(0), scratch); + __ cvt_d_l(i.OutputDoubleRegister(), scratch); + break; + } case kMips64CvtDUw: { FPURegister scratch = kScratchDoubleReg; __ Cvt_d_uw(i.OutputDoubleRegister(), i.InputRegister(0), scratch); @@ -885,18 +1033,6 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { } break; } - case kMips64StoreWriteBarrier: { - Register object = i.InputRegister(0); - Register index = i.InputRegister(1); - Register value = i.InputRegister(2); - __ daddu(index, object, index); - __ sd(value, MemOperand(index)); - SaveFPRegsMode mode = - frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; - RAStatus ra_status = kRAHasNotBeenSaved; - __ RecordWrite(object, index, value, ra_status, mode); - break; - } case kCheckedLoadInt8: ASSEMBLE_CHECKED_LOAD_INTEGER(lb); break; @@ -1005,14 +1141,24 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { if (!convertCondition(branch->condition, cc)) { UNSUPPORTED_COND(kMips64CmpS, branch->condition); } - __ BranchF32(tlabel, NULL, cc, i.InputSingleRegister(0), - i.InputSingleRegister(1)); + FPURegister left = i.InputOrZeroSingleRegister(0); + FPURegister right = i.InputOrZeroSingleRegister(1); + if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) && + !__ IsDoubleZeroRegSet()) { + __ Move(kDoubleRegZero, 0.0); + } + __ BranchF32(tlabel, NULL, cc, left, right); } else if (instr->arch_opcode() == kMips64CmpD) { if (!convertCondition(branch->condition, cc)) { UNSUPPORTED_COND(kMips64CmpD, branch->condition); } - __ BranchF64(tlabel, NULL, cc, i.InputDoubleRegister(0), - i.InputDoubleRegister(1)); + FPURegister left = i.InputOrZeroDoubleRegister(0); + FPURegister right = i.InputOrZeroDoubleRegister(1); + if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) && + !__ IsDoubleZeroRegSet()) { + __ Move(kDoubleRegZero, 0.0); + } + __ BranchF64(tlabel, NULL, cc, left, right); } else { PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n", instr->arch_opcode()); @@ -1046,19 +1192,10 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, if (instr->arch_opcode() == kMips64Tst) { cc = FlagsConditionToConditionTst(condition); __ And(kScratchReg, i.InputRegister(0), i.InputOperand(1)); - __ xori(result, zero_reg, 1); // Create 1 for true. - if (kArchVariant == kMips64r6) { - if (cc == eq) { - __ seleqz(result, result, kScratchReg); - } else { - __ selnez(result, result, kScratchReg); - } - } else { - if (cc == eq) { - __ Movn(result, zero_reg, kScratchReg); - } else { - __ Movz(result, zero_reg, kScratchReg); - } + __ Sltu(result, zero_reg, kScratchReg); + if (cc == eq) { + // Sltu produces 0 for equality, invert the result. + __ xori(result, result, 1); } return; } else if (instr->arch_opcode() == kMips64Dadd || @@ -1078,20 +1215,18 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, case ne: { Register left = i.InputRegister(0); Operand right = i.InputOperand(1); - __ Dsubu(kScratchReg, left, right); - __ xori(result, zero_reg, 1); - if (kArchVariant == kMips64r6) { - if (cc == eq) { - __ seleqz(result, result, kScratchReg); - } else { - __ selnez(result, result, kScratchReg); - } + Register select; + if (instr->InputAt(1)->IsImmediate() && right.immediate() == 0) { + // Pass left operand if right is zero. + select = left; } else { - if (cc == eq) { - __ Movn(result, zero_reg, kScratchReg); - } else { - __ Movz(result, zero_reg, kScratchReg); - } + __ Dsubu(kScratchReg, left, right); + select = kScratchReg; + } + __ Sltu(result, zero_reg, select); + if (cc == eq) { + // Sltu produces 0 for equality, invert the result. + __ xori(result, result, 1); } } break; case lt: @@ -1136,8 +1271,12 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, return; } else if (instr->arch_opcode() == kMips64CmpD || instr->arch_opcode() == kMips64CmpS) { - FPURegister left = i.InputDoubleRegister(0); - FPURegister right = i.InputDoubleRegister(1); + FPURegister left = i.InputOrZeroDoubleRegister(0); + FPURegister right = i.InputOrZeroDoubleRegister(1); + if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) && + !__ IsDoubleZeroRegSet()) { + __ Move(kDoubleRegZero, 0.0); + } bool predicate; FPUCondition cc = FlagsConditionToConditionCmpFPU(predicate, condition); if (kArchVariant != kMips64r6) { @@ -1160,9 +1299,10 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, DCHECK(instr->arch_opcode() == kMips64CmpS); __ cmp(cc, W, kDoubleCompareReg, left, right); } - __ dmfc1(at, kDoubleCompareReg); - __ dsrl32(result, at, 31); // Cmp returns all 1s for true. - if (!predicate) // Toggle result for not equal. + __ dmfc1(result, kDoubleCompareReg); + __ andi(result, result, 1); // Cmp returns all 1's/0's, use only LSB. + + if (!predicate) // Toggle result for not equal. __ xori(result, result, 1); } return; |