Chromium Code Reviews| 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 <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include "src/base/adapters.h" | 7 #include "src/base/adapters.h" |
| 8 #include "src/compiler/instruction-selector-impl.h" | 8 #include "src/compiler/instruction-selector-impl.h" |
| 9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
| 10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 } | 173 } |
| 174 } | 174 } |
| 175 | 175 |
| 176 bool CanBeBetterLeftOperand(Node* node) const { | 176 bool CanBeBetterLeftOperand(Node* node) const { |
| 177 return !selector()->IsLive(node); | 177 return !selector()->IsLive(node); |
| 178 } | 178 } |
| 179 }; | 179 }; |
| 180 | 180 |
| 181 namespace { | 181 namespace { |
| 182 | 182 |
| 183 ArchOpcode GetLoadOpcode(LoadRepresentation load_rep) { | 183 ArchOpcode GetLoadOpcode(LoadRepresentation load_rep, bool protect) { |
| 184 ArchOpcode opcode = kArchNop; | 184 ArchOpcode opcode = kArchNop; |
| 185 switch (load_rep.representation()) { | 185 switch (load_rep.representation()) { |
| 186 case MachineRepresentation::kFloat32: | 186 case MachineRepresentation::kFloat32: |
| 187 DCHECK(!protect); | |
|
titzer
2016/11/22 10:33:20
We'll need to support all of these types with prot
Eric Holk
2016/11/22 23:16:25
I think this is a better idea. It looks like I can
| |
| 187 opcode = kX64Movss; | 188 opcode = kX64Movss; |
| 188 break; | 189 break; |
| 189 case MachineRepresentation::kFloat64: | 190 case MachineRepresentation::kFloat64: |
| 191 DCHECK(!protect); | |
| 190 opcode = kX64Movsd; | 192 opcode = kX64Movsd; |
| 191 break; | 193 break; |
| 192 case MachineRepresentation::kBit: // Fall through. | 194 case MachineRepresentation::kBit: // Fall through. |
| 193 case MachineRepresentation::kWord8: | 195 case MachineRepresentation::kWord8: |
| 196 DCHECK(!protect); | |
| 194 opcode = load_rep.IsSigned() ? kX64Movsxbl : kX64Movzxbl; | 197 opcode = load_rep.IsSigned() ? kX64Movsxbl : kX64Movzxbl; |
| 195 break; | 198 break; |
| 196 case MachineRepresentation::kWord16: | 199 case MachineRepresentation::kWord16: |
| 200 DCHECK(!protect); | |
| 197 opcode = load_rep.IsSigned() ? kX64Movsxwl : kX64Movzxwl; | 201 opcode = load_rep.IsSigned() ? kX64Movsxwl : kX64Movzxwl; |
| 198 break; | 202 break; |
| 199 case MachineRepresentation::kWord32: | 203 case MachineRepresentation::kWord32: |
| 200 opcode = kX64Movl; | 204 opcode = protect ? kX64TrapMovl : kX64Movl; |
| 201 break; | 205 break; |
| 202 case MachineRepresentation::kTaggedSigned: // Fall through. | 206 case MachineRepresentation::kTaggedSigned: // Fall through. |
| 203 case MachineRepresentation::kTaggedPointer: // Fall through. | 207 case MachineRepresentation::kTaggedPointer: // Fall through. |
| 204 case MachineRepresentation::kTagged: // Fall through. | 208 case MachineRepresentation::kTagged: // Fall through. |
| 205 case MachineRepresentation::kWord64: | 209 case MachineRepresentation::kWord64: |
| 210 DCHECK(!protect); | |
| 206 opcode = kX64Movq; | 211 opcode = kX64Movq; |
| 207 break; | 212 break; |
| 208 case MachineRepresentation::kSimd128: // Fall through. | 213 case MachineRepresentation::kSimd128: // Fall through. |
| 209 case MachineRepresentation::kNone: | 214 case MachineRepresentation::kNone: |
| 210 UNREACHABLE(); | 215 UNREACHABLE(); |
| 211 break; | 216 break; |
| 212 } | 217 } |
| 213 return opcode; | 218 return opcode; |
| 214 } | 219 } |
| 215 | 220 |
| 221 ArchOpcode GetStoreOpcode(StoreRepresentation store_rep, bool protect) { | |
| 222 switch (store_rep.representation()) { | |
| 223 case MachineRepresentation::kFloat32: | |
| 224 DCHECK(!protect); | |
| 225 return kX64Movss; | |
| 226 break; | |
| 227 case MachineRepresentation::kFloat64: | |
| 228 DCHECK(!protect); | |
| 229 return kX64Movsd; | |
| 230 break; | |
| 231 case MachineRepresentation::kBit: // Fall through. | |
| 232 case MachineRepresentation::kWord8: | |
| 233 DCHECK(!protect); | |
| 234 return kX64Movb; | |
| 235 break; | |
| 236 case MachineRepresentation::kWord16: | |
| 237 DCHECK(!protect); | |
| 238 return kX64Movw; | |
| 239 break; | |
| 240 case MachineRepresentation::kWord32: | |
| 241 return protect ? kX64TrapMovl : kX64Movl; | |
| 242 break; | |
| 243 case MachineRepresentation::kTaggedSigned: // Fall through. | |
| 244 case MachineRepresentation::kTaggedPointer: // Fall through. | |
| 245 case MachineRepresentation::kTagged: // Fall through. | |
| 246 case MachineRepresentation::kWord64: | |
| 247 DCHECK(!protect); | |
| 248 return kX64Movq; | |
| 249 break; | |
| 250 case MachineRepresentation::kSimd128: // Fall through. | |
| 251 case MachineRepresentation::kNone: | |
| 252 UNREACHABLE(); | |
| 253 return kArchNop; | |
| 254 } | |
| 255 } | |
| 256 | |
| 216 } // namespace | 257 } // namespace |
| 217 | 258 |
| 218 void InstructionSelector::VisitLoad(Node* node) { | 259 void InstructionSelector::VisitLoad(Node* node) { |
| 219 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); | 260 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
| 220 X64OperandGenerator g(this); | 261 X64OperandGenerator g(this); |
| 221 | 262 |
| 222 ArchOpcode opcode = GetLoadOpcode(load_rep); | 263 const bool protect = false; |
| 264 ArchOpcode opcode = GetLoadOpcode(load_rep, protect); | |
| 223 InstructionOperand outputs[1]; | 265 InstructionOperand outputs[1]; |
| 224 outputs[0] = g.DefineAsRegister(node); | 266 outputs[0] = g.DefineAsRegister(node); |
| 225 InstructionOperand inputs[3]; | 267 InstructionOperand inputs[3]; |
| 226 size_t input_count = 0; | 268 size_t input_count = 0; |
| 227 AddressingMode mode = | 269 AddressingMode mode = |
| 228 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 270 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
| 229 InstructionCode code = opcode | AddressingModeField::encode(mode); | 271 InstructionCode code = opcode | AddressingModeField::encode(mode); |
| 230 Emit(code, 1, outputs, input_count, inputs); | 272 Emit(code, 1, outputs, input_count, inputs); |
| 231 } | 273 } |
| 232 | 274 |
| 233 void InstructionSelector::VisitProtectedLoad(Node* node) { | 275 void InstructionSelector::VisitProtectedLoad(Node* node) { |
| 234 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); | 276 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
| 235 X64OperandGenerator g(this); | 277 X64OperandGenerator g(this); |
| 236 | 278 |
| 237 ArchOpcode opcode = GetLoadOpcode(load_rep); | 279 const bool protect = true; |
| 280 ArchOpcode opcode = GetLoadOpcode(load_rep, protect); | |
| 238 InstructionOperand outputs[1]; | 281 InstructionOperand outputs[1]; |
| 239 outputs[0] = g.DefineAsRegister(node); | 282 outputs[0] = g.DefineAsRegister(node); |
| 240 InstructionOperand inputs[4]; | 283 InstructionOperand inputs[4]; |
| 241 size_t input_count = 0; | 284 size_t input_count = 0; |
| 242 AddressingMode mode = | 285 AddressingMode mode = |
| 243 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 286 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
| 244 // Add the context parameter as an input. | 287 // Add the context parameter as an input. |
| 245 inputs[input_count++] = g.UseUniqueRegister(node->InputAt(2)); | 288 inputs[input_count++] = g.UseUniqueRegister(node->InputAt(2)); |
| 246 // Add the source position as an input | 289 // Add the source position as an input |
| 247 inputs[input_count++] = g.UseImmediate(node->InputAt(3)); | 290 inputs[input_count++] = g.UseImmediate(node->InputAt(3)); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 record_write_mode = RecordWriteMode::kValueIsAny; | 331 record_write_mode = RecordWriteMode::kValueIsAny; |
| 289 break; | 332 break; |
| 290 } | 333 } |
| 291 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 334 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
| 292 size_t const temp_count = arraysize(temps); | 335 size_t const temp_count = arraysize(temps); |
| 293 InstructionCode code = kArchStoreWithWriteBarrier; | 336 InstructionCode code = kArchStoreWithWriteBarrier; |
| 294 code |= AddressingModeField::encode(addressing_mode); | 337 code |= AddressingModeField::encode(addressing_mode); |
| 295 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 338 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
| 296 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 339 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
| 297 } else { | 340 } else { |
| 298 ArchOpcode opcode = kArchNop; | 341 const bool protect = false; |
| 299 switch (rep) { | 342 ArchOpcode opcode = GetStoreOpcode(store_rep, protect); |
| 300 case MachineRepresentation::kFloat32: | |
| 301 opcode = kX64Movss; | |
| 302 break; | |
| 303 case MachineRepresentation::kFloat64: | |
| 304 opcode = kX64Movsd; | |
| 305 break; | |
| 306 case MachineRepresentation::kBit: // Fall through. | |
| 307 case MachineRepresentation::kWord8: | |
| 308 opcode = kX64Movb; | |
| 309 break; | |
| 310 case MachineRepresentation::kWord16: | |
| 311 opcode = kX64Movw; | |
| 312 break; | |
| 313 case MachineRepresentation::kWord32: | |
| 314 opcode = kX64Movl; | |
| 315 break; | |
| 316 case MachineRepresentation::kTaggedSigned: // Fall through. | |
| 317 case MachineRepresentation::kTaggedPointer: // Fall through. | |
| 318 case MachineRepresentation::kTagged: // Fall through. | |
| 319 case MachineRepresentation::kWord64: | |
| 320 opcode = kX64Movq; | |
| 321 break; | |
| 322 case MachineRepresentation::kSimd128: // Fall through. | |
| 323 case MachineRepresentation::kNone: | |
| 324 UNREACHABLE(); | |
| 325 return; | |
| 326 } | |
| 327 InstructionOperand inputs[4]; | 343 InstructionOperand inputs[4]; |
| 328 size_t input_count = 0; | 344 size_t input_count = 0; |
| 329 AddressingMode addressing_mode = | 345 AddressingMode addressing_mode = |
| 330 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 346 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
| 331 InstructionCode code = | 347 InstructionCode code = |
| 332 opcode | AddressingModeField::encode(addressing_mode); | 348 opcode | AddressingModeField::encode(addressing_mode); |
| 333 InstructionOperand value_operand = | 349 InstructionOperand value_operand = |
| 334 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); | 350 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); |
| 335 inputs[input_count++] = value_operand; | 351 inputs[input_count++] = value_operand; |
| 336 Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count, | 352 Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count, |
| 337 inputs); | 353 inputs); |
| 338 } | 354 } |
| 339 } | 355 } |
| 340 | 356 |
| 357 void InstructionSelector::VisitProtectedStore(Node* node) { | |
| 358 X64OperandGenerator g(this); | |
| 359 Node* base = node->InputAt(0); | |
| 360 Node* index = node->InputAt(1); | |
| 361 Node* value = node->InputAt(2); | |
| 362 Node* context = node->InputAt(3); | |
| 363 Node* position = node->InputAt(4); | |
| 364 | |
| 365 StoreRepresentation store_rep = StoreRepresentationOf(node->op()); | |
| 366 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | |
| 367 MachineRepresentation rep = store_rep.representation(); | |
| 368 | |
| 369 const bool protect = true; | |
| 370 ArchOpcode opcode = GetStoreOpcode(store_rep, protect); | |
| 371 InstructionOperand inputs[6]; | |
| 372 size_t input_count = 0; | |
| 373 AddressingMode addressing_mode = | |
| 374 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | |
| 375 InstructionCode code = opcode | AddressingModeField::encode(addressing_mode); | |
| 376 InstructionOperand value_operand = | |
| 377 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); | |
| 378 inputs[input_count++] = value_operand; | |
| 379 inputs[input_count++] = g.UseRegister(context); | |
| 380 inputs[input_count++] = g.UseImmediate(position); | |
| 381 Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count, inputs); | |
| 382 } | |
| 383 | |
| 341 // Architecture supports unaligned access, therefore VisitLoad is used instead | 384 // Architecture supports unaligned access, therefore VisitLoad is used instead |
| 342 void InstructionSelector::VisitUnalignedLoad(Node* node) { UNREACHABLE(); } | 385 void InstructionSelector::VisitUnalignedLoad(Node* node) { UNREACHABLE(); } |
| 343 | 386 |
| 344 // Architecture supports unaligned access, therefore VisitStore is used instead | 387 // Architecture supports unaligned access, therefore VisitStore is used instead |
| 345 void InstructionSelector::VisitUnalignedStore(Node* node) { UNREACHABLE(); } | 388 void InstructionSelector::VisitUnalignedStore(Node* node) { UNREACHABLE(); } |
| 346 | 389 |
| 347 void InstructionSelector::VisitCheckedLoad(Node* node) { | 390 void InstructionSelector::VisitCheckedLoad(Node* node) { |
| 348 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); | 391 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
| 349 X64OperandGenerator g(this); | 392 X64OperandGenerator g(this); |
| 350 Node* const buffer = node->InputAt(0); | 393 Node* const buffer = node->InputAt(0); |
| (...skipping 2034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2385 // static | 2428 // static |
| 2386 MachineOperatorBuilder::AlignmentRequirements | 2429 MachineOperatorBuilder::AlignmentRequirements |
| 2387 InstructionSelector::AlignmentRequirements() { | 2430 InstructionSelector::AlignmentRequirements() { |
| 2388 return MachineOperatorBuilder::AlignmentRequirements:: | 2431 return MachineOperatorBuilder::AlignmentRequirements:: |
| 2389 FullUnalignedAccessSupport(); | 2432 FullUnalignedAccessSupport(); |
| 2390 } | 2433 } |
| 2391 | 2434 |
| 2392 } // namespace compiler | 2435 } // namespace compiler |
| 2393 } // namespace internal | 2436 } // namespace internal |
| 2394 } // namespace v8 | 2437 } // namespace v8 |
| OLD | NEW |