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-intrinsics.h" | 7 #include "src/compiler-intrinsics.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 | 309 |
310 | 310 |
311 static void VisitBinop(InstructionSelector* selector, Node* node, | 311 static void VisitBinop(InstructionSelector* selector, Node* node, |
312 InstructionCode opcode, InstructionCode reverse_opcode) { | 312 InstructionCode opcode, InstructionCode reverse_opcode) { |
313 FlagsContinuation cont; | 313 FlagsContinuation cont; |
314 VisitBinop(selector, node, opcode, reverse_opcode, &cont); | 314 VisitBinop(selector, node, opcode, reverse_opcode, &cont); |
315 } | 315 } |
316 | 316 |
317 | 317 |
318 void InstructionSelector::VisitLoad(Node* node) { | 318 void InstructionSelector::VisitLoad(Node* node) { |
319 MachineType rep = OpParameter<MachineType>(node); | 319 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); |
320 ArmOperandGenerator g(this); | 320 ArmOperandGenerator g(this); |
321 Node* base = node->InputAt(0); | 321 Node* base = node->InputAt(0); |
322 Node* index = node->InputAt(1); | 322 Node* index = node->InputAt(1); |
323 | 323 |
324 InstructionOperand* result = rep == kMachineFloat64 | 324 InstructionOperand* result = rep == kRepFloat64 |
325 ? g.DefineAsDoubleRegister(node) | 325 ? g.DefineAsDoubleRegister(node) |
326 : g.DefineAsRegister(node); | 326 : g.DefineAsRegister(node); |
327 | 327 |
328 ArchOpcode opcode; | 328 ArchOpcode opcode; |
| 329 // TODO(titzer): signed/unsigned small loads |
329 switch (rep) { | 330 switch (rep) { |
330 case kMachineFloat64: | 331 case kRepFloat64: |
331 opcode = kArmFloat64Load; | 332 opcode = kArmFloat64Load; |
332 break; | 333 break; |
333 case kMachineWord8: | 334 case kRepBit: // Fall through. |
| 335 case kRepWord8: |
334 opcode = kArmLoadWord8; | 336 opcode = kArmLoadWord8; |
335 break; | 337 break; |
336 case kMachineWord16: | 338 case kRepWord16: |
337 opcode = kArmLoadWord16; | 339 opcode = kArmLoadWord16; |
338 break; | 340 break; |
339 case kMachineTagged: // Fall through. | 341 case kRepTagged: // Fall through. |
340 case kMachineWord32: | 342 case kRepWord32: |
341 opcode = kArmLoadWord32; | 343 opcode = kArmLoadWord32; |
342 break; | 344 break; |
343 default: | 345 default: |
344 UNREACHABLE(); | 346 UNREACHABLE(); |
345 return; | 347 return; |
346 } | 348 } |
347 | 349 |
348 if (g.CanBeImmediate(index, opcode)) { | 350 if (g.CanBeImmediate(index, opcode)) { |
349 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), result, | 351 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), result, |
350 g.UseRegister(base), g.UseImmediate(index)); | 352 g.UseRegister(base), g.UseImmediate(index)); |
351 } else if (g.CanBeImmediate(base, opcode)) { | 353 } else if (g.CanBeImmediate(base, opcode)) { |
352 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), result, | 354 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), result, |
353 g.UseRegister(index), g.UseImmediate(base)); | 355 g.UseRegister(index), g.UseImmediate(base)); |
354 } else { | 356 } else { |
355 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), result, | 357 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), result, |
356 g.UseRegister(base), g.UseRegister(index)); | 358 g.UseRegister(base), g.UseRegister(index)); |
357 } | 359 } |
358 } | 360 } |
359 | 361 |
360 | 362 |
361 void InstructionSelector::VisitStore(Node* node) { | 363 void InstructionSelector::VisitStore(Node* node) { |
362 ArmOperandGenerator g(this); | 364 ArmOperandGenerator g(this); |
363 Node* base = node->InputAt(0); | 365 Node* base = node->InputAt(0); |
364 Node* index = node->InputAt(1); | 366 Node* index = node->InputAt(1); |
365 Node* value = node->InputAt(2); | 367 Node* value = node->InputAt(2); |
366 | 368 |
367 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 369 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
368 MachineType rep = store_rep.rep; | 370 MachineType rep = RepresentationOf(store_rep.machine_type); |
369 if (store_rep.write_barrier_kind == kFullWriteBarrier) { | 371 if (store_rep.write_barrier_kind == kFullWriteBarrier) { |
370 DCHECK(rep == kMachineTagged); | 372 DCHECK(rep == kRepTagged); |
371 // TODO(dcarney): refactor RecordWrite function to take temp registers | 373 // TODO(dcarney): refactor RecordWrite function to take temp registers |
372 // and pass them here instead of using fixed regs | 374 // and pass them here instead of using fixed regs |
373 // TODO(dcarney): handle immediate indices. | 375 // TODO(dcarney): handle immediate indices. |
374 InstructionOperand* temps[] = {g.TempRegister(r5), g.TempRegister(r6)}; | 376 InstructionOperand* temps[] = {g.TempRegister(r5), g.TempRegister(r6)}; |
375 Emit(kArmStoreWriteBarrier, NULL, g.UseFixed(base, r4), | 377 Emit(kArmStoreWriteBarrier, NULL, g.UseFixed(base, r4), |
376 g.UseFixed(index, r5), g.UseFixed(value, r6), ARRAY_SIZE(temps), | 378 g.UseFixed(index, r5), g.UseFixed(value, r6), ARRAY_SIZE(temps), |
377 temps); | 379 temps); |
378 return; | 380 return; |
379 } | 381 } |
380 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind); | 382 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind); |
381 InstructionOperand* val = rep == kMachineFloat64 ? g.UseDoubleRegister(value) | 383 InstructionOperand* val = |
382 : g.UseRegister(value); | 384 rep == kRepFloat64 ? g.UseDoubleRegister(value) : g.UseRegister(value); |
383 | 385 |
384 ArchOpcode opcode; | 386 ArchOpcode opcode; |
385 switch (rep) { | 387 switch (rep) { |
386 case kMachineFloat64: | 388 case kRepFloat64: |
387 opcode = kArmFloat64Store; | 389 opcode = kArmFloat64Store; |
388 break; | 390 break; |
389 case kMachineWord8: | 391 case kRepBit: // Fall through. |
| 392 case kRepWord8: |
390 opcode = kArmStoreWord8; | 393 opcode = kArmStoreWord8; |
391 break; | 394 break; |
392 case kMachineWord16: | 395 case kRepWord16: |
393 opcode = kArmStoreWord16; | 396 opcode = kArmStoreWord16; |
394 break; | 397 break; |
395 case kMachineTagged: // Fall through. | 398 case kRepTagged: // Fall through. |
396 case kMachineWord32: | 399 case kRepWord32: |
397 opcode = kArmStoreWord32; | 400 opcode = kArmStoreWord32; |
398 break; | 401 break; |
399 default: | 402 default: |
400 UNREACHABLE(); | 403 UNREACHABLE(); |
401 return; | 404 return; |
402 } | 405 } |
403 | 406 |
404 if (g.CanBeImmediate(index, opcode)) { | 407 if (g.CanBeImmediate(index, opcode)) { |
405 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), NULL, | 408 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), NULL, |
406 g.UseRegister(base), g.UseImmediate(index), val); | 409 g.UseRegister(base), g.UseImmediate(index), val); |
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 DCHECK(cont->IsSet()); | 948 DCHECK(cont->IsSet()); |
946 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), | 949 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), |
947 g.UseDoubleRegister(m.left().node()), | 950 g.UseDoubleRegister(m.left().node()), |
948 g.UseDoubleRegister(m.right().node())); | 951 g.UseDoubleRegister(m.right().node())); |
949 } | 952 } |
950 } | 953 } |
951 | 954 |
952 } // namespace compiler | 955 } // namespace compiler |
953 } // namespace internal | 956 } // namespace internal |
954 } // namespace v8 | 957 } // namespace v8 |
OLD | NEW |