Index: src/compiler/ppc/code-generator-ppc.cc |
diff --git a/src/compiler/ppc/code-generator-ppc.cc b/src/compiler/ppc/code-generator-ppc.cc |
index 28ff242f66b36f01fb23559509aaf24c2072c7d8..e61550470b41b20d5c6c921aff56a01b8849869c 100644 |
--- a/src/compiler/ppc/code-generator-ppc.cc |
+++ b/src/compiler/ppc/code-generator-ppc.cc |
@@ -2018,7 +2018,79 @@ 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 { |
+ PPCOperandConverter 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, true); |
+ } |
+ 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(); |
+ Label end; |
+ |
+ ArchOpcode op = instr->arch_opcode(); |
+ CRegister cr = cr0; |
+ Condition cond = FlagsConditionToCondition(condition, op); |
+ if (op == kPPC_CmpDouble) { |
+ // check for unordered if necessary |
+ if (cond == le) { |
+ __ bunordered(&end, cr); |
+ // Unnecessary for eq/lt since only FU bit will be set. |
+ } else if (cond == gt) { |
+ __ bunordered(tlabel, cr); |
+ // Unnecessary for ne/ge since only FU bit will be set. |
+ } |
+ } |
+ __ b(cond, tlabel, cr); |
+ __ bind(&end); |
} |
// Assembles boolean materializations after an instruction. |