OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 2000 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2011 if (!branch->fallthru) __ b(flabel); // no fallthru to flabel. | 2011 if (!branch->fallthru) __ b(flabel); // no fallthru to flabel. |
2012 } | 2012 } |
2013 | 2013 |
2014 | 2014 |
2015 void CodeGenerator::AssembleArchJump(RpoNumber target) { | 2015 void CodeGenerator::AssembleArchJump(RpoNumber target) { |
2016 if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target)); | 2016 if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target)); |
2017 } | 2017 } |
2018 | 2018 |
2019 void CodeGenerator::AssembleArchTrap(Instruction* instr, | 2019 void CodeGenerator::AssembleArchTrap(Instruction* instr, |
2020 FlagsCondition condition) { | 2020 FlagsCondition condition) { |
2021 UNREACHABLE(); | 2021 class OutOfLineTrap final : public OutOfLineCode { |
| 2022 public: |
| 2023 OutOfLineTrap(CodeGenerator* gen, bool frame_elided, Instruction* instr) |
| 2024 : OutOfLineCode(gen), |
| 2025 frame_elided_(frame_elided), |
| 2026 instr_(instr), |
| 2027 gen_(gen) {} |
| 2028 |
| 2029 void Generate() final { |
| 2030 PPCOperandConverter i(gen_, instr_); |
| 2031 |
| 2032 Runtime::FunctionId trap_id = static_cast<Runtime::FunctionId>( |
| 2033 i.InputInt32(instr_->InputCount() - 1)); |
| 2034 bool old_has_frame = __ has_frame(); |
| 2035 if (frame_elided_) { |
| 2036 __ set_has_frame(true); |
| 2037 __ EnterFrame(StackFrame::WASM_COMPILED, true); |
| 2038 } |
| 2039 GenerateCallToTrap(trap_id); |
| 2040 if (frame_elided_) { |
| 2041 __ set_has_frame(old_has_frame); |
| 2042 } |
| 2043 if (FLAG_debug_code) { |
| 2044 __ stop(GetBailoutReason(kUnexpectedReturnFromWasmTrap)); |
| 2045 } |
| 2046 } |
| 2047 |
| 2048 private: |
| 2049 void GenerateCallToTrap(Runtime::FunctionId trap_id) { |
| 2050 if (trap_id == Runtime::kNumFunctions) { |
| 2051 // We cannot test calls to the runtime in cctest/test-run-wasm. |
| 2052 // Therefore we emit a call to C here instead of a call to the runtime. |
| 2053 // We use the context register as the scratch register, because we do |
| 2054 // not have a context here. |
| 2055 __ PrepareCallCFunction(0, 0, cp); |
| 2056 __ CallCFunction( |
| 2057 ExternalReference::wasm_call_trap_callback_for_testing(isolate()), |
| 2058 0); |
| 2059 } else { |
| 2060 __ Move(cp, isolate()->native_context()); |
| 2061 gen_->AssembleSourcePosition(instr_); |
| 2062 __ CallRuntime(trap_id); |
| 2063 } |
| 2064 ReferenceMap* reference_map = |
| 2065 new (gen_->zone()) ReferenceMap(gen_->zone()); |
| 2066 gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0, |
| 2067 Safepoint::kNoLazyDeopt); |
| 2068 } |
| 2069 |
| 2070 bool frame_elided_; |
| 2071 Instruction* instr_; |
| 2072 CodeGenerator* gen_; |
| 2073 }; |
| 2074 bool frame_elided = !frame_access_state()->has_frame(); |
| 2075 auto ool = new (zone()) OutOfLineTrap(this, frame_elided, instr); |
| 2076 Label* tlabel = ool->entry(); |
| 2077 Label end; |
| 2078 |
| 2079 ArchOpcode op = instr->arch_opcode(); |
| 2080 CRegister cr = cr0; |
| 2081 Condition cond = FlagsConditionToCondition(condition, op); |
| 2082 if (op == kPPC_CmpDouble) { |
| 2083 // check for unordered if necessary |
| 2084 if (cond == le) { |
| 2085 __ bunordered(&end, cr); |
| 2086 // Unnecessary for eq/lt since only FU bit will be set. |
| 2087 } else if (cond == gt) { |
| 2088 __ bunordered(tlabel, cr); |
| 2089 // Unnecessary for ne/ge since only FU bit will be set. |
| 2090 } |
| 2091 } |
| 2092 __ b(cond, tlabel, cr); |
| 2093 __ bind(&end); |
2022 } | 2094 } |
2023 | 2095 |
2024 // Assembles boolean materializations after an instruction. | 2096 // Assembles boolean materializations after an instruction. |
2025 void CodeGenerator::AssembleArchBoolean(Instruction* instr, | 2097 void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
2026 FlagsCondition condition) { | 2098 FlagsCondition condition) { |
2027 PPCOperandConverter i(this, instr); | 2099 PPCOperandConverter i(this, instr); |
2028 Label done; | 2100 Label done; |
2029 ArchOpcode op = instr->arch_opcode(); | 2101 ArchOpcode op = instr->arch_opcode(); |
2030 CRegister cr = cr0; | 2102 CRegister cr = cr0; |
2031 int reg_value = -1; | 2103 int reg_value = -1; |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2490 padding_size -= v8::internal::Assembler::kInstrSize; | 2562 padding_size -= v8::internal::Assembler::kInstrSize; |
2491 } | 2563 } |
2492 } | 2564 } |
2493 } | 2565 } |
2494 | 2566 |
2495 #undef __ | 2567 #undef __ |
2496 | 2568 |
2497 } // namespace compiler | 2569 } // namespace compiler |
2498 } // namespace internal | 2570 } // namespace internal |
2499 } // namespace v8 | 2571 } // namespace v8 |
OLD | NEW |