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/wasm-compiler.h" | 5 #include "src/compiler/wasm-compiler.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/isolate-inl.h" | 9 #include "src/isolate-inl.h" |
10 | 10 |
(...skipping 1902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1913 Node* div = graph()->NewNode(m->Int32Div(), left, right, z.if_false); | 1913 Node* div = graph()->NewNode(m->Int32Div(), left, right, z.if_false); |
1914 Node* neg = | 1914 Node* neg = |
1915 graph()->NewNode(m->Int32Sub(), jsgraph()->Int32Constant(0), left); | 1915 graph()->NewNode(m->Int32Sub(), jsgraph()->Int32Constant(0), left); |
1916 | 1916 |
1917 return n.Phi( | 1917 return n.Phi( |
1918 MachineRepresentation::kWord32, neg, | 1918 MachineRepresentation::kWord32, neg, |
1919 z.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0), div)); | 1919 z.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0), div)); |
1920 } | 1920 } |
1921 | 1921 |
1922 Node* WasmGraphBuilder::BuildI32AsmjsRemS(Node* left, Node* right) { | 1922 Node* WasmGraphBuilder::BuildI32AsmjsRemS(Node* left, Node* right) { |
| 1923 CommonOperatorBuilder* c = jsgraph()->common(); |
1923 MachineOperatorBuilder* m = jsgraph()->machine(); | 1924 MachineOperatorBuilder* m = jsgraph()->machine(); |
| 1925 Node* const zero = jsgraph()->Int32Constant(0); |
1924 | 1926 |
1925 Int32Matcher mr(right); | 1927 Int32Matcher mr(right); |
1926 if (mr.HasValue()) { | 1928 if (mr.HasValue()) { |
1927 if (mr.Value() == 0) { | 1929 if (mr.Value() == 0 || mr.Value() == -1) { |
1928 return jsgraph()->Int32Constant(0); | 1930 return zero; |
1929 } else if (mr.Value() == -1) { | |
1930 return jsgraph()->Int32Constant(0); | |
1931 } | 1931 } |
1932 return graph()->NewNode(m->Int32Mod(), left, right, *control_); | 1932 return graph()->NewNode(m->Int32Mod(), left, right, *control_); |
1933 } | 1933 } |
1934 | 1934 |
1935 // asm.js semantics return 0 on divide or mod by zero. | 1935 // General case for signed integer modulus, with optimization for (unknown) |
1936 // Explicit check for x % 0. | 1936 // power of 2 right hand side. |
1937 Diamond z( | 1937 // |
1938 graph(), jsgraph()->common(), | 1938 // if 0 < right then |
1939 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(0)), | 1939 // msk = right - 1 |
1940 BranchHint::kFalse); | 1940 // if right & msk != 0 then |
| 1941 // left % right |
| 1942 // else |
| 1943 // if left < 0 then |
| 1944 // -(-left & msk) |
| 1945 // else |
| 1946 // left & msk |
| 1947 // else |
| 1948 // if right < -1 then |
| 1949 // left % right |
| 1950 // else |
| 1951 // zero |
| 1952 // |
| 1953 // Note: We do not use the Diamond helper class here, because it really hurts |
| 1954 // readability with nested diamonds. |
| 1955 Node* const minus_one = jsgraph()->Int32Constant(-1); |
1941 | 1956 |
1942 // Explicit check for x % -1. | 1957 const Operator* const merge_op = c->Merge(2); |
1943 Diamond d( | 1958 const Operator* const phi_op = c->Phi(MachineRepresentation::kWord32, 2); |
1944 graph(), jsgraph()->common(), | |
1945 graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)), | |
1946 BranchHint::kFalse); | |
1947 d.Chain(z.if_false); | |
1948 | 1959 |
1949 return z.Phi( | 1960 Node* check0 = graph()->NewNode(m->Int32LessThan(), zero, right); |
1950 MachineRepresentation::kWord32, jsgraph()->Int32Constant(0), | 1961 Node* branch0 = |
1951 d.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0), | 1962 graph()->NewNode(c->Branch(BranchHint::kTrue), check0, graph()->start()); |
1952 graph()->NewNode(m->Int32Mod(), left, right, d.if_false))); | 1963 |
| 1964 Node* if_true0 = graph()->NewNode(c->IfTrue(), branch0); |
| 1965 Node* true0; |
| 1966 { |
| 1967 Node* msk = graph()->NewNode(m->Int32Add(), right, minus_one); |
| 1968 |
| 1969 Node* check1 = graph()->NewNode(m->Word32And(), right, msk); |
| 1970 Node* branch1 = graph()->NewNode(c->Branch(), check1, if_true0); |
| 1971 |
| 1972 Node* if_true1 = graph()->NewNode(c->IfTrue(), branch1); |
| 1973 Node* true1 = graph()->NewNode(m->Int32Mod(), left, right, if_true1); |
| 1974 |
| 1975 Node* if_false1 = graph()->NewNode(c->IfFalse(), branch1); |
| 1976 Node* false1; |
| 1977 { |
| 1978 Node* check2 = graph()->NewNode(m->Int32LessThan(), left, zero); |
| 1979 Node* branch2 = |
| 1980 graph()->NewNode(c->Branch(BranchHint::kFalse), check2, if_false1); |
| 1981 |
| 1982 Node* if_true2 = graph()->NewNode(c->IfTrue(), branch2); |
| 1983 Node* true2 = graph()->NewNode( |
| 1984 m->Int32Sub(), zero, |
| 1985 graph()->NewNode(m->Word32And(), |
| 1986 graph()->NewNode(m->Int32Sub(), zero, left), msk)); |
| 1987 |
| 1988 Node* if_false2 = graph()->NewNode(c->IfFalse(), branch2); |
| 1989 Node* false2 = graph()->NewNode(m->Word32And(), left, msk); |
| 1990 |
| 1991 if_false1 = graph()->NewNode(merge_op, if_true2, if_false2); |
| 1992 false1 = graph()->NewNode(phi_op, true2, false2, if_false1); |
| 1993 } |
| 1994 |
| 1995 if_true0 = graph()->NewNode(merge_op, if_true1, if_false1); |
| 1996 true0 = graph()->NewNode(phi_op, true1, false1, if_true0); |
| 1997 } |
| 1998 |
| 1999 Node* if_false0 = graph()->NewNode(c->IfFalse(), branch0); |
| 2000 Node* false0; |
| 2001 { |
| 2002 Node* check1 = graph()->NewNode(m->Int32LessThan(), right, minus_one); |
| 2003 Node* branch1 = |
| 2004 graph()->NewNode(c->Branch(BranchHint::kTrue), check1, if_false0); |
| 2005 |
| 2006 Node* if_true1 = graph()->NewNode(c->IfTrue(), branch1); |
| 2007 Node* true1 = graph()->NewNode(m->Int32Mod(), left, right, if_true1); |
| 2008 |
| 2009 Node* if_false1 = graph()->NewNode(c->IfFalse(), branch1); |
| 2010 Node* false1 = zero; |
| 2011 |
| 2012 if_false0 = graph()->NewNode(merge_op, if_true1, if_false1); |
| 2013 false0 = graph()->NewNode(phi_op, true1, false1, if_false0); |
| 2014 } |
| 2015 |
| 2016 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0); |
| 2017 return graph()->NewNode(phi_op, true0, false0, merge0); |
1953 } | 2018 } |
1954 | 2019 |
1955 Node* WasmGraphBuilder::BuildI32AsmjsDivU(Node* left, Node* right) { | 2020 Node* WasmGraphBuilder::BuildI32AsmjsDivU(Node* left, Node* right) { |
1956 MachineOperatorBuilder* m = jsgraph()->machine(); | 2021 MachineOperatorBuilder* m = jsgraph()->machine(); |
1957 // asm.js semantics return 0 on divide or mod by zero. | 2022 // asm.js semantics return 0 on divide or mod by zero. |
1958 if (m->Uint32DivIsSafe()) { | 2023 if (m->Uint32DivIsSafe()) { |
1959 // The hardware instruction does the right thing (e.g. arm). | 2024 // The hardware instruction does the right thing (e.g. arm). |
1960 return graph()->NewNode(m->Uint32Div(), left, right, graph()->start()); | 2025 return graph()->NewNode(m->Uint32Div(), left, right, graph()->start()); |
1961 } | 2026 } |
1962 | 2027 |
(...skipping 1572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3535 Smi::FromInt(instruction.instr_offset)); | 3600 Smi::FromInt(instruction.instr_offset)); |
3536 fn_protected->set(Code::kTrapDataSize * i + Code::kTrapLandingOffset, | 3601 fn_protected->set(Code::kTrapDataSize * i + Code::kTrapLandingOffset, |
3537 Smi::FromInt(instruction.landing_offset)); | 3602 Smi::FromInt(instruction.landing_offset)); |
3538 } | 3603 } |
3539 return fn_protected; | 3604 return fn_protected; |
3540 } | 3605 } |
3541 | 3606 |
3542 } // namespace compiler | 3607 } // namespace compiler |
3543 } // namespace internal | 3608 } // namespace internal |
3544 } // namespace v8 | 3609 } // namespace v8 |
OLD | NEW |