Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: src/compiler/mips64/code-generator-mips64.cc

Issue 2627003002: [wasm] TrapIf and TrapUnless TurboFan operators implemented on mips64. (Closed)
Patch Set: rebase Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/compiler/mips64/instruction-selector-mips64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "src/compilation-info.h" 6 #include "src/compilation-info.h"
7 #include "src/compiler/code-generator-impl.h" 7 #include "src/compiler/code-generator-impl.h"
8 #include "src/compiler/gap-resolver.h" 8 #include "src/compiler/gap-resolver.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/compiler/osr.h" 10 #include "src/compiler/osr.h"
(...skipping 1917 matching lines...) Expand 10 before | Expand all | Expand 10 after
1928 return true; 1928 return true;
1929 case kUnsignedGreaterThan: 1929 case kUnsignedGreaterThan:
1930 cc = ugt; 1930 cc = ugt;
1931 return true; 1931 return true;
1932 default: 1932 default:
1933 break; 1933 break;
1934 } 1934 }
1935 return false; 1935 return false;
1936 } 1936 }
1937 1937
1938 void AssembleBranchToLabels(CodeGenerator* gen, MacroAssembler* masm,
1939 Instruction* instr, FlagsCondition condition,
1940 Label* tlabel, Label* flabel, bool fallthru) {
1941 #undef __
1942 #define __ masm->
1943 MipsOperandConverter i(gen, instr);
1938 1944
1939 // Assembles branches after an instruction.
1940 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
1941 MipsOperandConverter i(this, instr);
1942 Label* tlabel = branch->true_label;
1943 Label* flabel = branch->false_label;
1944 Condition cc = kNoCondition; 1945 Condition cc = kNoCondition;
1945 // MIPS does not have condition code flags, so compare and branch are 1946 // MIPS does not have condition code flags, so compare and branch are
1946 // implemented differently than on the other arch's. The compare operations 1947 // implemented differently than on the other arch's. The compare operations
1947 // emit mips psuedo-instructions, which are handled here by branch 1948 // emit mips psuedo-instructions, which are handled here by branch
1948 // instructions that do the actual comparison. Essential that the input 1949 // instructions that do the actual comparison. Essential that the input
1949 // registers to compare pseudo-op are not modified before this branch op, as 1950 // registers to compare pseudo-op are not modified before this branch op, as
1950 // they are tested here. 1951 // they are tested here.
1951 1952
1952 if (instr->arch_opcode() == kMips64Tst) { 1953 if (instr->arch_opcode() == kMips64Tst) {
1953 cc = FlagsConditionToConditionTst(branch->condition); 1954 cc = FlagsConditionToConditionTst(condition);
1954 __ And(at, i.InputRegister(0), i.InputOperand(1)); 1955 __ And(at, i.InputRegister(0), i.InputOperand(1));
1955 __ Branch(tlabel, cc, at, Operand(zero_reg)); 1956 __ Branch(tlabel, cc, at, Operand(zero_reg));
1956 } else if (instr->arch_opcode() == kMips64Dadd || 1957 } else if (instr->arch_opcode() == kMips64Dadd ||
1957 instr->arch_opcode() == kMips64Dsub) { 1958 instr->arch_opcode() == kMips64Dsub) {
1958 cc = FlagsConditionToConditionOvf(branch->condition); 1959 cc = FlagsConditionToConditionOvf(condition);
1959 __ dsra32(kScratchReg, i.OutputRegister(), 0); 1960 __ dsra32(kScratchReg, i.OutputRegister(), 0);
1960 __ sra(at, i.OutputRegister(), 31); 1961 __ sra(at, i.OutputRegister(), 31);
1961 __ Branch(tlabel, cc, at, Operand(kScratchReg)); 1962 __ Branch(tlabel, cc, at, Operand(kScratchReg));
1962 } else if (instr->arch_opcode() == kMips64DaddOvf) { 1963 } else if (instr->arch_opcode() == kMips64DaddOvf) {
1963 switch (branch->condition) { 1964 switch (condition) {
1964 case kOverflow: 1965 case kOverflow:
1965 __ DaddBranchOvf(i.OutputRegister(), i.InputRegister(0), 1966 __ DaddBranchOvf(i.OutputRegister(), i.InputRegister(0),
1966 i.InputOperand(1), tlabel, flabel); 1967 i.InputOperand(1), tlabel, flabel);
1967 break; 1968 break;
1968 case kNotOverflow: 1969 case kNotOverflow:
1969 __ DaddBranchOvf(i.OutputRegister(), i.InputRegister(0), 1970 __ DaddBranchOvf(i.OutputRegister(), i.InputRegister(0),
1970 i.InputOperand(1), flabel, tlabel); 1971 i.InputOperand(1), flabel, tlabel);
1971 break; 1972 break;
1972 default: 1973 default:
1973 UNSUPPORTED_COND(kMips64DaddOvf, branch->condition); 1974 UNSUPPORTED_COND(kMips64DaddOvf, condition);
1974 break; 1975 break;
1975 } 1976 }
1976 } else if (instr->arch_opcode() == kMips64DsubOvf) { 1977 } else if (instr->arch_opcode() == kMips64DsubOvf) {
1977 switch (branch->condition) { 1978 switch (condition) {
1978 case kOverflow: 1979 case kOverflow:
1979 __ DsubBranchOvf(i.OutputRegister(), i.InputRegister(0), 1980 __ DsubBranchOvf(i.OutputRegister(), i.InputRegister(0),
1980 i.InputOperand(1), tlabel, flabel); 1981 i.InputOperand(1), tlabel, flabel);
1981 break; 1982 break;
1982 case kNotOverflow: 1983 case kNotOverflow:
1983 __ DsubBranchOvf(i.OutputRegister(), i.InputRegister(0), 1984 __ DsubBranchOvf(i.OutputRegister(), i.InputRegister(0),
1984 i.InputOperand(1), flabel, tlabel); 1985 i.InputOperand(1), flabel, tlabel);
1985 break; 1986 break;
1986 default: 1987 default:
1987 UNSUPPORTED_COND(kMips64DsubOvf, branch->condition); 1988 UNSUPPORTED_COND(kMips64DsubOvf, condition);
1988 break; 1989 break;
1989 } 1990 }
1990 } else if (instr->arch_opcode() == kMips64MulOvf) { 1991 } else if (instr->arch_opcode() == kMips64MulOvf) {
1991 switch (branch->condition) { 1992 switch (condition) {
1992 case kOverflow: { 1993 case kOverflow: {
1993 __ MulBranchOvf(i.OutputRegister(), i.InputRegister(0), 1994 __ MulBranchOvf(i.OutputRegister(), i.InputRegister(0),
1994 i.InputOperand(1), tlabel, flabel, kScratchReg); 1995 i.InputOperand(1), tlabel, flabel, kScratchReg);
1995 } break; 1996 } break;
1996 case kNotOverflow: { 1997 case kNotOverflow: {
1997 __ MulBranchOvf(i.OutputRegister(), i.InputRegister(0), 1998 __ MulBranchOvf(i.OutputRegister(), i.InputRegister(0),
1998 i.InputOperand(1), flabel, tlabel, kScratchReg); 1999 i.InputOperand(1), flabel, tlabel, kScratchReg);
1999 } break; 2000 } break;
2000 default: 2001 default:
2001 UNSUPPORTED_COND(kMips64MulOvf, branch->condition); 2002 UNSUPPORTED_COND(kMips64MulOvf, condition);
2002 break; 2003 break;
2003 } 2004 }
2004 } else if (instr->arch_opcode() == kMips64Cmp) { 2005 } else if (instr->arch_opcode() == kMips64Cmp) {
2005 cc = FlagsConditionToConditionCmp(branch->condition); 2006 cc = FlagsConditionToConditionCmp(condition);
2006 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); 2007 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
2007 } else if (instr->arch_opcode() == kMips64CmpS) { 2008 } else if (instr->arch_opcode() == kMips64CmpS) {
2008 if (!convertCondition(branch->condition, cc)) { 2009 if (!convertCondition(condition, cc)) {
2009 UNSUPPORTED_COND(kMips64CmpS, branch->condition); 2010 UNSUPPORTED_COND(kMips64CmpS, condition);
2010 } 2011 }
2011 FPURegister left = i.InputOrZeroSingleRegister(0); 2012 FPURegister left = i.InputOrZeroSingleRegister(0);
2012 FPURegister right = i.InputOrZeroSingleRegister(1); 2013 FPURegister right = i.InputOrZeroSingleRegister(1);
2013 if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) && 2014 if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) &&
2014 !__ IsDoubleZeroRegSet()) { 2015 !__ IsDoubleZeroRegSet()) {
2015 __ Move(kDoubleRegZero, 0.0); 2016 __ Move(kDoubleRegZero, 0.0);
2016 } 2017 }
2017 __ BranchF32(tlabel, nullptr, cc, left, right); 2018 __ BranchF32(tlabel, nullptr, cc, left, right);
2018 } else if (instr->arch_opcode() == kMips64CmpD) { 2019 } else if (instr->arch_opcode() == kMips64CmpD) {
2019 if (!convertCondition(branch->condition, cc)) { 2020 if (!convertCondition(condition, cc)) {
2020 UNSUPPORTED_COND(kMips64CmpD, branch->condition); 2021 UNSUPPORTED_COND(kMips64CmpD, condition);
2021 } 2022 }
2022 FPURegister left = i.InputOrZeroDoubleRegister(0); 2023 FPURegister left = i.InputOrZeroDoubleRegister(0);
2023 FPURegister right = i.InputOrZeroDoubleRegister(1); 2024 FPURegister right = i.InputOrZeroDoubleRegister(1);
2024 if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) && 2025 if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) &&
2025 !__ IsDoubleZeroRegSet()) { 2026 !__ IsDoubleZeroRegSet()) {
2026 __ Move(kDoubleRegZero, 0.0); 2027 __ Move(kDoubleRegZero, 0.0);
2027 } 2028 }
2028 __ BranchF64(tlabel, nullptr, cc, left, right); 2029 __ BranchF64(tlabel, nullptr, cc, left, right);
2029 } else { 2030 } else {
2030 PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n", 2031 PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n",
2031 instr->arch_opcode()); 2032 instr->arch_opcode());
2032 UNIMPLEMENTED(); 2033 UNIMPLEMENTED();
2033 } 2034 }
2034 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel. 2035 if (!fallthru) __ Branch(flabel); // no fallthru to flabel.
2036 #undef __
2037 #define __ masm()->
2038 }
2039
2040 // Assembles branches after an instruction.
2041 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
2042 Label* tlabel = branch->true_label;
2043 Label* flabel = branch->false_label;
2044
2045 AssembleBranchToLabels(this, masm(), instr, branch->condition, tlabel, flabel,
2046 branch->fallthru);
2035 } 2047 }
2036 2048
2037 2049
2038 void CodeGenerator::AssembleArchJump(RpoNumber target) { 2050 void CodeGenerator::AssembleArchJump(RpoNumber target) {
2039 if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target)); 2051 if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
2040 } 2052 }
2041 2053
2042 void CodeGenerator::AssembleArchTrap(Instruction* instr, 2054 void CodeGenerator::AssembleArchTrap(Instruction* instr,
2043 FlagsCondition condition) { 2055 FlagsCondition condition) {
2044 UNREACHABLE(); 2056 class OutOfLineTrap final : public OutOfLineCode {
2057 public:
2058 OutOfLineTrap(CodeGenerator* gen, bool frame_elided, Instruction* instr)
2059 : OutOfLineCode(gen),
2060 frame_elided_(frame_elided),
2061 instr_(instr),
2062 gen_(gen) {}
2063 void Generate() final {
2064 MipsOperandConverter i(gen_, instr_);
2065 Runtime::FunctionId trap_id = static_cast<Runtime::FunctionId>(
2066 i.InputInt32(instr_->InputCount() - 1));
2067 bool old_has_frame = __ has_frame();
2068 if (frame_elided_) {
2069 __ set_has_frame(true);
2070 __ EnterFrame(StackFrame::WASM_COMPILED);
2071 }
2072 GenerateCallToTrap(trap_id);
2073 if (frame_elided_) {
2074 __ set_has_frame(old_has_frame);
2075 }
2076 if (FLAG_debug_code) {
2077 __ stop(GetBailoutReason(kUnexpectedReturnFromWasmTrap));
2078 }
2079 }
2080
2081 private:
2082 void GenerateCallToTrap(Runtime::FunctionId trap_id) {
2083 if (trap_id == Runtime::kNumFunctions) {
2084 // We cannot test calls to the runtime in cctest/test-run-wasm.
2085 // Therefore we emit a call to C here instead of a call to the runtime.
2086 // We use the context register as the scratch register, because we do
2087 // not have a context here.
2088 __ PrepareCallCFunction(0, 0, cp);
2089 __ CallCFunction(
2090 ExternalReference::wasm_call_trap_callback_for_testing(isolate()),
2091 0);
2092 } else {
2093 __ Move(cp, isolate()->native_context());
2094 gen_->AssembleSourcePosition(instr_);
2095 __ CallRuntime(trap_id);
2096 }
2097 ReferenceMap* reference_map =
2098 new (gen_->zone()) ReferenceMap(gen_->zone());
2099 gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0,
2100 Safepoint::kNoLazyDeopt);
2101 }
2102 bool frame_elided_;
2103 Instruction* instr_;
2104 CodeGenerator* gen_;
2105 };
2106 bool frame_elided = !frame_access_state()->has_frame();
2107 auto ool = new (zone()) OutOfLineTrap(this, frame_elided, instr);
2108 Label* tlabel = ool->entry();
2109 AssembleBranchToLabels(this, masm(), instr, condition, tlabel, nullptr, true);
2045 } 2110 }
2046 2111
2047 // Assembles boolean materializations after an instruction. 2112 // Assembles boolean materializations after an instruction.
2048 void CodeGenerator::AssembleArchBoolean(Instruction* instr, 2113 void CodeGenerator::AssembleArchBoolean(Instruction* instr,
2049 FlagsCondition condition) { 2114 FlagsCondition condition) {
2050 MipsOperandConverter i(this, instr); 2115 MipsOperandConverter i(this, instr);
2051 Label done; 2116 Label done;
2052 2117
2053 // Materialize a full 32-bit 1 or 0 value. The result register is always the 2118 // Materialize a full 32-bit 1 or 0 value. The result register is always the
2054 // last output of the instruction. 2119 // last output of the instruction.
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
2585 padding_size -= v8::internal::Assembler::kInstrSize; 2650 padding_size -= v8::internal::Assembler::kInstrSize;
2586 } 2651 }
2587 } 2652 }
2588 } 2653 }
2589 2654
2590 #undef __ 2655 #undef __
2591 2656
2592 } // namespace compiler 2657 } // namespace compiler
2593 } // namespace internal 2658 } // namespace internal
2594 } // namespace v8 2659 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/mips64/instruction-selector-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698