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 |