| 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 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 | 278 |
| 279 | 279 |
| 280 static void VisitBinop(InstructionSelector* selector, Node* node, | 280 static void VisitBinop(InstructionSelector* selector, Node* node, |
| 281 InstructionCode opcode, InstructionCode reverse_opcode) { | 281 InstructionCode opcode, InstructionCode reverse_opcode) { |
| 282 FlagsContinuation cont; | 282 FlagsContinuation cont; |
| 283 VisitBinop(selector, node, opcode, reverse_opcode, &cont); | 283 VisitBinop(selector, node, opcode, reverse_opcode, &cont); |
| 284 } | 284 } |
| 285 | 285 |
| 286 | 286 |
| 287 void InstructionSelector::VisitLoad(Node* node) { | 287 void InstructionSelector::VisitLoad(Node* node) { |
| 288 MachineType rep = OpParameter<MachineType>(node); | 288 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); |
| 289 ArmOperandGenerator g(this); | 289 ArmOperandGenerator g(this); |
| 290 Node* base = node->InputAt(0); | 290 Node* base = node->InputAt(0); |
| 291 Node* index = node->InputAt(1); | 291 Node* index = node->InputAt(1); |
| 292 | 292 |
| 293 InstructionOperand* result = rep == kMachineFloat64 | 293 InstructionOperand* result = rep == kRepFloat64 |
| 294 ? g.DefineAsDoubleRegister(node) | 294 ? g.DefineAsDoubleRegister(node) |
| 295 : g.DefineAsRegister(node); | 295 : g.DefineAsRegister(node); |
| 296 | 296 |
| 297 ArchOpcode opcode; | 297 ArchOpcode opcode; |
| 298 // TODO(titzer): signed/unsigned small loads |
| 298 switch (rep) { | 299 switch (rep) { |
| 299 case kMachineFloat64: | 300 case kRepFloat64: |
| 300 opcode = kArmFloat64Load; | 301 opcode = kArmFloat64Load; |
| 301 break; | 302 break; |
| 302 case kMachineWord8: | 303 case kRepBit: // Fall through. |
| 304 case kRepWord8: |
| 303 opcode = kArmLoadWord8; | 305 opcode = kArmLoadWord8; |
| 304 break; | 306 break; |
| 305 case kMachineWord16: | 307 case kRepWord16: |
| 306 opcode = kArmLoadWord16; | 308 opcode = kArmLoadWord16; |
| 307 break; | 309 break; |
| 308 case kMachineTagged: // Fall through. | 310 case kRepTagged: // Fall through. |
| 309 case kMachineWord32: | 311 case kRepWord32: |
| 310 opcode = kArmLoadWord32; | 312 opcode = kArmLoadWord32; |
| 311 break; | 313 break; |
| 312 default: | 314 default: |
| 313 UNREACHABLE(); | 315 UNREACHABLE(); |
| 314 return; | 316 return; |
| 315 } | 317 } |
| 316 | 318 |
| 317 if (g.CanBeImmediate(index, opcode)) { | 319 if (g.CanBeImmediate(index, opcode)) { |
| 318 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), result, | 320 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), result, |
| 319 g.UseRegister(base), g.UseImmediate(index)); | 321 g.UseRegister(base), g.UseImmediate(index)); |
| 320 } else if (g.CanBeImmediate(base, opcode)) { | 322 } else if (g.CanBeImmediate(base, opcode)) { |
| 321 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), result, | 323 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), result, |
| 322 g.UseRegister(index), g.UseImmediate(base)); | 324 g.UseRegister(index), g.UseImmediate(base)); |
| 323 } else { | 325 } else { |
| 324 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), result, | 326 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), result, |
| 325 g.UseRegister(base), g.UseRegister(index)); | 327 g.UseRegister(base), g.UseRegister(index)); |
| 326 } | 328 } |
| 327 } | 329 } |
| 328 | 330 |
| 329 | 331 |
| 330 void InstructionSelector::VisitStore(Node* node) { | 332 void InstructionSelector::VisitStore(Node* node) { |
| 331 ArmOperandGenerator g(this); | 333 ArmOperandGenerator g(this); |
| 332 Node* base = node->InputAt(0); | 334 Node* base = node->InputAt(0); |
| 333 Node* index = node->InputAt(1); | 335 Node* index = node->InputAt(1); |
| 334 Node* value = node->InputAt(2); | 336 Node* value = node->InputAt(2); |
| 335 | 337 |
| 336 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 338 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
| 337 MachineType rep = store_rep.rep; | 339 MachineType rep = RepresentationOf(store_rep.machine_type); |
| 338 if (store_rep.write_barrier_kind == kFullWriteBarrier) { | 340 if (store_rep.write_barrier_kind == kFullWriteBarrier) { |
| 339 DCHECK(rep == kMachineTagged); | 341 DCHECK(rep == kRepTagged); |
| 340 // TODO(dcarney): refactor RecordWrite function to take temp registers | 342 // TODO(dcarney): refactor RecordWrite function to take temp registers |
| 341 // and pass them here instead of using fixed regs | 343 // and pass them here instead of using fixed regs |
| 342 // TODO(dcarney): handle immediate indices. | 344 // TODO(dcarney): handle immediate indices. |
| 343 InstructionOperand* temps[] = {g.TempRegister(r5), g.TempRegister(r6)}; | 345 InstructionOperand* temps[] = {g.TempRegister(r5), g.TempRegister(r6)}; |
| 344 Emit(kArmStoreWriteBarrier, NULL, g.UseFixed(base, r4), | 346 Emit(kArmStoreWriteBarrier, NULL, g.UseFixed(base, r4), |
| 345 g.UseFixed(index, r5), g.UseFixed(value, r6), ARRAY_SIZE(temps), | 347 g.UseFixed(index, r5), g.UseFixed(value, r6), ARRAY_SIZE(temps), |
| 346 temps); | 348 temps); |
| 347 return; | 349 return; |
| 348 } | 350 } |
| 349 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind); | 351 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind); |
| 350 InstructionOperand* val = rep == kMachineFloat64 ? g.UseDoubleRegister(value) | 352 InstructionOperand* val = |
| 351 : g.UseRegister(value); | 353 rep == kRepFloat64 ? g.UseDoubleRegister(value) : g.UseRegister(value); |
| 352 | 354 |
| 353 ArchOpcode opcode; | 355 ArchOpcode opcode; |
| 354 switch (rep) { | 356 switch (rep) { |
| 355 case kMachineFloat64: | 357 case kRepFloat64: |
| 356 opcode = kArmFloat64Store; | 358 opcode = kArmFloat64Store; |
| 357 break; | 359 break; |
| 358 case kMachineWord8: | 360 case kRepBit: // Fall through. |
| 361 case kRepWord8: |
| 359 opcode = kArmStoreWord8; | 362 opcode = kArmStoreWord8; |
| 360 break; | 363 break; |
| 361 case kMachineWord16: | 364 case kRepWord16: |
| 362 opcode = kArmStoreWord16; | 365 opcode = kArmStoreWord16; |
| 363 break; | 366 break; |
| 364 case kMachineTagged: // Fall through. | 367 case kRepTagged: // Fall through. |
| 365 case kMachineWord32: | 368 case kRepWord32: |
| 366 opcode = kArmStoreWord32; | 369 opcode = kArmStoreWord32; |
| 367 break; | 370 break; |
| 368 default: | 371 default: |
| 369 UNREACHABLE(); | 372 UNREACHABLE(); |
| 370 return; | 373 return; |
| 371 } | 374 } |
| 372 | 375 |
| 373 if (g.CanBeImmediate(index, opcode)) { | 376 if (g.CanBeImmediate(index, opcode)) { |
| 374 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), NULL, | 377 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), NULL, |
| 375 g.UseRegister(base), g.UseImmediate(index), val); | 378 g.UseRegister(base), g.UseImmediate(index), val); |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 DCHECK(cont->IsSet()); | 914 DCHECK(cont->IsSet()); |
| 912 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), | 915 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), |
| 913 g.UseDoubleRegister(m.left().node()), | 916 g.UseDoubleRegister(m.left().node()), |
| 914 g.UseDoubleRegister(m.right().node())); | 917 g.UseDoubleRegister(m.right().node())); |
| 915 } | 918 } |
| 916 } | 919 } |
| 917 | 920 |
| 918 } // namespace compiler | 921 } // namespace compiler |
| 919 } // namespace internal | 922 } // namespace internal |
| 920 } // namespace v8 | 923 } // namespace v8 |
| OLD | NEW |