summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/mips64/code-generator-mips64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/mips64/code-generator-mips64.cc')
-rw-r--r--deps/v8/src/compiler/mips64/code-generator-mips64.cc234
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;