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 |