| 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 | 7 |
| 8 namespace v8 { | 8 namespace v8 { |
| 9 namespace internal { | 9 namespace internal { |
| 10 namespace compiler { | 10 namespace compiler { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 } | 50 } |
| 51 default: | 51 default: |
| 52 return false; | 52 return false; |
| 53 } | 53 } |
| 54 } | 54 } |
| 55 }; | 55 }; |
| 56 | 56 |
| 57 | 57 |
| 58 void InstructionSelector::VisitLoad(Node* node) { | 58 void InstructionSelector::VisitLoad(Node* node) { |
| 59 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 59 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); |
| 60 MachineType typ = TypeOf(OpParameter<MachineType>(node)); |
| 60 X64OperandGenerator g(this); | 61 X64OperandGenerator g(this); |
| 61 Node* base = node->InputAt(0); | 62 Node* base = node->InputAt(0); |
| 62 Node* index = node->InputAt(1); | 63 Node* index = node->InputAt(1); |
| 63 | 64 |
| 64 InstructionOperand* output = rep == kRepFloat64 | 65 InstructionOperand* output = rep == kRepFloat64 |
| 65 ? g.DefineAsDoubleRegister(node) | 66 ? g.DefineAsDoubleRegister(node) |
| 66 : g.DefineAsRegister(node); | 67 : g.DefineAsRegister(node); |
| 67 ArchOpcode opcode; | 68 ArchOpcode opcode; |
| 68 // TODO(titzer): signed/unsigned small loads | 69 // TODO(titzer): signed/unsigned small loads |
| 69 switch (rep) { | 70 switch (rep) { |
| 70 case kRepFloat64: | 71 case kRepFloat64: |
| 71 opcode = kSSELoad; | 72 opcode = kX64Movsd; |
| 72 break; | 73 break; |
| 73 case kRepBit: // Fall through. | 74 case kRepBit: // Fall through. |
| 74 case kRepWord8: | 75 case kRepWord8: |
| 75 opcode = kX64LoadWord8; | 76 opcode = typ == kTypeInt32 ? kX64Movsxbl : kX64Movzxbl; |
| 76 break; | 77 break; |
| 77 case kRepWord16: | 78 case kRepWord16: |
| 78 opcode = kX64LoadWord16; | 79 opcode = typ == kTypeInt32 ? kX64Movsxwl : kX64Movzxwl; |
| 79 break; | 80 break; |
| 80 case kRepWord32: | 81 case kRepWord32: |
| 81 opcode = kX64LoadWord32; | 82 opcode = kX64Movl; |
| 82 break; | 83 break; |
| 83 case kRepTagged: // Fall through. | 84 case kRepTagged: // Fall through. |
| 84 case kRepWord64: | 85 case kRepWord64: |
| 85 opcode = kX64LoadWord64; | 86 opcode = kX64Movq; |
| 86 break; | 87 break; |
| 87 default: | 88 default: |
| 88 UNREACHABLE(); | 89 UNREACHABLE(); |
| 89 return; | 90 return; |
| 90 } | 91 } |
| 91 if (g.CanBeImmediate(base)) { | 92 if (g.CanBeImmediate(base)) { |
| 92 // load [#base + %index] | 93 // load [#base + %index] |
| 93 Emit(opcode | AddressingModeField::encode(kMode_MRI), output, | 94 Emit(opcode | AddressingModeField::encode(kMode_MRI), output, |
| 94 g.UseRegister(index), g.UseImmediate(base)); | 95 g.UseRegister(index), g.UseImmediate(base)); |
| 95 } else if (g.CanBeImmediate(index)) { // load [%base + #index] | 96 } else if (g.CanBeImmediate(index)) { // load [%base + #index] |
| (...skipping 20 matching lines...) Expand all Loading... |
| 116 // TODO(dcarney): refactor RecordWrite function to take temp registers | 117 // TODO(dcarney): refactor RecordWrite function to take temp registers |
| 117 // and pass them here instead of using fixed regs | 118 // and pass them here instead of using fixed regs |
| 118 // TODO(dcarney): handle immediate indices. | 119 // TODO(dcarney): handle immediate indices. |
| 119 InstructionOperand* temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)}; | 120 InstructionOperand* temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)}; |
| 120 Emit(kX64StoreWriteBarrier, NULL, g.UseFixed(base, rbx), | 121 Emit(kX64StoreWriteBarrier, NULL, g.UseFixed(base, rbx), |
| 121 g.UseFixed(index, rcx), g.UseFixed(value, rdx), ARRAY_SIZE(temps), | 122 g.UseFixed(index, rcx), g.UseFixed(value, rdx), ARRAY_SIZE(temps), |
| 122 temps); | 123 temps); |
| 123 return; | 124 return; |
| 124 } | 125 } |
| 125 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind); | 126 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind); |
| 126 bool is_immediate = false; | |
| 127 InstructionOperand* val; | 127 InstructionOperand* val; |
| 128 if (rep == kRepFloat64) { | 128 if (rep == kRepFloat64) { |
| 129 val = g.UseDoubleRegister(value); | 129 val = g.UseDoubleRegister(value); |
| 130 } else { | 130 } else { |
| 131 is_immediate = g.CanBeImmediate(value); | 131 if (g.CanBeImmediate(value)) { |
| 132 if (is_immediate) { | |
| 133 val = g.UseImmediate(value); | 132 val = g.UseImmediate(value); |
| 134 } else if (rep == kRepWord8 || rep == kRepBit) { | 133 } else if (rep == kRepWord8 || rep == kRepBit) { |
| 135 val = g.UseByteRegister(value); | 134 val = g.UseByteRegister(value); |
| 136 } else { | 135 } else { |
| 137 val = g.UseRegister(value); | 136 val = g.UseRegister(value); |
| 138 } | 137 } |
| 139 } | 138 } |
| 140 ArchOpcode opcode; | 139 ArchOpcode opcode; |
| 141 switch (rep) { | 140 switch (rep) { |
| 142 case kRepFloat64: | 141 case kRepFloat64: |
| 143 opcode = kSSEStore; | 142 opcode = kX64Movsd; |
| 144 break; | 143 break; |
| 145 case kRepBit: // Fall through. | 144 case kRepBit: // Fall through. |
| 146 case kRepWord8: | 145 case kRepWord8: |
| 147 opcode = is_immediate ? kX64StoreWord8I : kX64StoreWord8; | 146 opcode = kX64Movb; |
| 148 break; | 147 break; |
| 149 case kRepWord16: | 148 case kRepWord16: |
| 150 opcode = is_immediate ? kX64StoreWord16I : kX64StoreWord16; | 149 opcode = kX64Movw; |
| 151 break; | 150 break; |
| 152 case kRepWord32: | 151 case kRepWord32: |
| 153 opcode = is_immediate ? kX64StoreWord32I : kX64StoreWord32; | 152 opcode = kX64Movl; |
| 154 break; | 153 break; |
| 155 case kRepTagged: // Fall through. | 154 case kRepTagged: // Fall through. |
| 156 case kRepWord64: | 155 case kRepWord64: |
| 157 opcode = is_immediate ? kX64StoreWord64I : kX64StoreWord64; | 156 opcode = kX64Movq; |
| 158 break; | 157 break; |
| 159 default: | 158 default: |
| 160 UNREACHABLE(); | 159 UNREACHABLE(); |
| 161 return; | 160 return; |
| 162 } | 161 } |
| 163 if (g.CanBeImmediate(base)) { | 162 if (g.CanBeImmediate(base)) { |
| 164 // store [#base + %index], %|#value | 163 // store [#base + %index], %|#value |
| 165 Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, | 164 Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, |
| 166 g.UseRegister(index), g.UseImmediate(base), val); | 165 g.UseRegister(index), g.UseImmediate(base), val); |
| 167 } else if (g.CanBeImmediate(index)) { // store [%base + #index], %|#value | 166 } else if (g.CanBeImmediate(index)) { // store [%base + #index], %|#value |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 DCHECK(deoptimization == NULL && continuation == NULL); | 736 DCHECK(deoptimization == NULL && continuation == NULL); |
| 738 Emit(kPopStack | | 737 Emit(kPopStack | |
| 739 MiscField::encode(static_cast<int>(buffer.pushed_nodes.size())), | 738 MiscField::encode(static_cast<int>(buffer.pushed_nodes.size())), |
| 740 NULL); | 739 NULL); |
| 741 } | 740 } |
| 742 } | 741 } |
| 743 | 742 |
| 744 } // namespace compiler | 743 } // namespace compiler |
| 745 } // namespace internal | 744 } // namespace internal |
| 746 } // namespace v8 | 745 } // namespace v8 |
| OLD | NEW |