| 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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 return kMode_MR1; | 172 return kMode_MR1; |
| 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 ArchOpcode GetLoadOpcode(LoadRepresentation load_rep, bool protect) { | 182 ArchOpcode GetLoadOpcode(LoadRepresentation load_rep) { |
| 183 ArchOpcode opcode = kArchNop; | 183 ArchOpcode opcode = kArchNop; |
| 184 switch (load_rep.representation()) { | 184 switch (load_rep.representation()) { |
| 185 case MachineRepresentation::kFloat32: | 185 case MachineRepresentation::kFloat32: |
| 186 opcode = kX64Movss; | 186 opcode = kX64Movss; |
| 187 break; | 187 break; |
| 188 case MachineRepresentation::kFloat64: | 188 case MachineRepresentation::kFloat64: |
| 189 opcode = kX64Movsd; | 189 opcode = kX64Movsd; |
| 190 break; | 190 break; |
| 191 case MachineRepresentation::kBit: // Fall through. | 191 case MachineRepresentation::kBit: // Fall through. |
| 192 case MachineRepresentation::kWord8: | 192 case MachineRepresentation::kWord8: |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 UNREACHABLE(); | 244 UNREACHABLE(); |
| 245 return kArchNop; | 245 return kArchNop; |
| 246 } | 246 } |
| 247 | 247 |
| 248 } // namespace | 248 } // namespace |
| 249 | 249 |
| 250 void InstructionSelector::VisitLoad(Node* node) { | 250 void InstructionSelector::VisitLoad(Node* node) { |
| 251 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); | 251 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
| 252 X64OperandGenerator g(this); | 252 X64OperandGenerator g(this); |
| 253 | 253 |
| 254 const bool protect = false; | 254 ArchOpcode opcode = GetLoadOpcode(load_rep); |
| 255 ArchOpcode opcode = GetLoadOpcode(load_rep, protect); | |
| 256 InstructionOperand outputs[1]; | |
| 257 outputs[0] = g.DefineAsRegister(node); | |
| 258 InstructionOperand inputs[3]; | |
| 259 size_t input_count = 0; | |
| 260 AddressingMode mode = | |
| 261 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | |
| 262 InstructionCode code = opcode | AddressingModeField::encode(mode); | |
| 263 Emit(code, 1, outputs, input_count, inputs); | |
| 264 } | |
| 265 | |
| 266 void InstructionSelector::VisitProtectedLoad(Node* node) { | |
| 267 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); | |
| 268 X64OperandGenerator g(this); | |
| 269 | |
| 270 const bool protect = true; | |
| 271 ArchOpcode opcode = GetLoadOpcode(load_rep, protect); | |
| 272 InstructionOperand outputs[1]; | 255 InstructionOperand outputs[1]; |
| 273 outputs[0] = g.DefineAsRegister(node); | 256 outputs[0] = g.DefineAsRegister(node); |
| 274 InstructionOperand inputs[4]; | 257 InstructionOperand inputs[4]; |
| 275 size_t input_count = 0; | 258 size_t input_count = 0; |
| 276 AddressingMode mode = | 259 AddressingMode mode = |
| 277 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 260 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
| 278 // Add the context parameter as an input. | 261 InstructionCode code = opcode | AddressingModeField::encode(mode); |
| 279 inputs[input_count++] = g.UseUniqueRegister(node->InputAt(2)); | 262 if (node->opcode() == IrOpcode::kProtectedLoad) { |
| 280 // Add the source position as an input | 263 code |= MiscField::encode(X64MemoryProtection::kProtected); |
| 281 inputs[input_count++] = g.UseImmediate(node->InputAt(3)); | 264 // Add the source position as an input |
| 282 InstructionCode code = opcode | AddressingModeField::encode(mode) | | 265 inputs[input_count++] = g.UseImmediate(node->InputAt(2)); |
| 283 MiscField::encode(X64MemoryProtection::kProtected); | 266 } |
| 284 Emit(code, 1, outputs, input_count, inputs); | 267 Emit(code, 1, outputs, input_count, inputs); |
| 285 } | 268 } |
| 286 | 269 |
| 270 void InstructionSelector::VisitProtectedLoad(Node* node) { VisitLoad(node); } |
| 271 |
| 287 void InstructionSelector::VisitStore(Node* node) { | 272 void InstructionSelector::VisitStore(Node* node) { |
| 288 X64OperandGenerator g(this); | 273 X64OperandGenerator g(this); |
| 289 Node* base = node->InputAt(0); | 274 Node* base = node->InputAt(0); |
| 290 Node* index = node->InputAt(1); | 275 Node* index = node->InputAt(1); |
| 291 Node* value = node->InputAt(2); | 276 Node* value = node->InputAt(2); |
| 292 | 277 |
| 293 StoreRepresentation store_rep = StoreRepresentationOf(node->op()); | 278 StoreRepresentation store_rep = StoreRepresentationOf(node->op()); |
| 294 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 279 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
| 295 | 280 |
| 296 if (write_barrier_kind != kNoWriteBarrier) { | 281 if (write_barrier_kind != kNoWriteBarrier) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); | 325 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); |
| 341 inputs[input_count++] = value_operand; | 326 inputs[input_count++] = value_operand; |
| 342 Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count, | 327 Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count, |
| 343 inputs); | 328 inputs); |
| 344 } | 329 } |
| 345 } | 330 } |
| 346 | 331 |
| 347 void InstructionSelector::VisitProtectedStore(Node* node) { | 332 void InstructionSelector::VisitProtectedStore(Node* node) { |
| 348 X64OperandGenerator g(this); | 333 X64OperandGenerator g(this); |
| 349 Node* value = node->InputAt(2); | 334 Node* value = node->InputAt(2); |
| 350 Node* context = node->InputAt(3); | 335 Node* position = node->InputAt(3); |
| 351 Node* position = node->InputAt(4); | |
| 352 | 336 |
| 353 StoreRepresentation store_rep = StoreRepresentationOf(node->op()); | 337 StoreRepresentation store_rep = StoreRepresentationOf(node->op()); |
| 354 | 338 |
| 355 ArchOpcode opcode = GetStoreOpcode(store_rep); | 339 ArchOpcode opcode = GetStoreOpcode(store_rep); |
| 356 InstructionOperand inputs[6]; | 340 InstructionOperand inputs[5]; |
| 357 size_t input_count = 0; | 341 size_t input_count = 0; |
| 358 AddressingMode addressing_mode = | 342 AddressingMode addressing_mode = |
| 359 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 343 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
| 360 InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) | | 344 InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) | |
| 361 MiscField::encode(X64MemoryProtection::kProtected); | 345 MiscField::encode(X64MemoryProtection::kProtected); |
| 362 InstructionOperand value_operand = | 346 InstructionOperand value_operand = |
| 363 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); | 347 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); |
| 364 inputs[input_count++] = value_operand; | 348 inputs[input_count++] = value_operand; |
| 365 inputs[input_count++] = g.UseRegister(context); | |
| 366 inputs[input_count++] = g.UseImmediate(position); | 349 inputs[input_count++] = g.UseImmediate(position); |
| 367 Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count, inputs); | 350 Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count, inputs); |
| 368 } | 351 } |
| 369 | 352 |
| 370 // Architecture supports unaligned access, therefore VisitLoad is used instead | 353 // Architecture supports unaligned access, therefore VisitLoad is used instead |
| 371 void InstructionSelector::VisitUnalignedLoad(Node* node) { UNREACHABLE(); } | 354 void InstructionSelector::VisitUnalignedLoad(Node* node) { UNREACHABLE(); } |
| 372 | 355 |
| 373 // Architecture supports unaligned access, therefore VisitStore is used instead | 356 // Architecture supports unaligned access, therefore VisitStore is used instead |
| 374 void InstructionSelector::VisitUnalignedStore(Node* node) { UNREACHABLE(); } | 357 void InstructionSelector::VisitUnalignedStore(Node* node) { UNREACHABLE(); } |
| 375 | 358 |
| (...skipping 2075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2451 // static | 2434 // static |
| 2452 MachineOperatorBuilder::AlignmentRequirements | 2435 MachineOperatorBuilder::AlignmentRequirements |
| 2453 InstructionSelector::AlignmentRequirements() { | 2436 InstructionSelector::AlignmentRequirements() { |
| 2454 return MachineOperatorBuilder::AlignmentRequirements:: | 2437 return MachineOperatorBuilder::AlignmentRequirements:: |
| 2455 FullUnalignedAccessSupport(); | 2438 FullUnalignedAccessSupport(); |
| 2456 } | 2439 } |
| 2457 | 2440 |
| 2458 } // namespace compiler | 2441 } // namespace compiler |
| 2459 } // namespace internal | 2442 } // namespace internal |
| 2460 } // namespace v8 | 2443 } // namespace v8 |
| OLD | NEW |