Chromium Code Reviews| Index: src/compiler/x64/code-generator-x64.cc |
| diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc |
| index 0a14781921a660bec6dead9866d0e3e67a7cf326..da4df55875d16bf2d4eb7e5a4be61ee529b814ec 100644 |
| --- a/src/compiler/x64/code-generator-x64.cc |
| +++ b/src/compiler/x64/code-generator-x64.cc |
| @@ -2226,61 +2226,67 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( |
| return kSuccess; |
| } // NOLINT(readability/fn_size) |
| - |
| -// Assembles branches after this instruction. |
| -void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
| - X64OperandConverter i(this, instr); |
| - Label::Distance flabel_distance = |
| - branch->fallthru ? Label::kNear : Label::kFar; |
| - Label* tlabel = branch->true_label; |
| - Label* flabel = branch->false_label; |
| - switch (branch->condition) { |
| +static Condition ToCC(FlagsCondition condition) { |
| + switch (condition) { |
| case kUnorderedEqual: |
| - __ j(parity_even, flabel, flabel_distance); |
| - // Fall through. |
| case kEqual: |
| - __ j(equal, tlabel); |
| + return equal; |
| break; |
| case kUnorderedNotEqual: |
| - __ j(parity_even, tlabel); |
| - // Fall through. |
| case kNotEqual: |
| - __ j(not_equal, tlabel); |
| + return not_equal; |
| break; |
| case kSignedLessThan: |
| - __ j(less, tlabel); |
| + return less; |
| break; |
| case kSignedGreaterThanOrEqual: |
| - __ j(greater_equal, tlabel); |
| + return greater_equal; |
| break; |
| case kSignedLessThanOrEqual: |
| - __ j(less_equal, tlabel); |
| + return less_equal; |
| break; |
| case kSignedGreaterThan: |
| - __ j(greater, tlabel); |
| + return greater; |
| break; |
| case kUnsignedLessThan: |
| - __ j(below, tlabel); |
| + return below; |
| break; |
| case kUnsignedGreaterThanOrEqual: |
| - __ j(above_equal, tlabel); |
| + return above_equal; |
| break; |
| case kUnsignedLessThanOrEqual: |
| - __ j(below_equal, tlabel); |
| + return below_equal; |
| break; |
| case kUnsignedGreaterThan: |
| - __ j(above, tlabel); |
| + return above; |
| break; |
| case kOverflow: |
| - __ j(overflow, tlabel); |
| + return overflow; |
| break; |
| case kNotOverflow: |
| - __ j(no_overflow, tlabel); |
| + return no_overflow; |
| break; |
| default: |
| UNREACHABLE(); |
| + return no_condition; |
| break; |
| } |
| +} |
| + |
| +// Assembles branches after this instruction. |
| +void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
| + X64OperandConverter i(this, instr); |
| + Label::Distance flabel_distance = |
| + branch->fallthru ? Label::kNear : Label::kFar; |
| + Label* tlabel = branch->true_label; |
| + Label* flabel = branch->false_label; |
| + if (branch->condition == kUnorderedEqual) { |
| + __ j(parity_even, flabel, flabel_distance); |
| + } else if (branch->condition == kUnorderedNotEqual) { |
| + __ j(parity_even, tlabel); |
| + } |
| + __ j(ToCC(branch->condition), tlabel); |
| + |
| if (!branch->fallthru) __ jmp(flabel, flabel_distance); |
| } |
| @@ -2289,6 +2295,59 @@ void CodeGenerator::AssembleArchJump(RpoNumber target) { |
| if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target)); |
| } |
| +void CodeGenerator::AssembleArchTrap(Instruction* instr, |
| + FlagsCondition condition) { |
| + 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 { |
| + X64OperandConverter i(gen_, instr_); |
| + |
| + Runtime::FunctionId trap_id = static_cast<Runtime::FunctionId>( |
| + i.InputInt32(instr_->InputCount() - 1)); |
| + if (frame_elided_) { |
|
titzer
2016/12/12 14:21:34
We don't need the frame teardown, since the call t
|
| + FrameScope f(masm(), StackFrame::WASM); |
| + GenerateCallToTrap(trap_id); |
| + } else { |
| + GenerateCallToTrap(trap_id); |
| + } |
| + } |
| + |
| + private: |
| + void GenerateCallToTrap(Runtime::FunctionId trap_id) { |
| + if (trap_id == Runtime::kNumFunctions) { |
|
titzer
2016/12/12 14:21:33
You should probably leave a comment here that this
|
| + __ PrepareCallCFunction(0); |
| + __ CallCFunction( |
| + ExternalReference::wasm_call_trap_callback_for_testing(isolate()), |
| + 0); |
| + } else { |
| + __ Move(rsi, isolate()->native_context()); |
| + gen_->AssembleSourcePosition(instr_); |
|
titzer
2016/12/12 14:21:33
Should the source position recording be after the
ahaas
2016/12/13 12:38:59
I looked up other code, and there it is recorded b
|
| + __ CallRuntime(trap_id); |
| + } |
| + } |
| + |
| + 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(); |
| + Label end; |
| + if (condition == kUnorderedEqual) { |
| + __ j(parity_even, &end); |
| + } else if (condition == kUnorderedNotEqual) { |
| + __ j(parity_even, tlabel); |
| + } |
| + __ j(ToCC(condition), tlabel); |
| + __ bind(&end); |
| +} |
| // Assembles boolean materializations after this instruction. |
| void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
| @@ -2301,60 +2360,17 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
| Label check; |
| DCHECK_NE(0u, instr->OutputCount()); |
| Register reg = i.OutputRegister(instr->OutputCount() - 1); |
| - Condition cc = no_condition; |
| - switch (condition) { |
| - case kUnorderedEqual: |
| - __ j(parity_odd, &check, Label::kNear); |
| - __ movl(reg, Immediate(0)); |
| - __ jmp(&done, Label::kNear); |
| - // Fall through. |
| - case kEqual: |
| - cc = equal; |
| - break; |
| - case kUnorderedNotEqual: |
| - __ j(parity_odd, &check, Label::kNear); |
| - __ movl(reg, Immediate(1)); |
| - __ jmp(&done, Label::kNear); |
| - // Fall through. |
| - case kNotEqual: |
| - cc = not_equal; |
| - break; |
| - case kSignedLessThan: |
| - cc = less; |
| - break; |
| - case kSignedGreaterThanOrEqual: |
| - cc = greater_equal; |
| - break; |
| - case kSignedLessThanOrEqual: |
| - cc = less_equal; |
| - break; |
| - case kSignedGreaterThan: |
| - cc = greater; |
| - break; |
| - case kUnsignedLessThan: |
| - cc = below; |
| - break; |
| - case kUnsignedGreaterThanOrEqual: |
| - cc = above_equal; |
| - break; |
| - case kUnsignedLessThanOrEqual: |
| - cc = below_equal; |
| - break; |
| - case kUnsignedGreaterThan: |
| - cc = above; |
| - break; |
| - case kOverflow: |
| - cc = overflow; |
| - break; |
| - case kNotOverflow: |
| - cc = no_overflow; |
| - break; |
| - default: |
| - UNREACHABLE(); |
| - break; |
| + if (condition == kUnorderedEqual) { |
| + __ j(parity_odd, &check, Label::kNear); |
| + __ movl(reg, Immediate(0)); |
| + __ jmp(&done, Label::kNear); |
| + } else if (condition == kUnorderedNotEqual) { |
| + __ j(parity_odd, &check, Label::kNear); |
| + __ movl(reg, Immediate(1)); |
| + __ jmp(&done, Label::kNear); |
| } |
| __ bind(&check); |
| - __ setcc(cc, reg); |
| + __ setcc(ToCC(condition), reg); |
| __ movzxbl(reg, reg); |
| __ bind(&done); |
| } |