Chromium Code Reviews| Index: src/compiler/mips/code-generator-mips.cc |
| diff --git a/src/compiler/mips/code-generator-mips.cc b/src/compiler/mips/code-generator-mips.cc |
| index 93fe36d8308442aa3c4bd1a2c5d26a4cd857e8be..859f839f8b29c67d15729f2bc53a0408c609814f 100644 |
| --- a/src/compiler/mips/code-generator-mips.cc |
| +++ b/src/compiler/mips/code-generator-mips.cc |
| @@ -1628,12 +1628,9 @@ static bool convertCondition(FlagsCondition condition, Condition& cc) { |
| return false; |
| } |
| - |
| -// 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; |
| +void AssembleBranchToLabels(CodeGenerator* gen, MacroAssembler* masm, |
|
titzer
2017/01/11 09:53:32
Is it possible to either redefine the __ macro or
ahaas
2017/01/11 14:05:36
Done.
|
| + Instruction* instr, FlagsCondition condition, |
| + Label* tlabel, Label* flabel, bool fallthru) { |
| 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 |
| @@ -1642,83 +1639,92 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
| // registers to compare pseudo-op are not modified before this branch op, as |
| // they are tested here. |
| + MipsOperandConverter i(gen, instr); |
| if (instr->arch_opcode() == kMipsTst) { |
| - cc = FlagsConditionToConditionTst(branch->condition); |
| - __ And(at, i.InputRegister(0), i.InputOperand(1)); |
| - __ Branch(tlabel, cc, at, Operand(zero_reg)); |
| + cc = FlagsConditionToConditionTst(condition); |
| + masm->And(at, i.InputRegister(0), i.InputOperand(1)); |
| + masm->Branch(tlabel, cc, at, Operand(zero_reg)); |
| } else if (instr->arch_opcode() == kMipsAddOvf) { |
| - switch (branch->condition) { |
| + switch (condition) { |
| case kOverflow: |
| - __ AddBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| - i.InputOperand(1), tlabel, flabel); |
| + masm->AddBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| + i.InputOperand(1), tlabel, flabel); |
| break; |
| case kNotOverflow: |
| - __ AddBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| - i.InputOperand(1), flabel, tlabel); |
| + masm->AddBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| + i.InputOperand(1), flabel, tlabel); |
| break; |
| default: |
| - UNSUPPORTED_COND(kMipsAddOvf, branch->condition); |
| + UNSUPPORTED_COND(kMipsAddOvf, condition); |
| break; |
| } |
| } else if (instr->arch_opcode() == kMipsSubOvf) { |
| - switch (branch->condition) { |
| + switch (condition) { |
| case kOverflow: |
| - __ SubBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| - i.InputOperand(1), tlabel, flabel); |
| + masm->SubBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| + i.InputOperand(1), tlabel, flabel); |
| break; |
| case kNotOverflow: |
| - __ SubBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| - i.InputOperand(1), flabel, tlabel); |
| + masm->SubBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| + i.InputOperand(1), flabel, tlabel); |
| break; |
| default: |
| - UNSUPPORTED_COND(kMipsAddOvf, branch->condition); |
| + UNSUPPORTED_COND(kMipsAddOvf, condition); |
| break; |
| } |
| } else if (instr->arch_opcode() == kMipsMulOvf) { |
| - switch (branch->condition) { |
| + switch (condition) { |
| case kOverflow: |
| - __ MulBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| - i.InputOperand(1), tlabel, flabel); |
| + masm->MulBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| + i.InputOperand(1), tlabel, flabel); |
| break; |
| case kNotOverflow: |
| - __ MulBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| - i.InputOperand(1), flabel, tlabel); |
| + masm->MulBranchOvf(i.OutputRegister(), i.InputRegister(0), |
| + i.InputOperand(1), flabel, tlabel); |
| break; |
| default: |
| - UNSUPPORTED_COND(kMipsMulOvf, branch->condition); |
| + UNSUPPORTED_COND(kMipsMulOvf, condition); |
| break; |
| } |
| } else if (instr->arch_opcode() == kMipsCmp) { |
| - cc = FlagsConditionToConditionCmp(branch->condition); |
| - __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); |
| + cc = FlagsConditionToConditionCmp(condition); |
| + masm->Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); |
| } else if (instr->arch_opcode() == kMipsCmpS) { |
| - 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); |
| if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) && |
| - !__ IsDoubleZeroRegSet()) { |
| - __ Move(kDoubleRegZero, 0.0); |
| + !masm->IsDoubleZeroRegSet()) { |
| + masm->Move(kDoubleRegZero, 0.0); |
| } |
| - __ BranchF32(tlabel, nullptr, cc, left, right); |
| + masm->BranchF32(tlabel, nullptr, cc, left, right); |
| } else if (instr->arch_opcode() == kMipsCmpD) { |
| - 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); |
| if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) && |
| - !__ IsDoubleZeroRegSet()) { |
| - __ Move(kDoubleRegZero, 0.0); |
| + !masm->IsDoubleZeroRegSet()) { |
| + masm->Move(kDoubleRegZero, 0.0); |
| } |
| - __ BranchF64(tlabel, nullptr, cc, left, right); |
| + masm->BranchF64(tlabel, nullptr, cc, left, right); |
| } else { |
| PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n", |
| instr->arch_opcode()); |
| UNIMPLEMENTED(); |
| } |
| - if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. |
| + if (!fallthru) masm->Branch(flabel); // no fallthru to flabel. |
| +} |
| + |
| +// 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); |
| } |
| @@ -1728,7 +1734,63 @@ 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); |
| + } |
| + 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. |