Index: src/compiler/mips64/code-generator-mips64.cc |
diff --git a/src/compiler/mips64/code-generator-mips64.cc b/src/compiler/mips64/code-generator-mips64.cc |
index 12f7161f98e27cd1d4b2c9f480b9bfb1137535e5..45cf340b65e68ab970eb65a26f2e52d2a4e9cf40 100644 |
--- a/src/compiler/mips64/code-generator-mips64.cc |
+++ b/src/compiler/mips64/code-generator-mips64.cc |
@@ -1935,12 +1935,13 @@ static bool convertCondition(FlagsCondition condition, Condition& cc) { |
return false; |
} |
+void AssembleBranchToLabels(CodeGenerator* gen, MacroAssembler* masm, |
+ Instruction* instr, FlagsCondition condition, |
+ Label* tlabel, Label* flabel, bool fallthru) { |
+#undef __ |
+#define __ masm-> |
+ MipsOperandConverter i(gen, instr); |
-// Assembles branches after an instruction. |
-void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
- MipsOperandConverter i(this, instr); |
- 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 |
@@ -1950,17 +1951,17 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
// they are tested here. |
if (instr->arch_opcode() == kMips64Tst) { |
- cc = FlagsConditionToConditionTst(branch->condition); |
+ cc = FlagsConditionToConditionTst(condition); |
__ And(at, i.InputRegister(0), i.InputOperand(1)); |
__ Branch(tlabel, cc, at, Operand(zero_reg)); |
} else if (instr->arch_opcode() == kMips64Dadd || |
instr->arch_opcode() == kMips64Dsub) { |
- cc = FlagsConditionToConditionOvf(branch->condition); |
+ cc = FlagsConditionToConditionOvf(condition); |
__ dsra32(kScratchReg, i.OutputRegister(), 0); |
__ sra(at, i.OutputRegister(), 31); |
__ Branch(tlabel, cc, at, Operand(kScratchReg)); |
} else if (instr->arch_opcode() == kMips64DaddOvf) { |
- switch (branch->condition) { |
+ switch (condition) { |
case kOverflow: |
__ DaddBranchOvf(i.OutputRegister(), i.InputRegister(0), |
i.InputOperand(1), tlabel, flabel); |
@@ -1970,11 +1971,11 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
i.InputOperand(1), flabel, tlabel); |
break; |
default: |
- UNSUPPORTED_COND(kMips64DaddOvf, branch->condition); |
+ UNSUPPORTED_COND(kMips64DaddOvf, condition); |
break; |
} |
} else if (instr->arch_opcode() == kMips64DsubOvf) { |
- switch (branch->condition) { |
+ switch (condition) { |
case kOverflow: |
__ DsubBranchOvf(i.OutputRegister(), i.InputRegister(0), |
i.InputOperand(1), tlabel, flabel); |
@@ -1984,11 +1985,11 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
i.InputOperand(1), flabel, tlabel); |
break; |
default: |
- UNSUPPORTED_COND(kMips64DsubOvf, branch->condition); |
+ UNSUPPORTED_COND(kMips64DsubOvf, condition); |
break; |
} |
} else if (instr->arch_opcode() == kMips64MulOvf) { |
- switch (branch->condition) { |
+ switch (condition) { |
case kOverflow: { |
__ MulBranchOvf(i.OutputRegister(), i.InputRegister(0), |
i.InputOperand(1), tlabel, flabel, kScratchReg); |
@@ -1998,15 +1999,15 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
i.InputOperand(1), flabel, tlabel, kScratchReg); |
} break; |
default: |
- UNSUPPORTED_COND(kMips64MulOvf, branch->condition); |
+ UNSUPPORTED_COND(kMips64MulOvf, condition); |
break; |
} |
} else if (instr->arch_opcode() == kMips64Cmp) { |
- cc = FlagsConditionToConditionCmp(branch->condition); |
+ cc = FlagsConditionToConditionCmp(condition); |
__ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); |
} else if (instr->arch_opcode() == kMips64CmpS) { |
- if (!convertCondition(branch->condition, cc)) { |
- UNSUPPORTED_COND(kMips64CmpS, branch->condition); |
+ if (!convertCondition(condition, cc)) { |
+ UNSUPPORTED_COND(kMips64CmpS, condition); |
} |
FPURegister left = i.InputOrZeroSingleRegister(0); |
FPURegister right = i.InputOrZeroSingleRegister(1); |
@@ -2016,8 +2017,8 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
} |
__ BranchF32(tlabel, nullptr, cc, left, right); |
} else if (instr->arch_opcode() == kMips64CmpD) { |
- if (!convertCondition(branch->condition, cc)) { |
- UNSUPPORTED_COND(kMips64CmpD, branch->condition); |
+ if (!convertCondition(condition, cc)) { |
+ UNSUPPORTED_COND(kMips64CmpD, condition); |
} |
FPURegister left = i.InputOrZeroDoubleRegister(0); |
FPURegister right = i.InputOrZeroDoubleRegister(1); |
@@ -2031,7 +2032,18 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
instr->arch_opcode()); |
UNIMPLEMENTED(); |
} |
- if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. |
+ if (!fallthru) __ Branch(flabel); // no fallthru to flabel. |
+#undef __ |
+#define __ masm()-> |
+} |
+ |
+// Assembles branches after an instruction. |
+void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
+ Label* tlabel = branch->true_label; |
+ Label* flabel = branch->false_label; |
+ |
+ AssembleBranchToLabels(this, masm(), instr, branch->condition, tlabel, flabel, |
+ branch->fallthru); |
} |
@@ -2041,7 +2053,60 @@ void CodeGenerator::AssembleArchJump(RpoNumber target) { |
void CodeGenerator::AssembleArchTrap(Instruction* instr, |
FlagsCondition condition) { |
- UNREACHABLE(); |
+ class OutOfLineTrap final : public OutOfLineCode { |
+ public: |
+ OutOfLineTrap(CodeGenerator* gen, bool frame_elided, Instruction* instr) |
+ : OutOfLineCode(gen), |
+ frame_elided_(frame_elided), |
+ instr_(instr), |
+ gen_(gen) {} |
+ void Generate() final { |
+ MipsOperandConverter i(gen_, instr_); |
+ Runtime::FunctionId trap_id = static_cast<Runtime::FunctionId>( |
+ i.InputInt32(instr_->InputCount() - 1)); |
+ bool old_has_frame = __ has_frame(); |
+ if (frame_elided_) { |
+ __ set_has_frame(true); |
+ __ EnterFrame(StackFrame::WASM_COMPILED); |
+ } |
+ GenerateCallToTrap(trap_id); |
+ if (frame_elided_) { |
+ __ set_has_frame(old_has_frame); |
+ } |
+ if (FLAG_debug_code) { |
+ __ stop(GetBailoutReason(kUnexpectedReturnFromWasmTrap)); |
+ } |
+ } |
+ |
+ private: |
+ void GenerateCallToTrap(Runtime::FunctionId trap_id) { |
+ if (trap_id == Runtime::kNumFunctions) { |
+ // We cannot test calls to the runtime in cctest/test-run-wasm. |
+ // Therefore we emit a call to C here instead of a call to the runtime. |
+ // We use the context register as the scratch register, because we do |
+ // not have a context here. |
+ __ PrepareCallCFunction(0, 0, cp); |
+ __ CallCFunction( |
+ ExternalReference::wasm_call_trap_callback_for_testing(isolate()), |
+ 0); |
+ } else { |
+ __ Move(cp, isolate()->native_context()); |
+ gen_->AssembleSourcePosition(instr_); |
+ __ CallRuntime(trap_id); |
+ } |
+ ReferenceMap* reference_map = |
+ new (gen_->zone()) ReferenceMap(gen_->zone()); |
+ gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0, |
+ Safepoint::kNoLazyDeopt); |
+ } |
+ bool frame_elided_; |
+ Instruction* instr_; |
+ CodeGenerator* gen_; |
+ }; |
+ bool frame_elided = !frame_access_state()->has_frame(); |
+ auto ool = new (zone()) OutOfLineTrap(this, frame_elided, instr); |
+ Label* tlabel = ool->entry(); |
+ AssembleBranchToLabels(this, masm(), instr, condition, tlabel, nullptr, true); |
} |
// Assembles boolean materializations after an instruction. |