| 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/base/bits.h" | 5 #include "src/base/bits.h" |
| 6 #include "src/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" |
| 7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 return ImmediateFitsAddrMode1Instruction(value) || | 48 return ImmediateFitsAddrMode1Instruction(value) || |
| 49 ImmediateFitsAddrMode1Instruction(-value); | 49 ImmediateFitsAddrMode1Instruction(-value); |
| 50 | 50 |
| 51 case kArmTst: | 51 case kArmTst: |
| 52 case kArmTeq: | 52 case kArmTeq: |
| 53 case kArmOrr: | 53 case kArmOrr: |
| 54 case kArmEor: | 54 case kArmEor: |
| 55 case kArmRsb: | 55 case kArmRsb: |
| 56 return ImmediateFitsAddrMode1Instruction(value); | 56 return ImmediateFitsAddrMode1Instruction(value); |
| 57 | 57 |
| 58 case kArmFloat64Load: | 58 case kArmVldr64: |
| 59 case kArmFloat64Store: | 59 case kArmVstr64: |
| 60 return value >= -1020 && value <= 1020 && (value % 4) == 0; | 60 return value >= -1020 && value <= 1020 && (value % 4) == 0; |
| 61 | 61 |
| 62 case kArmLoadWord8: | 62 case kArmLdrb: |
| 63 case kArmStoreWord8: | 63 case kArmLdrsb: |
| 64 case kArmLoadWord32: | 64 case kArmStrb: |
| 65 case kArmStoreWord32: | 65 case kArmLdr: |
| 66 case kArmStr: |
| 66 case kArmStoreWriteBarrier: | 67 case kArmStoreWriteBarrier: |
| 67 return value >= -4095 && value <= 4095; | 68 return value >= -4095 && value <= 4095; |
| 68 | 69 |
| 69 case kArmLoadWord16: | 70 case kArmLdrh: |
| 70 case kArmStoreWord16: | 71 case kArmLdrsh: |
| 72 case kArmStrh: |
| 71 return value >= -255 && value <= 255; | 73 return value >= -255 && value <= 255; |
| 72 | 74 |
| 73 case kArchJmp: | 75 case kArchJmp: |
| 74 case kArchNop: | 76 case kArchNop: |
| 75 case kArchRet: | 77 case kArchRet: |
| 76 case kArchDeoptimize: | 78 case kArchDeoptimize: |
| 77 case kArchTruncateDoubleToI: | 79 case kArchTruncateDoubleToI: |
| 78 case kArmMul: | 80 case kArmMul: |
| 79 case kArmMla: | 81 case kArmMla: |
| 80 case kArmMls: | 82 case kArmMls: |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 | 282 |
| 281 static void VisitBinop(InstructionSelector* selector, Node* node, | 283 static void VisitBinop(InstructionSelector* selector, Node* node, |
| 282 InstructionCode opcode, InstructionCode reverse_opcode) { | 284 InstructionCode opcode, InstructionCode reverse_opcode) { |
| 283 FlagsContinuation cont; | 285 FlagsContinuation cont; |
| 284 VisitBinop(selector, node, opcode, reverse_opcode, &cont); | 286 VisitBinop(selector, node, opcode, reverse_opcode, &cont); |
| 285 } | 287 } |
| 286 | 288 |
| 287 | 289 |
| 288 void InstructionSelector::VisitLoad(Node* node) { | 290 void InstructionSelector::VisitLoad(Node* node) { |
| 289 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 291 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); |
| 292 MachineType typ = TypeOf(OpParameter<MachineType>(node)); |
| 290 ArmOperandGenerator g(this); | 293 ArmOperandGenerator g(this); |
| 291 Node* base = node->InputAt(0); | 294 Node* base = node->InputAt(0); |
| 292 Node* index = node->InputAt(1); | 295 Node* index = node->InputAt(1); |
| 293 | 296 |
| 294 InstructionOperand* result = rep == kRepFloat64 | 297 InstructionOperand* result = rep == kRepFloat64 |
| 295 ? g.DefineAsDoubleRegister(node) | 298 ? g.DefineAsDoubleRegister(node) |
| 296 : g.DefineAsRegister(node); | 299 : g.DefineAsRegister(node); |
| 297 | 300 |
| 298 ArchOpcode opcode; | 301 ArchOpcode opcode; |
| 299 // TODO(titzer): signed/unsigned small loads | |
| 300 switch (rep) { | 302 switch (rep) { |
| 301 case kRepFloat64: | 303 case kRepFloat64: |
| 302 opcode = kArmFloat64Load; | 304 opcode = kArmVldr64; |
| 303 break; | 305 break; |
| 304 case kRepBit: // Fall through. | 306 case kRepBit: // Fall through. |
| 305 case kRepWord8: | 307 case kRepWord8: |
| 306 opcode = kArmLoadWord8; | 308 opcode = typ == kTypeUint32 ? kArmLdrb : kArmLdrsb; |
| 307 break; | 309 break; |
| 308 case kRepWord16: | 310 case kRepWord16: |
| 309 opcode = kArmLoadWord16; | 311 opcode = typ == kTypeUint32 ? kArmLdrh : kArmLdrsh; |
| 310 break; | 312 break; |
| 311 case kRepTagged: // Fall through. | 313 case kRepTagged: // Fall through. |
| 312 case kRepWord32: | 314 case kRepWord32: |
| 313 opcode = kArmLoadWord32; | 315 opcode = kArmLdr; |
| 314 break; | 316 break; |
| 315 default: | 317 default: |
| 316 UNREACHABLE(); | 318 UNREACHABLE(); |
| 317 return; | 319 return; |
| 318 } | 320 } |
| 319 | 321 |
| 320 if (g.CanBeImmediate(index, opcode)) { | 322 if (g.CanBeImmediate(index, opcode)) { |
| 321 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), result, | 323 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), result, |
| 322 g.UseRegister(base), g.UseImmediate(index)); | 324 g.UseRegister(base), g.UseImmediate(index)); |
| 323 } else if (g.CanBeImmediate(base, opcode)) { | |
| 324 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), result, | |
| 325 g.UseRegister(index), g.UseImmediate(base)); | |
| 326 } else { | 325 } else { |
| 327 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), result, | 326 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), result, |
| 328 g.UseRegister(base), g.UseRegister(index)); | 327 g.UseRegister(base), g.UseRegister(index)); |
| 329 } | 328 } |
| 330 } | 329 } |
| 331 | 330 |
| 332 | 331 |
| 333 void InstructionSelector::VisitStore(Node* node) { | 332 void InstructionSelector::VisitStore(Node* node) { |
| 334 ArmOperandGenerator g(this); | 333 ArmOperandGenerator g(this); |
| 335 Node* base = node->InputAt(0); | 334 Node* base = node->InputAt(0); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 349 temps); | 348 temps); |
| 350 return; | 349 return; |
| 351 } | 350 } |
| 352 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind); | 351 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind); |
| 353 InstructionOperand* val = | 352 InstructionOperand* val = |
| 354 rep == kRepFloat64 ? g.UseDoubleRegister(value) : g.UseRegister(value); | 353 rep == kRepFloat64 ? g.UseDoubleRegister(value) : g.UseRegister(value); |
| 355 | 354 |
| 356 ArchOpcode opcode; | 355 ArchOpcode opcode; |
| 357 switch (rep) { | 356 switch (rep) { |
| 358 case kRepFloat64: | 357 case kRepFloat64: |
| 359 opcode = kArmFloat64Store; | 358 opcode = kArmVstr64; |
| 360 break; | 359 break; |
| 361 case kRepBit: // Fall through. | 360 case kRepBit: // Fall through. |
| 362 case kRepWord8: | 361 case kRepWord8: |
| 363 opcode = kArmStoreWord8; | 362 opcode = kArmStrb; |
| 364 break; | 363 break; |
| 365 case kRepWord16: | 364 case kRepWord16: |
| 366 opcode = kArmStoreWord16; | 365 opcode = kArmStrh; |
| 367 break; | 366 break; |
| 368 case kRepTagged: // Fall through. | 367 case kRepTagged: // Fall through. |
| 369 case kRepWord32: | 368 case kRepWord32: |
| 370 opcode = kArmStoreWord32; | 369 opcode = kArmStr; |
| 371 break; | 370 break; |
| 372 default: | 371 default: |
| 373 UNREACHABLE(); | 372 UNREACHABLE(); |
| 374 return; | 373 return; |
| 375 } | 374 } |
| 376 | 375 |
| 377 if (g.CanBeImmediate(index, opcode)) { | 376 if (g.CanBeImmediate(index, opcode)) { |
| 378 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), NULL, | 377 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), NULL, |
| 379 g.UseRegister(base), g.UseImmediate(index), val); | 378 g.UseRegister(base), g.UseImmediate(index), val); |
| 380 } else if (g.CanBeImmediate(base, opcode)) { | |
| 381 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), NULL, | |
| 382 g.UseRegister(index), g.UseImmediate(base), val); | |
| 383 } else { | 379 } else { |
| 384 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), NULL, | 380 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), NULL, |
| 385 g.UseRegister(base), g.UseRegister(index), val); | 381 g.UseRegister(base), g.UseRegister(index), val); |
| 386 } | 382 } |
| 387 } | 383 } |
| 388 | 384 |
| 389 | 385 |
| 390 static inline void EmitBic(InstructionSelector* selector, Node* node, | 386 static inline void EmitBic(InstructionSelector* selector, Node* node, |
| 391 Node* left, Node* right) { | 387 Node* left, Node* right) { |
| 392 ArmOperandGenerator g(selector); | 388 ArmOperandGenerator g(selector); |
| (...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 DCHECK(cont->IsSet()); | 955 DCHECK(cont->IsSet()); |
| 960 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), | 956 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), |
| 961 g.UseDoubleRegister(m.left().node()), | 957 g.UseDoubleRegister(m.left().node()), |
| 962 g.UseDoubleRegister(m.right().node())); | 958 g.UseDoubleRegister(m.right().node())); |
| 963 } | 959 } |
| 964 } | 960 } |
| 965 | 961 |
| 966 } // namespace compiler | 962 } // namespace compiler |
| 967 } // namespace internal | 963 } // namespace internal |
| 968 } // namespace v8 | 964 } // namespace v8 |
| OLD | NEW |