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.cc164
1 files changed, 120 insertions, 44 deletions
diff --git a/deps/v8/src/compiler/mips64/code-generator-mips64.cc b/deps/v8/src/compiler/mips64/code-generator-mips64.cc
index c72d9789b8..053434eec9 100644
--- a/deps/v8/src/compiler/mips64/code-generator-mips64.cc
+++ b/deps/v8/src/compiler/mips64/code-generator-mips64.cc
@@ -305,8 +305,8 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
if (instr->InputAt(0)->IsRegister()) { \
auto offset = i.InputRegister(0); \
__ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
- __ Daddu(at, i.InputRegister(2), offset); \
- __ asm_instr(result, MemOperand(at, 0)); \
+ __ Daddu(kScratchReg, i.InputRegister(2), offset); \
+ __ asm_instr(result, MemOperand(kScratchReg, 0)); \
} else { \
int offset = static_cast<int>(i.InputOperand(0).immediate()); \
__ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \
@@ -323,8 +323,8 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
if (instr->InputAt(0)->IsRegister()) { \
auto offset = i.InputRegister(0); \
__ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
- __ Daddu(at, i.InputRegister(2), offset); \
- __ asm_instr(result, MemOperand(at, 0)); \
+ __ Daddu(kScratchReg, i.InputRegister(2), offset); \
+ __ asm_instr(result, MemOperand(kScratchReg, 0)); \
} else { \
int offset = static_cast<int>(i.InputOperand(0).immediate()); \
__ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \
@@ -341,8 +341,8 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
auto offset = i.InputRegister(0); \
auto value = i.Input##width##Register(2); \
__ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
- __ Daddu(at, i.InputRegister(3), offset); \
- __ asm_instr(value, MemOperand(at, 0)); \
+ __ Daddu(kScratchReg, i.InputRegister(3), offset); \
+ __ asm_instr(value, MemOperand(kScratchReg, 0)); \
} else { \
int offset = static_cast<int>(i.InputOperand(0).immediate()); \
auto value = i.Input##width##Register(2); \
@@ -360,8 +360,8 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
auto offset = i.InputRegister(0); \
auto value = i.InputRegister(2); \
__ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
- __ Daddu(at, i.InputRegister(3), offset); \
- __ asm_instr(value, MemOperand(at, 0)); \
+ __ Daddu(kScratchReg, i.InputRegister(3), offset); \
+ __ asm_instr(value, MemOperand(kScratchReg, 0)); \
} else { \
int offset = static_cast<int>(i.InputOperand(0).immediate()); \
auto value = i.InputRegister(2); \
@@ -799,6 +799,12 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ Trunc_uw_d(i.InputDoubleRegister(0), i.OutputRegister(), scratch);
break;
}
+ case kMips64BitcastDL:
+ __ dmfc1(i.OutputRegister(), i.InputDoubleRegister(0));
+ break;
+ case kMips64BitcastLD:
+ __ dmtc1(i.InputRegister(0), i.OutputDoubleRegister());
+ break;
case kMips64Float64ExtractLowWord32:
__ FmoveLow(i.OutputRegister(), i.InputDoubleRegister(0));
break;
@@ -906,6 +912,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
case kCheckedLoadWord32:
ASSEMBLE_CHECKED_LOAD_INTEGER(lw);
break;
+ case kCheckedLoadWord64:
+ ASSEMBLE_CHECKED_LOAD_INTEGER(ld);
+ break;
case kCheckedLoadFloat32:
ASSEMBLE_CHECKED_LOAD_FLOAT(Single, lwc1);
break;
@@ -921,6 +930,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
case kCheckedStoreWord32:
ASSEMBLE_CHECKED_STORE_INTEGER(sw);
break;
+ case kCheckedStoreWord64:
+ ASSEMBLE_CHECKED_STORE_INTEGER(sd);
+ break;
case kCheckedStoreFloat32:
ASSEMBLE_CHECKED_STORE_FLOAT(Single, swc1);
break;
@@ -969,7 +981,6 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
Label* tlabel = branch->true_label;
Label* flabel = branch->false_label;
Condition cc = kNoCondition;
-
// MIPS does not have condition code flags, so compare and branch are
// implemented differently than on the other arch's. The compare operations
// emit mips psuedo-instructions, which are handled here by branch
@@ -1028,38 +1039,105 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
DCHECK_NE(0u, instr->OutputCount());
Register result = i.OutputRegister(instr->OutputCount() - 1);
Condition cc = kNoCondition;
-
// MIPS does not have condition code flags, so compare and branch are
// implemented differently than on the other arch's. The compare operations
// emit mips pseudo-instructions, which are checked and handled here.
- // For materializations, we use delay slot to set the result true, and
- // in the false case, where we fall through the branch, we reset the result
- // false.
-
if (instr->arch_opcode() == kMips64Tst) {
cc = FlagsConditionToConditionTst(condition);
- __ And(at, i.InputRegister(0), i.InputOperand(1));
- __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg));
- __ li(result, Operand(1)); // In delay slot.
+ __ 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);
+ }
+ }
+ return;
} else if (instr->arch_opcode() == kMips64Dadd ||
instr->arch_opcode() == kMips64Dsub) {
cc = FlagsConditionToConditionOvf(condition);
- __ dsra32(kScratchReg, i.OutputRegister(), 0);
- __ sra(at, i.OutputRegister(), 31);
- __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(kScratchReg));
- __ li(result, Operand(1)); // In delay slot.
+ // Check for overflow creates 1 or 0 for result.
+ __ dsrl32(kScratchReg, i.OutputRegister(), 31);
+ __ srl(at, i.OutputRegister(), 31);
+ __ xor_(result, kScratchReg, at);
+ if (cc == eq) // Toggle result for not overflow.
+ __ xori(result, result, 1);
+ return;
} else if (instr->arch_opcode() == kMips64Cmp) {
- Register left = i.InputRegister(0);
- Operand right = i.InputOperand(1);
cc = FlagsConditionToConditionCmp(condition);
- __ Branch(USE_DELAY_SLOT, &done, cc, left, right);
- __ li(result, Operand(1)); // In delay slot.
+ switch (cc) {
+ case eq:
+ 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);
+ }
+ } else {
+ if (cc == eq) {
+ __ Movn(result, zero_reg, kScratchReg);
+ } else {
+ __ Movz(result, zero_reg, kScratchReg);
+ }
+ }
+ } break;
+ case lt:
+ case ge: {
+ Register left = i.InputRegister(0);
+ Operand right = i.InputOperand(1);
+ __ Slt(result, left, right);
+ if (cc == ge) {
+ __ xori(result, result, 1);
+ }
+ } break;
+ case gt:
+ case le: {
+ Register left = i.InputRegister(1);
+ Operand right = i.InputOperand(0);
+ __ Slt(result, left, right);
+ if (cc == le) {
+ __ xori(result, result, 1);
+ }
+ } break;
+ case lo:
+ case hs: {
+ Register left = i.InputRegister(0);
+ Operand right = i.InputOperand(1);
+ __ Sltu(result, left, right);
+ if (cc == hs) {
+ __ xori(result, result, 1);
+ }
+ } break;
+ case hi:
+ case ls: {
+ Register left = i.InputRegister(1);
+ Operand right = i.InputOperand(0);
+ __ Sltu(result, left, right);
+ if (cc == ls) {
+ __ xori(result, result, 1);
+ }
+ } break;
+ default:
+ UNREACHABLE();
+ }
+ return;
} else if (instr->arch_opcode() == kMips64CmpD ||
instr->arch_opcode() == kMips64CmpS) {
FPURegister left = i.InputDoubleRegister(0);
FPURegister right = i.InputDoubleRegister(1);
-
bool predicate;
FPUCondition cc = FlagsConditionToConditionCmpFPU(predicate, condition);
if (kArchVariant != kMips64r6) {
@@ -1094,10 +1172,6 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
TRACE_UNIMPL();
UNIMPLEMENTED();
}
- // Fallthru case is the false materialization.
- __ bind(&false_value);
- __ li(result, Operand(static_cast<int64_t>(0)));
- __ bind(&done);
}
@@ -1428,21 +1502,23 @@ void CodeGenerator::AddNopForSmiCodeInlining() {
void CodeGenerator::EnsureSpaceForLazyDeopt() {
+ if (!info()->ShouldEnsureSpaceForLazyDeopt()) {
+ return;
+ }
+
int space_needed = Deoptimizer::patch_size();
- if (!info()->IsStub()) {
- // Ensure that we have enough space after the previous lazy-bailout
- // instruction for patching the code here.
- int current_pc = masm()->pc_offset();
- if (current_pc < last_lazy_deopt_pc_ + space_needed) {
- // Block tramoline pool emission for duration of padding.
- v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
- masm());
- int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
- DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
- while (padding_size > 0) {
- __ nop();
- padding_size -= v8::internal::Assembler::kInstrSize;
- }
+ // Ensure that we have enough space after the previous lazy-bailout
+ // instruction for patching the code here.
+ int current_pc = masm()->pc_offset();
+ if (current_pc < last_lazy_deopt_pc_ + space_needed) {
+ // Block tramoline pool emission for duration of padding.
+ v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
+ masm());
+ int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
+ DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
+ while (padding_size > 0) {
+ __ nop();
+ padding_size -= v8::internal::Assembler::kInstrSize;
}
}
}