OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/compilation-info.h" | 7 #include "src/compilation-info.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 2282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2293 __ b(cond, tlabel); | 2293 __ b(cond, tlabel); |
2294 if (!branch->fallthru) __ b(flabel); // no fallthru to flabel. | 2294 if (!branch->fallthru) __ b(flabel); // no fallthru to flabel. |
2295 } | 2295 } |
2296 | 2296 |
2297 void CodeGenerator::AssembleArchJump(RpoNumber target) { | 2297 void CodeGenerator::AssembleArchJump(RpoNumber target) { |
2298 if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target)); | 2298 if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target)); |
2299 } | 2299 } |
2300 | 2300 |
2301 void CodeGenerator::AssembleArchTrap(Instruction* instr, | 2301 void CodeGenerator::AssembleArchTrap(Instruction* instr, |
2302 FlagsCondition condition) { | 2302 FlagsCondition condition) { |
2303 UNREACHABLE(); | 2303 class OutOfLineTrap final : public OutOfLineCode { |
| 2304 public: |
| 2305 OutOfLineTrap(CodeGenerator* gen, bool frame_elided, Instruction* instr) |
| 2306 : OutOfLineCode(gen), |
| 2307 frame_elided_(frame_elided), |
| 2308 instr_(instr), |
| 2309 gen_(gen) {} |
| 2310 |
| 2311 void Generate() final { |
| 2312 S390OperandConverter i(gen_, instr_); |
| 2313 |
| 2314 Runtime::FunctionId trap_id = static_cast<Runtime::FunctionId>( |
| 2315 i.InputInt32(instr_->InputCount() - 1)); |
| 2316 bool old_has_frame = __ has_frame(); |
| 2317 if (frame_elided_) { |
| 2318 __ set_has_frame(true); |
| 2319 __ EnterFrame(StackFrame::WASM_COMPILED); |
| 2320 } |
| 2321 GenerateCallToTrap(trap_id); |
| 2322 if (frame_elided_) { |
| 2323 __ set_has_frame(old_has_frame); |
| 2324 } |
| 2325 if (FLAG_debug_code) { |
| 2326 __ stop(GetBailoutReason(kUnexpectedReturnFromWasmTrap)); |
| 2327 } |
| 2328 } |
| 2329 |
| 2330 private: |
| 2331 void GenerateCallToTrap(Runtime::FunctionId trap_id) { |
| 2332 if (trap_id == Runtime::kNumFunctions) { |
| 2333 // We cannot test calls to the runtime in cctest/test-run-wasm. |
| 2334 // Therefore we emit a call to C here instead of a call to the runtime. |
| 2335 // We use the context register as the scratch register, because we do |
| 2336 // not have a context here. |
| 2337 __ PrepareCallCFunction(0, 0, cp); |
| 2338 __ CallCFunction( |
| 2339 ExternalReference::wasm_call_trap_callback_for_testing(isolate()), |
| 2340 0); |
| 2341 } else { |
| 2342 __ Move(cp, isolate()->native_context()); |
| 2343 gen_->AssembleSourcePosition(instr_); |
| 2344 __ CallRuntime(trap_id); |
| 2345 } |
| 2346 ReferenceMap* reference_map = |
| 2347 new (gen_->zone()) ReferenceMap(gen_->zone()); |
| 2348 gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0, |
| 2349 Safepoint::kNoLazyDeopt); |
| 2350 } |
| 2351 |
| 2352 bool frame_elided_; |
| 2353 Instruction* instr_; |
| 2354 CodeGenerator* gen_; |
| 2355 }; |
| 2356 bool frame_elided = !frame_access_state()->has_frame(); |
| 2357 auto ool = new (zone()) OutOfLineTrap(this, frame_elided, instr); |
| 2358 Label* tlabel = ool->entry(); |
| 2359 Label end; |
| 2360 |
| 2361 ArchOpcode op = instr->arch_opcode(); |
| 2362 Condition cond = FlagsConditionToCondition(condition, op); |
| 2363 if (op == kS390_CmpDouble) { |
| 2364 // check for unordered if necessary |
| 2365 if (cond == le) { |
| 2366 __ bunordered(&end); |
| 2367 // Unnecessary for eq/lt since only FU bit will be set. |
| 2368 } else if (cond == gt) { |
| 2369 __ bunordered(tlabel); |
| 2370 // Unnecessary for ne/ge since only FU bit will be set. |
| 2371 } |
| 2372 } |
| 2373 __ b(cond, tlabel); |
| 2374 __ bind(&end); |
2304 } | 2375 } |
2305 | 2376 |
2306 // Assembles boolean materializations after an instruction. | 2377 // Assembles boolean materializations after an instruction. |
2307 void CodeGenerator::AssembleArchBoolean(Instruction* instr, | 2378 void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
2308 FlagsCondition condition) { | 2379 FlagsCondition condition) { |
2309 S390OperandConverter i(this, instr); | 2380 S390OperandConverter i(this, instr); |
2310 ArchOpcode op = instr->arch_opcode(); | 2381 ArchOpcode op = instr->arch_opcode(); |
2311 bool check_unordered = (op == kS390_CmpDouble || op == kS390_CmpFloat); | 2382 bool check_unordered = (op == kS390_CmpDouble || op == kS390_CmpFloat); |
2312 | 2383 |
2313 // Overflow checked for add/sub only. | 2384 // Overflow checked for add/sub only. |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2725 padding_size -= 2; | 2796 padding_size -= 2; |
2726 } | 2797 } |
2727 } | 2798 } |
2728 } | 2799 } |
2729 | 2800 |
2730 #undef __ | 2801 #undef __ |
2731 | 2802 |
2732 } // namespace compiler | 2803 } // namespace compiler |
2733 } // namespace internal | 2804 } // namespace internal |
2734 } // namespace v8 | 2805 } // namespace v8 |
OLD | NEW |