| 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/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
| 6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
| 7 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 } | 80 } |
| 81 | 81 |
| 82 private: | 82 private: |
| 83 bool IsLoadStoreImmediate(int64_t value, LSDataSize size) { | 83 bool IsLoadStoreImmediate(int64_t value, LSDataSize size) { |
| 84 return Assembler::IsImmLSScaled(value, size) || | 84 return Assembler::IsImmLSScaled(value, size) || |
| 85 Assembler::IsImmLSUnscaled(value); | 85 Assembler::IsImmLSUnscaled(value); |
| 86 } | 86 } |
| 87 }; | 87 }; |
| 88 | 88 |
| 89 | 89 |
| 90 static void VisitRRFloat64(InstructionSelector* selector, ArchOpcode opcode, | 90 namespace { |
| 91 Node* node) { | 91 |
| 92 void VisitRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { |
| 92 Arm64OperandGenerator g(selector); | 93 Arm64OperandGenerator g(selector); |
| 93 selector->Emit(opcode, g.DefineAsRegister(node), | 94 selector->Emit(opcode, g.DefineAsRegister(node), |
| 94 g.UseRegister(node->InputAt(0))); | 95 g.UseRegister(node->InputAt(0))); |
| 95 } | 96 } |
| 96 | 97 |
| 97 | 98 |
| 98 static void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, | 99 void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { |
| 99 Node* node) { | |
| 100 Arm64OperandGenerator g(selector); | 100 Arm64OperandGenerator g(selector); |
| 101 selector->Emit(opcode, g.DefineAsRegister(node), | 101 selector->Emit(opcode, g.DefineAsRegister(node), |
| 102 g.UseRegister(node->InputAt(0)), | 102 g.UseRegister(node->InputAt(0)), |
| 103 g.UseRegister(node->InputAt(1))); | |
| 104 } | |
| 105 | |
| 106 | |
| 107 static void VisitRRRFloat64(InstructionSelector* selector, ArchOpcode opcode, | |
| 108 Node* node) { | |
| 109 Arm64OperandGenerator g(selector); | |
| 110 selector->Emit(opcode, g.DefineAsRegister(node), | |
| 111 g.UseRegister(node->InputAt(0)), | |
| 112 g.UseRegister(node->InputAt(1))); | 103 g.UseRegister(node->InputAt(1))); |
| 113 } | 104 } |
| 114 | 105 |
| 115 | 106 |
| 116 static void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, | 107 void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node, |
| 117 Node* node, ImmediateMode operand_mode) { | 108 ImmediateMode operand_mode) { |
| 118 Arm64OperandGenerator g(selector); | 109 Arm64OperandGenerator g(selector); |
| 119 selector->Emit(opcode, g.DefineAsRegister(node), | 110 selector->Emit(opcode, g.DefineAsRegister(node), |
| 120 g.UseRegister(node->InputAt(0)), | 111 g.UseRegister(node->InputAt(0)), |
| 121 g.UseOperand(node->InputAt(1), operand_mode)); | 112 g.UseOperand(node->InputAt(1), operand_mode)); |
| 122 } | 113 } |
| 123 | 114 |
| 124 | 115 |
| 125 template <typename Matcher> | 116 template <typename Matcher> |
| 126 static bool TryMatchShift(InstructionSelector* selector, Node* node, | 117 bool TryMatchShift(InstructionSelector* selector, Node* node, |
| 127 InstructionCode* opcode, IrOpcode::Value shift_opcode, | 118 InstructionCode* opcode, IrOpcode::Value shift_opcode, |
| 128 ImmediateMode imm_mode, | 119 ImmediateMode imm_mode, AddressingMode addressing_mode) { |
| 129 AddressingMode addressing_mode) { | |
| 130 if (node->opcode() != shift_opcode) return false; | 120 if (node->opcode() != shift_opcode) return false; |
| 131 Arm64OperandGenerator g(selector); | 121 Arm64OperandGenerator g(selector); |
| 132 Matcher m(node); | 122 Matcher m(node); |
| 133 if (g.CanBeImmediate(m.right().node(), imm_mode)) { | 123 if (g.CanBeImmediate(m.right().node(), imm_mode)) { |
| 134 *opcode |= AddressingModeField::encode(addressing_mode); | 124 *opcode |= AddressingModeField::encode(addressing_mode); |
| 135 return true; | 125 return true; |
| 136 } | 126 } |
| 137 return false; | 127 return false; |
| 138 } | 128 } |
| 139 | 129 |
| 140 | 130 |
| 141 static bool TryMatchAnyShift(InstructionSelector* selector, Node* node, | 131 bool TryMatchAnyShift(InstructionSelector* selector, Node* node, |
| 142 InstructionCode* opcode, bool try_ror) { | 132 InstructionCode* opcode, bool try_ror) { |
| 143 return TryMatchShift<Int32BinopMatcher>(selector, node, opcode, | 133 return TryMatchShift<Int32BinopMatcher>(selector, node, opcode, |
| 144 IrOpcode::kWord32Shl, kShift32Imm, | 134 IrOpcode::kWord32Shl, kShift32Imm, |
| 145 kMode_Operand2_R_LSL_I) || | 135 kMode_Operand2_R_LSL_I) || |
| 146 TryMatchShift<Int32BinopMatcher>(selector, node, opcode, | 136 TryMatchShift<Int32BinopMatcher>(selector, node, opcode, |
| 147 IrOpcode::kWord32Shr, kShift32Imm, | 137 IrOpcode::kWord32Shr, kShift32Imm, |
| 148 kMode_Operand2_R_LSR_I) || | 138 kMode_Operand2_R_LSR_I) || |
| 149 TryMatchShift<Int32BinopMatcher>(selector, node, opcode, | 139 TryMatchShift<Int32BinopMatcher>(selector, node, opcode, |
| 150 IrOpcode::kWord32Sar, kShift32Imm, | 140 IrOpcode::kWord32Sar, kShift32Imm, |
| 151 kMode_Operand2_R_ASR_I) || | 141 kMode_Operand2_R_ASR_I) || |
| 152 (try_ror && TryMatchShift<Int32BinopMatcher>( | 142 (try_ror && TryMatchShift<Int32BinopMatcher>( |
| 153 selector, node, opcode, IrOpcode::kWord32Ror, | 143 selector, node, opcode, IrOpcode::kWord32Ror, |
| 154 kShift32Imm, kMode_Operand2_R_ROR_I)) || | 144 kShift32Imm, kMode_Operand2_R_ROR_I)) || |
| 155 TryMatchShift<Int64BinopMatcher>(selector, node, opcode, | 145 TryMatchShift<Int64BinopMatcher>(selector, node, opcode, |
| 156 IrOpcode::kWord64Shl, kShift64Imm, | 146 IrOpcode::kWord64Shl, kShift64Imm, |
| 157 kMode_Operand2_R_LSL_I) || | 147 kMode_Operand2_R_LSL_I) || |
| 158 TryMatchShift<Int64BinopMatcher>(selector, node, opcode, | 148 TryMatchShift<Int64BinopMatcher>(selector, node, opcode, |
| 159 IrOpcode::kWord64Shr, kShift64Imm, | 149 IrOpcode::kWord64Shr, kShift64Imm, |
| 160 kMode_Operand2_R_LSR_I) || | 150 kMode_Operand2_R_LSR_I) || |
| 161 TryMatchShift<Int64BinopMatcher>(selector, node, opcode, | 151 TryMatchShift<Int64BinopMatcher>(selector, node, opcode, |
| 162 IrOpcode::kWord64Sar, kShift64Imm, | 152 IrOpcode::kWord64Sar, kShift64Imm, |
| 163 kMode_Operand2_R_ASR_I) || | 153 kMode_Operand2_R_ASR_I) || |
| 164 (try_ror && TryMatchShift<Int64BinopMatcher>( | 154 (try_ror && TryMatchShift<Int64BinopMatcher>( |
| 165 selector, node, opcode, IrOpcode::kWord64Ror, | 155 selector, node, opcode, IrOpcode::kWord64Ror, |
| 166 kShift64Imm, kMode_Operand2_R_ROR_I)); | 156 kShift64Imm, kMode_Operand2_R_ROR_I)); |
| 167 } | 157 } |
| 168 | 158 |
| 169 | 159 |
| 170 static bool TryMatchAnyExtend(InstructionSelector* selector, Node* node, | 160 bool TryMatchAnyExtend(InstructionSelector* selector, Node* node, |
| 171 InstructionCode* opcode) { | 161 InstructionCode* opcode) { |
| 172 NodeMatcher nm(node); | 162 NodeMatcher nm(node); |
| 173 if (nm.IsWord32And()) { | 163 if (nm.IsWord32And()) { |
| 174 Int32BinopMatcher m(node); | 164 Int32BinopMatcher m(node); |
| 175 if (m.right().HasValue()) { | 165 if (m.right().HasValue()) { |
| 176 if (m.right().Value() == 0xff) { | 166 if (m.right().Value() == 0xff) { |
| 177 *opcode |= AddressingModeField::encode(kMode_Operand2_R_UXTB); | 167 *opcode |= AddressingModeField::encode(kMode_Operand2_R_UXTB); |
| 178 return true; | 168 return true; |
| 179 } else if (m.right().Value() == 0xffff) { | 169 } else if (m.right().Value() == 0xffff) { |
| 180 *opcode |= AddressingModeField::encode(kMode_Operand2_R_UXTH); | 170 *opcode |= AddressingModeField::encode(kMode_Operand2_R_UXTH); |
| 181 return true; | 171 return true; |
| 182 } | 172 } |
| 183 } | 173 } |
| 184 } | 174 } |
| 185 return false; | 175 return false; |
| 186 } | 176 } |
| 187 | 177 |
| 188 | 178 |
| 189 // Shared routine for multiple binary operations. | 179 // Shared routine for multiple binary operations. |
| 190 template <typename Matcher> | 180 template <typename Matcher> |
| 191 static void VisitBinop(InstructionSelector* selector, Node* node, | 181 void VisitBinop(InstructionSelector* selector, Node* node, |
| 192 InstructionCode opcode, ImmediateMode operand_mode, | 182 InstructionCode opcode, ImmediateMode operand_mode, |
| 193 FlagsContinuation* cont) { | 183 FlagsContinuation* cont) { |
| 194 Arm64OperandGenerator g(selector); | 184 Arm64OperandGenerator g(selector); |
| 195 Matcher m(node); | 185 Matcher m(node); |
| 196 InstructionOperand inputs[4]; | 186 InstructionOperand inputs[4]; |
| 197 size_t input_count = 0; | 187 size_t input_count = 0; |
| 198 InstructionOperand outputs[2]; | 188 InstructionOperand outputs[2]; |
| 199 size_t output_count = 0; | 189 size_t output_count = 0; |
| 200 bool is_add_sub = false; | 190 bool is_add_sub = false; |
| 201 | 191 |
| 202 if (m.IsInt32Add() || m.IsInt64Add() || m.IsInt32Sub() || m.IsInt64Sub()) { | 192 if (m.IsInt32Add() || m.IsInt64Add() || m.IsInt32Sub() || m.IsInt64Sub()) { |
| 203 is_add_sub = true; | 193 is_add_sub = true; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 DCHECK_GE(arraysize(inputs), input_count); | 239 DCHECK_GE(arraysize(inputs), input_count); |
| 250 DCHECK_GE(arraysize(outputs), output_count); | 240 DCHECK_GE(arraysize(outputs), output_count); |
| 251 | 241 |
| 252 selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, | 242 selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, |
| 253 inputs); | 243 inputs); |
| 254 } | 244 } |
| 255 | 245 |
| 256 | 246 |
| 257 // Shared routine for multiple binary operations. | 247 // Shared routine for multiple binary operations. |
| 258 template <typename Matcher> | 248 template <typename Matcher> |
| 259 static void VisitBinop(InstructionSelector* selector, Node* node, | 249 void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode, |
| 260 ArchOpcode opcode, ImmediateMode operand_mode) { | 250 ImmediateMode operand_mode) { |
| 261 FlagsContinuation cont; | 251 FlagsContinuation cont; |
| 262 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); | 252 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); |
| 263 } | 253 } |
| 264 | 254 |
| 265 | 255 |
| 266 template <typename Matcher> | 256 template <typename Matcher> |
| 267 static void VisitAddSub(InstructionSelector* selector, Node* node, | 257 void VisitAddSub(InstructionSelector* selector, Node* node, ArchOpcode opcode, |
| 268 ArchOpcode opcode, ArchOpcode negate_opcode) { | 258 ArchOpcode negate_opcode) { |
| 269 Arm64OperandGenerator g(selector); | 259 Arm64OperandGenerator g(selector); |
| 270 Matcher m(node); | 260 Matcher m(node); |
| 271 if (m.right().HasValue() && (m.right().Value() < 0) && | 261 if (m.right().HasValue() && (m.right().Value() < 0) && |
| 272 g.CanBeImmediate(-m.right().Value(), kArithmeticImm)) { | 262 g.CanBeImmediate(-m.right().Value(), kArithmeticImm)) { |
| 273 selector->Emit(negate_opcode, g.DefineAsRegister(node), | 263 selector->Emit(negate_opcode, g.DefineAsRegister(node), |
| 274 g.UseRegister(m.left().node()), | 264 g.UseRegister(m.left().node()), |
| 275 g.TempImmediate(-m.right().Value())); | 265 g.TempImmediate(-m.right().Value())); |
| 276 } else { | 266 } else { |
| 277 VisitBinop<Matcher>(selector, node, opcode, kArithmeticImm); | 267 VisitBinop<Matcher>(selector, node, opcode, kArithmeticImm); |
| 278 } | 268 } |
| 279 } | 269 } |
| 280 | 270 |
| 271 } // namespace |
| 272 |
| 281 | 273 |
| 282 void InstructionSelector::VisitLoad(Node* node) { | 274 void InstructionSelector::VisitLoad(Node* node) { |
| 283 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 275 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); |
| 284 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | 276 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); |
| 285 Arm64OperandGenerator g(this); | 277 Arm64OperandGenerator g(this); |
| 286 Node* base = node->InputAt(0); | 278 Node* base = node->InputAt(0); |
| 287 Node* index = node->InputAt(1); | 279 Node* index = node->InputAt(1); |
| 288 ArchOpcode opcode; | 280 ArchOpcode opcode; |
| 289 ImmediateMode immediate_mode = kNoImmediate; | 281 ImmediateMode immediate_mode = kNoImmediate; |
| 290 switch (rep) { | 282 switch (rep) { |
| (...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 VisitRRR(this, kArm64Umod32, node); | 941 VisitRRR(this, kArm64Umod32, node); |
| 950 } | 942 } |
| 951 | 943 |
| 952 | 944 |
| 953 void InstructionSelector::VisitUint64Mod(Node* node) { | 945 void InstructionSelector::VisitUint64Mod(Node* node) { |
| 954 VisitRRR(this, kArm64Umod, node); | 946 VisitRRR(this, kArm64Umod, node); |
| 955 } | 947 } |
| 956 | 948 |
| 957 | 949 |
| 958 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { | 950 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { |
| 959 Arm64OperandGenerator g(this); | 951 VisitRR(this, kArm64Float32ToFloat64, node); |
| 960 Emit(kArm64Float32ToFloat64, g.DefineAsRegister(node), | |
| 961 g.UseRegister(node->InputAt(0))); | |
| 962 } | 952 } |
| 963 | 953 |
| 964 | 954 |
| 965 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { | 955 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { |
| 966 Arm64OperandGenerator g(this); | 956 VisitRR(this, kArm64Int32ToFloat64, node); |
| 967 Emit(kArm64Int32ToFloat64, g.DefineAsRegister(node), | |
| 968 g.UseRegister(node->InputAt(0))); | |
| 969 } | 957 } |
| 970 | 958 |
| 971 | 959 |
| 972 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { | 960 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { |
| 973 Arm64OperandGenerator g(this); | 961 VisitRR(this, kArm64Uint32ToFloat64, node); |
| 974 Emit(kArm64Uint32ToFloat64, g.DefineAsRegister(node), | |
| 975 g.UseRegister(node->InputAt(0))); | |
| 976 } | 962 } |
| 977 | 963 |
| 978 | 964 |
| 979 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { | 965 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { |
| 980 Arm64OperandGenerator g(this); | 966 VisitRR(this, kArm64Float64ToInt32, node); |
| 981 Emit(kArm64Float64ToInt32, g.DefineAsRegister(node), | |
| 982 g.UseRegister(node->InputAt(0))); | |
| 983 } | 967 } |
| 984 | 968 |
| 985 | 969 |
| 986 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { | 970 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { |
| 987 Arm64OperandGenerator g(this); | 971 VisitRR(this, kArm64Float64ToUint32, node); |
| 988 Emit(kArm64Float64ToUint32, g.DefineAsRegister(node), | |
| 989 g.UseRegister(node->InputAt(0))); | |
| 990 } | 972 } |
| 991 | 973 |
| 992 | 974 |
| 993 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) { | 975 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) { |
| 994 Arm64OperandGenerator g(this); | 976 VisitRR(this, kArm64Sxtw, node); |
| 995 Emit(kArm64Sxtw, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0))); | |
| 996 } | 977 } |
| 997 | 978 |
| 998 | 979 |
| 999 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) { | 980 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) { |
| 1000 Arm64OperandGenerator g(this); | 981 Arm64OperandGenerator g(this); |
| 1001 Node* value = node->InputAt(0); | 982 Node* value = node->InputAt(0); |
| 1002 switch (value->opcode()) { | 983 switch (value->opcode()) { |
| 1003 case IrOpcode::kWord32And: | 984 case IrOpcode::kWord32And: |
| 1004 case IrOpcode::kWord32Or: | 985 case IrOpcode::kWord32Or: |
| 1005 case IrOpcode::kWord32Xor: | 986 case IrOpcode::kWord32Xor: |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 Emit(kArm64Lsr, g.DefineAsRegister(node), g.UseRegister(m.left().node()), | 1035 Emit(kArm64Lsr, g.DefineAsRegister(node), g.UseRegister(m.left().node()), |
| 1055 g.UseImmediate(m.right().node())); | 1036 g.UseImmediate(m.right().node())); |
| 1056 return; | 1037 return; |
| 1057 } | 1038 } |
| 1058 } | 1039 } |
| 1059 | 1040 |
| 1060 Emit(kArm64Mov32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0))); | 1041 Emit(kArm64Mov32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0))); |
| 1061 } | 1042 } |
| 1062 | 1043 |
| 1063 | 1044 |
| 1045 void InstructionSelector::VisitFloat32Add(Node* node) { |
| 1046 VisitRRR(this, kArm64Float32Add, node); |
| 1047 } |
| 1048 |
| 1049 |
| 1064 void InstructionSelector::VisitFloat64Add(Node* node) { | 1050 void InstructionSelector::VisitFloat64Add(Node* node) { |
| 1065 VisitRRRFloat64(this, kArm64Float64Add, node); | 1051 VisitRRR(this, kArm64Float64Add, node); |
| 1066 } | 1052 } |
| 1067 | 1053 |
| 1068 | 1054 |
| 1055 void InstructionSelector::VisitFloat32Sub(Node* node) { |
| 1056 VisitRRR(this, kArm64Float32Sub, node); |
| 1057 } |
| 1058 |
| 1059 |
| 1069 void InstructionSelector::VisitFloat64Sub(Node* node) { | 1060 void InstructionSelector::VisitFloat64Sub(Node* node) { |
| 1070 Arm64OperandGenerator g(this); | 1061 Arm64OperandGenerator g(this); |
| 1071 Float64BinopMatcher m(node); | 1062 Float64BinopMatcher m(node); |
| 1072 if (m.left().IsMinusZero() && m.right().IsFloat64RoundDown() && | 1063 if (m.left().IsMinusZero() && m.right().IsFloat64RoundDown() && |
| 1073 CanCover(m.node(), m.right().node())) { | 1064 CanCover(m.node(), m.right().node())) { |
| 1074 if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub && | 1065 if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub && |
| 1075 CanCover(m.right().node(), m.right().InputAt(0))) { | 1066 CanCover(m.right().node(), m.right().InputAt(0))) { |
| 1076 Float64BinopMatcher mright0(m.right().InputAt(0)); | 1067 Float64BinopMatcher mright0(m.right().InputAt(0)); |
| 1077 if (mright0.left().IsMinusZero()) { | 1068 if (mright0.left().IsMinusZero()) { |
| 1078 Emit(kArm64Float64RoundUp, g.DefineAsRegister(node), | 1069 Emit(kArm64Float64RoundUp, g.DefineAsRegister(node), |
| 1079 g.UseRegister(mright0.right().node())); | 1070 g.UseRegister(mright0.right().node())); |
| 1080 return; | 1071 return; |
| 1081 } | 1072 } |
| 1082 } | 1073 } |
| 1083 } | 1074 } |
| 1084 VisitRRRFloat64(this, kArm64Float64Sub, node); | 1075 VisitRRR(this, kArm64Float64Sub, node); |
| 1076 } |
| 1077 |
| 1078 |
| 1079 void InstructionSelector::VisitFloat32Mul(Node* node) { |
| 1080 VisitRRR(this, kArm64Float32Mul, node); |
| 1085 } | 1081 } |
| 1086 | 1082 |
| 1087 | 1083 |
| 1088 void InstructionSelector::VisitFloat64Mul(Node* node) { | 1084 void InstructionSelector::VisitFloat64Mul(Node* node) { |
| 1089 VisitRRRFloat64(this, kArm64Float64Mul, node); | 1085 VisitRRR(this, kArm64Float64Mul, node); |
| 1086 } |
| 1087 |
| 1088 |
| 1089 void InstructionSelector::VisitFloat32Div(Node* node) { |
| 1090 VisitRRR(this, kArm64Float32Div, node); |
| 1090 } | 1091 } |
| 1091 | 1092 |
| 1092 | 1093 |
| 1093 void InstructionSelector::VisitFloat64Div(Node* node) { | 1094 void InstructionSelector::VisitFloat64Div(Node* node) { |
| 1094 VisitRRRFloat64(this, kArm64Float64Div, node); | 1095 VisitRRR(this, kArm64Float64Div, node); |
| 1095 } | 1096 } |
| 1096 | 1097 |
| 1097 | 1098 |
| 1098 void InstructionSelector::VisitFloat64Mod(Node* node) { | 1099 void InstructionSelector::VisitFloat64Mod(Node* node) { |
| 1099 Arm64OperandGenerator g(this); | 1100 Arm64OperandGenerator g(this); |
| 1100 Emit(kArm64Float64Mod, g.DefineAsFixed(node, d0), | 1101 Emit(kArm64Float64Mod, g.DefineAsFixed(node, d0), |
| 1101 g.UseFixed(node->InputAt(0), d0), | 1102 g.UseFixed(node->InputAt(0), d0), |
| 1102 g.UseFixed(node->InputAt(1), d1))->MarkAsCall(); | 1103 g.UseFixed(node->InputAt(1), d1))->MarkAsCall(); |
| 1103 } | 1104 } |
| 1104 | 1105 |
| 1105 | 1106 |
| 1107 void InstructionSelector::VisitFloat32Max(Node* node) { |
| 1108 VisitRRR(this, kArm64Float32Max, node); |
| 1109 } |
| 1110 |
| 1111 |
| 1106 void InstructionSelector::VisitFloat64Max(Node* node) { | 1112 void InstructionSelector::VisitFloat64Max(Node* node) { |
| 1107 Arm64OperandGenerator g(this); | 1113 VisitRRR(this, kArm64Float64Max, node); |
| 1108 Node* left = node->InputAt(0); | 1114 } |
| 1109 Node* right = node->InputAt(1); | 1115 |
| 1110 Emit(kArm64Float64Max, g.DefineAsRegister(node), g.UseRegister(left), | 1116 |
| 1111 g.UseRegister(right)); | 1117 void InstructionSelector::VisitFloat32Min(Node* node) { |
| 1118 VisitRRR(this, kArm64Float32Min, node); |
| 1112 } | 1119 } |
| 1113 | 1120 |
| 1114 | 1121 |
| 1115 void InstructionSelector::VisitFloat64Min(Node* node) { | 1122 void InstructionSelector::VisitFloat64Min(Node* node) { |
| 1116 Arm64OperandGenerator g(this); | 1123 VisitRRR(this, kArm64Float64Min, node); |
| 1117 Node* left = node->InputAt(0); | 1124 } |
| 1118 Node* right = node->InputAt(1); | 1125 |
| 1119 Emit(kArm64Float64Min, g.DefineAsRegister(node), g.UseRegister(left), | 1126 |
| 1120 g.UseRegister(right)); | 1127 void InstructionSelector::VisitFloat32Sqrt(Node* node) { |
| 1128 VisitRR(this, kArm64Float32Sqrt, node); |
| 1121 } | 1129 } |
| 1122 | 1130 |
| 1123 | 1131 |
| 1124 void InstructionSelector::VisitFloat64Sqrt(Node* node) { | 1132 void InstructionSelector::VisitFloat64Sqrt(Node* node) { |
| 1125 VisitRRFloat64(this, kArm64Float64Sqrt, node); | 1133 VisitRR(this, kArm64Float64Sqrt, node); |
| 1126 } | 1134 } |
| 1127 | 1135 |
| 1128 | 1136 |
| 1129 void InstructionSelector::VisitFloat64RoundDown(Node* node) { | 1137 void InstructionSelector::VisitFloat64RoundDown(Node* node) { |
| 1130 VisitRRFloat64(this, kArm64Float64RoundDown, node); | 1138 VisitRR(this, kArm64Float64RoundDown, node); |
| 1131 } | 1139 } |
| 1132 | 1140 |
| 1133 | 1141 |
| 1134 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { | 1142 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { |
| 1135 VisitRRFloat64(this, kArm64Float64RoundTruncate, node); | 1143 VisitRR(this, kArm64Float64RoundTruncate, node); |
| 1136 } | 1144 } |
| 1137 | 1145 |
| 1138 | 1146 |
| 1139 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | 1147 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { |
| 1140 VisitRRFloat64(this, kArm64Float64RoundTiesAway, node); | 1148 VisitRR(this, kArm64Float64RoundTiesAway, node); |
| 1141 } | 1149 } |
| 1142 | 1150 |
| 1143 | 1151 |
| 1144 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { | 1152 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { |
| 1145 Arm64OperandGenerator g(this); | 1153 Arm64OperandGenerator g(this); |
| 1146 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); | 1154 const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node); |
| 1147 | 1155 |
| 1148 FrameStateDescriptor* frame_state_descriptor = NULL; | 1156 FrameStateDescriptor* frame_state_descriptor = NULL; |
| 1149 if (descriptor->NeedsFrameState()) { | 1157 if (descriptor->NeedsFrameState()) { |
| 1150 frame_state_descriptor = | 1158 frame_state_descriptor = |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1215 // Emit the call instruction. | 1223 // Emit the call instruction. |
| 1216 InstructionOperand* first_output = | 1224 InstructionOperand* first_output = |
| 1217 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; | 1225 buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; |
| 1218 Instruction* call_instr = | 1226 Instruction* call_instr = |
| 1219 Emit(opcode, buffer.outputs.size(), first_output, | 1227 Emit(opcode, buffer.outputs.size(), first_output, |
| 1220 buffer.instruction_args.size(), &buffer.instruction_args.front()); | 1228 buffer.instruction_args.size(), &buffer.instruction_args.front()); |
| 1221 call_instr->MarkAsCall(); | 1229 call_instr->MarkAsCall(); |
| 1222 } | 1230 } |
| 1223 | 1231 |
| 1224 | 1232 |
| 1233 namespace { |
| 1234 |
| 1225 // Shared routine for multiple compare operations. | 1235 // Shared routine for multiple compare operations. |
| 1226 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | 1236 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, |
| 1227 InstructionOperand left, InstructionOperand right, | 1237 InstructionOperand left, InstructionOperand right, |
| 1228 FlagsContinuation* cont) { | 1238 FlagsContinuation* cont) { |
| 1229 Arm64OperandGenerator g(selector); | 1239 Arm64OperandGenerator g(selector); |
| 1230 opcode = cont->Encode(opcode); | 1240 opcode = cont->Encode(opcode); |
| 1231 if (cont->IsBranch()) { | 1241 if (cont->IsBranch()) { |
| 1232 selector->Emit(opcode, g.NoOutput(), left, right, | 1242 selector->Emit(opcode, g.NoOutput(), left, right, |
| 1233 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1243 g.Label(cont->true_block()), g.Label(cont->false_block())); |
| 1234 } else { | 1244 } else { |
| 1235 DCHECK(cont->IsSet()); | 1245 DCHECK(cont->IsSet()); |
| 1236 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); | 1246 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); |
| 1237 } | 1247 } |
| 1238 } | 1248 } |
| 1239 | 1249 |
| 1240 | 1250 |
| 1241 // Shared routine for multiple word compare operations. | 1251 // Shared routine for multiple word compare operations. |
| 1242 static void VisitWordCompare(InstructionSelector* selector, Node* node, | 1252 void VisitWordCompare(InstructionSelector* selector, Node* node, |
| 1243 InstructionCode opcode, FlagsContinuation* cont, | 1253 InstructionCode opcode, FlagsContinuation* cont, |
| 1244 bool commutative, ImmediateMode immediate_mode) { | 1254 bool commutative, ImmediateMode immediate_mode) { |
| 1245 Arm64OperandGenerator g(selector); | 1255 Arm64OperandGenerator g(selector); |
| 1246 Node* left = node->InputAt(0); | 1256 Node* left = node->InputAt(0); |
| 1247 Node* right = node->InputAt(1); | 1257 Node* right = node->InputAt(1); |
| 1248 | 1258 |
| 1249 // Match immediates on left or right side of comparison. | 1259 // Match immediates on left or right side of comparison. |
| 1250 if (g.CanBeImmediate(right, immediate_mode)) { | 1260 if (g.CanBeImmediate(right, immediate_mode)) { |
| 1251 VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right), | 1261 VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right), |
| 1252 cont); | 1262 cont); |
| 1253 } else if (g.CanBeImmediate(left, immediate_mode)) { | 1263 } else if (g.CanBeImmediate(left, immediate_mode)) { |
| 1254 if (!commutative) cont->Commute(); | 1264 if (!commutative) cont->Commute(); |
| 1255 VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left), | 1265 VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left), |
| 1256 cont); | 1266 cont); |
| 1257 } else { | 1267 } else { |
| 1258 VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right), | 1268 VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right), |
| 1259 cont); | 1269 cont); |
| 1260 } | 1270 } |
| 1261 } | 1271 } |
| 1262 | 1272 |
| 1263 | 1273 |
| 1264 static void VisitWord32Compare(InstructionSelector* selector, Node* node, | 1274 void VisitWord32Compare(InstructionSelector* selector, Node* node, |
| 1265 FlagsContinuation* cont) { | 1275 FlagsContinuation* cont) { |
| 1266 VisitWordCompare(selector, node, kArm64Cmp32, cont, false, kArithmeticImm); | 1276 VisitWordCompare(selector, node, kArm64Cmp32, cont, false, kArithmeticImm); |
| 1267 } | 1277 } |
| 1268 | 1278 |
| 1269 | 1279 |
| 1270 static void VisitWordTest(InstructionSelector* selector, Node* node, | 1280 void VisitWordTest(InstructionSelector* selector, Node* node, |
| 1271 InstructionCode opcode, FlagsContinuation* cont) { | 1281 InstructionCode opcode, FlagsContinuation* cont) { |
| 1272 Arm64OperandGenerator g(selector); | 1282 Arm64OperandGenerator g(selector); |
| 1273 VisitCompare(selector, opcode, g.UseRegister(node), g.UseRegister(node), | 1283 VisitCompare(selector, opcode, g.UseRegister(node), g.UseRegister(node), |
| 1274 cont); | 1284 cont); |
| 1275 } | 1285 } |
| 1276 | 1286 |
| 1277 | 1287 |
| 1278 static void VisitWord32Test(InstructionSelector* selector, Node* node, | 1288 void VisitWord32Test(InstructionSelector* selector, Node* node, |
| 1279 FlagsContinuation* cont) { | 1289 FlagsContinuation* cont) { |
| 1280 VisitWordTest(selector, node, kArm64Tst32, cont); | 1290 VisitWordTest(selector, node, kArm64Tst32, cont); |
| 1281 } | 1291 } |
| 1282 | 1292 |
| 1283 | 1293 |
| 1284 static void VisitWord64Test(InstructionSelector* selector, Node* node, | 1294 void VisitWord64Test(InstructionSelector* selector, Node* node, |
| 1285 FlagsContinuation* cont) { | 1295 FlagsContinuation* cont) { |
| 1286 VisitWordTest(selector, node, kArm64Tst, cont); | 1296 VisitWordTest(selector, node, kArm64Tst, cont); |
| 1287 } | 1297 } |
| 1288 | 1298 |
| 1289 | 1299 |
| 1290 // Shared routine for multiple float compare operations. | 1300 // Shared routine for multiple float64 compare operations. |
| 1291 static void VisitFloat64Compare(InstructionSelector* selector, Node* node, | 1301 void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
| 1292 FlagsContinuation* cont) { | 1302 FlagsContinuation* cont) { |
| 1303 Arm64OperandGenerator g(selector); |
| 1304 Float32BinopMatcher m(node); |
| 1305 if (m.right().Is(0.0f)) { |
| 1306 VisitCompare(selector, kArm64Float32Cmp, g.UseRegister(m.left().node()), |
| 1307 g.UseImmediate(m.right().node()), cont); |
| 1308 } else { |
| 1309 VisitCompare(selector, kArm64Float32Cmp, g.UseRegister(m.left().node()), |
| 1310 g.UseRegister(m.right().node()), cont); |
| 1311 } |
| 1312 } |
| 1313 |
| 1314 |
| 1315 // Shared routine for multiple float64 compare operations. |
| 1316 void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
| 1317 FlagsContinuation* cont) { |
| 1293 Arm64OperandGenerator g(selector); | 1318 Arm64OperandGenerator g(selector); |
| 1294 Float64BinopMatcher m(node); | 1319 Float64BinopMatcher m(node); |
| 1295 if (m.right().Is(0.0)) { | 1320 if (m.right().Is(0.0)) { |
| 1296 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.left().node()), | 1321 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.left().node()), |
| 1297 g.UseImmediate(m.right().node()), cont); | 1322 g.UseImmediate(m.right().node()), cont); |
| 1298 } else { | 1323 } else { |
| 1299 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.left().node()), | 1324 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.left().node()), |
| 1300 g.UseRegister(m.right().node()), cont); | 1325 g.UseRegister(m.right().node()), cont); |
| 1301 } | 1326 } |
| 1302 } | 1327 } |
| 1303 | 1328 |
| 1329 } // namespace |
| 1330 |
| 1304 | 1331 |
| 1305 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, | 1332 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
| 1306 BasicBlock* fbranch) { | 1333 BasicBlock* fbranch) { |
| 1307 OperandGenerator g(this); | 1334 OperandGenerator g(this); |
| 1308 Node* user = branch; | 1335 Node* user = branch; |
| 1309 Node* value = branch->InputAt(0); | 1336 Node* value = branch->InputAt(0); |
| 1310 | 1337 |
| 1311 FlagsContinuation cont(kNotEqual, tbranch, fbranch); | 1338 FlagsContinuation cont(kNotEqual, tbranch, fbranch); |
| 1312 | 1339 |
| 1313 // Try to combine with comparisons against 0 by simply inverting the branch. | 1340 // Try to combine with comparisons against 0 by simply inverting the branch. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1349 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, | 1376 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, |
| 1350 kArithmeticImm); | 1377 kArithmeticImm); |
| 1351 case IrOpcode::kInt64LessThanOrEqual: | 1378 case IrOpcode::kInt64LessThanOrEqual: |
| 1352 cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); | 1379 cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); |
| 1353 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, | 1380 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, |
| 1354 kArithmeticImm); | 1381 kArithmeticImm); |
| 1355 case IrOpcode::kUint64LessThan: | 1382 case IrOpcode::kUint64LessThan: |
| 1356 cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); | 1383 cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); |
| 1357 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, | 1384 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, |
| 1358 kArithmeticImm); | 1385 kArithmeticImm); |
| 1386 case IrOpcode::kFloat32Equal: |
| 1387 cont.OverwriteAndNegateIfEqual(kEqual); |
| 1388 return VisitFloat32Compare(this, value, &cont); |
| 1389 case IrOpcode::kFloat32LessThan: |
| 1390 cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); |
| 1391 return VisitFloat32Compare(this, value, &cont); |
| 1392 case IrOpcode::kFloat32LessThanOrEqual: |
| 1393 cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); |
| 1394 return VisitFloat32Compare(this, value, &cont); |
| 1359 case IrOpcode::kFloat64Equal: | 1395 case IrOpcode::kFloat64Equal: |
| 1360 cont.OverwriteAndNegateIfEqual(kEqual); | 1396 cont.OverwriteAndNegateIfEqual(kEqual); |
| 1361 return VisitFloat64Compare(this, value, &cont); | 1397 return VisitFloat64Compare(this, value, &cont); |
| 1362 case IrOpcode::kFloat64LessThan: | 1398 case IrOpcode::kFloat64LessThan: |
| 1363 cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); | 1399 cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); |
| 1364 return VisitFloat64Compare(this, value, &cont); | 1400 return VisitFloat64Compare(this, value, &cont); |
| 1365 case IrOpcode::kFloat64LessThanOrEqual: | 1401 case IrOpcode::kFloat64LessThanOrEqual: |
| 1366 cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); | 1402 cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); |
| 1367 return VisitFloat64Compare(this, value, &cont); | 1403 return VisitFloat64Compare(this, value, &cont); |
| 1368 case IrOpcode::kProjection: | 1404 case IrOpcode::kProjection: |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1577 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); | 1613 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); |
| 1578 } | 1614 } |
| 1579 | 1615 |
| 1580 | 1616 |
| 1581 void InstructionSelector::VisitUint64LessThan(Node* node) { | 1617 void InstructionSelector::VisitUint64LessThan(Node* node) { |
| 1582 FlagsContinuation cont(kUnsignedLessThan, node); | 1618 FlagsContinuation cont(kUnsignedLessThan, node); |
| 1583 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); | 1619 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); |
| 1584 } | 1620 } |
| 1585 | 1621 |
| 1586 | 1622 |
| 1623 void InstructionSelector::VisitFloat32Equal(Node* node) { |
| 1624 FlagsContinuation cont(kEqual, node); |
| 1625 VisitFloat32Compare(this, node, &cont); |
| 1626 } |
| 1627 |
| 1628 |
| 1629 void InstructionSelector::VisitFloat32LessThan(Node* node) { |
| 1630 FlagsContinuation cont(kUnsignedLessThan, node); |
| 1631 VisitFloat32Compare(this, node, &cont); |
| 1632 } |
| 1633 |
| 1634 |
| 1635 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { |
| 1636 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); |
| 1637 VisitFloat32Compare(this, node, &cont); |
| 1638 } |
| 1639 |
| 1640 |
| 1587 void InstructionSelector::VisitFloat64Equal(Node* node) { | 1641 void InstructionSelector::VisitFloat64Equal(Node* node) { |
| 1588 FlagsContinuation cont(kEqual, node); | 1642 FlagsContinuation cont(kEqual, node); |
| 1589 VisitFloat64Compare(this, node, &cont); | 1643 VisitFloat64Compare(this, node, &cont); |
| 1590 } | 1644 } |
| 1591 | 1645 |
| 1592 | 1646 |
| 1593 void InstructionSelector::VisitFloat64LessThan(Node* node) { | 1647 void InstructionSelector::VisitFloat64LessThan(Node* node) { |
| 1594 FlagsContinuation cont(kUnsignedLessThan, node); | 1648 FlagsContinuation cont(kUnsignedLessThan, node); |
| 1595 VisitFloat64Compare(this, node, &cont); | 1649 VisitFloat64Compare(this, node, &cont); |
| 1596 } | 1650 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1647 return; | 1701 return; |
| 1648 } | 1702 } |
| 1649 Emit(kArm64Float64InsertHighWord32, g.DefineAsRegister(node), | 1703 Emit(kArm64Float64InsertHighWord32, g.DefineAsRegister(node), |
| 1650 g.UseRegister(left), g.UseRegister(right)); | 1704 g.UseRegister(left), g.UseRegister(right)); |
| 1651 } | 1705 } |
| 1652 | 1706 |
| 1653 | 1707 |
| 1654 // static | 1708 // static |
| 1655 MachineOperatorBuilder::Flags | 1709 MachineOperatorBuilder::Flags |
| 1656 InstructionSelector::SupportedMachineOperatorFlags() { | 1710 InstructionSelector::SupportedMachineOperatorFlags() { |
| 1657 return MachineOperatorBuilder::kFloat64RoundDown | | 1711 return MachineOperatorBuilder::kFloat32Max | |
| 1712 MachineOperatorBuilder::kFloat32Min | |
| 1713 MachineOperatorBuilder::kFloat64Max | |
| 1714 MachineOperatorBuilder::kFloat64Min | |
| 1715 MachineOperatorBuilder::kFloat64RoundDown | |
| 1658 MachineOperatorBuilder::kFloat64RoundTruncate | | 1716 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 1659 MachineOperatorBuilder::kFloat64RoundTiesAway | | 1717 MachineOperatorBuilder::kFloat64RoundTiesAway | |
| 1660 MachineOperatorBuilder::kFloat64Max | | |
| 1661 MachineOperatorBuilder::kFloat64Min | | |
| 1662 MachineOperatorBuilder::kWord32ShiftIsSafe | | 1718 MachineOperatorBuilder::kWord32ShiftIsSafe | |
| 1663 MachineOperatorBuilder::kInt32DivIsSafe | | 1719 MachineOperatorBuilder::kInt32DivIsSafe | |
| 1664 MachineOperatorBuilder::kUint32DivIsSafe; | 1720 MachineOperatorBuilder::kUint32DivIsSafe; |
| 1665 } | 1721 } |
| 1666 | 1722 |
| 1667 } // namespace compiler | 1723 } // namespace compiler |
| 1668 } // namespace internal | 1724 } // namespace internal |
| 1669 } // namespace v8 | 1725 } // namespace v8 |
| OLD | NEW |