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/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/base/bits.h" | 6 #include "src/base/bits.h" |
7 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 | 10 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 | 125 |
126 | 126 |
127 static void VisitBinop(InstructionSelector* selector, Node* node, | 127 static void VisitBinop(InstructionSelector* selector, Node* node, |
128 InstructionCode opcode) { | 128 InstructionCode opcode) { |
129 FlagsContinuation cont; | 129 FlagsContinuation cont; |
130 VisitBinop(selector, node, opcode, &cont); | 130 VisitBinop(selector, node, opcode, &cont); |
131 } | 131 } |
132 | 132 |
133 | 133 |
134 void InstructionSelector::VisitLoad(Node* node) { | 134 void InstructionSelector::VisitLoad(Node* node) { |
135 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 135 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
136 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | |
137 Mips64OperandGenerator g(this); | 136 Mips64OperandGenerator g(this); |
138 Node* base = node->InputAt(0); | 137 Node* base = node->InputAt(0); |
139 Node* index = node->InputAt(1); | 138 Node* index = node->InputAt(1); |
140 | 139 |
141 ArchOpcode opcode; | 140 ArchOpcode opcode; |
142 switch (rep) { | 141 switch (load_rep.representation()) { |
143 case kRepFloat32: | 142 case MachineRepresentation::kFloat32: |
144 opcode = kMips64Lwc1; | 143 opcode = kMips64Lwc1; |
145 break; | 144 break; |
146 case kRepFloat64: | 145 case MachineRepresentation::kFloat64: |
147 opcode = kMips64Ldc1; | 146 opcode = kMips64Ldc1; |
148 break; | 147 break; |
149 case kRepBit: // Fall through. | 148 case MachineRepresentation::kBit: // Fall through. |
150 case kRepWord8: | 149 case MachineRepresentation::kWord8: |
151 opcode = typ == kTypeUint32 ? kMips64Lbu : kMips64Lb; | 150 opcode = load_rep.IsUnsigned() ? kMips64Lbu : kMips64Lb; |
152 break; | 151 break; |
153 case kRepWord16: | 152 case MachineRepresentation::kWord16: |
154 opcode = typ == kTypeUint32 ? kMips64Lhu : kMips64Lh; | 153 opcode = load_rep.IsUnsigned() ? kMips64Lhu : kMips64Lh; |
155 break; | 154 break; |
156 case kRepWord32: | 155 case MachineRepresentation::kWord32: |
157 opcode = kMips64Lw; | 156 opcode = kMips64Lw; |
158 break; | 157 break; |
159 case kRepTagged: // Fall through. | 158 case MachineRepresentation::kTagged: // Fall through. |
160 case kRepWord64: | 159 case MachineRepresentation::kWord64: |
161 opcode = kMips64Ld; | 160 opcode = kMips64Ld; |
162 break; | 161 break; |
163 default: | 162 default: |
164 UNREACHABLE(); | 163 UNREACHABLE(); |
165 return; | 164 return; |
166 } | 165 } |
167 | 166 |
168 if (g.CanBeImmediate(index, opcode)) { | 167 if (g.CanBeImmediate(index, opcode)) { |
169 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 168 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
170 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); | 169 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); |
171 } else { | 170 } else { |
172 InstructionOperand addr_reg = g.TempRegister(); | 171 InstructionOperand addr_reg = g.TempRegister(); |
173 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, | 172 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, |
174 g.UseRegister(index), g.UseRegister(base)); | 173 g.UseRegister(index), g.UseRegister(base)); |
175 // Emit desired load opcode, using temp addr_reg. | 174 // Emit desired load opcode, using temp addr_reg. |
176 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 175 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
177 g.DefineAsRegister(node), addr_reg, g.TempImmediate(0)); | 176 g.DefineAsRegister(node), addr_reg, g.TempImmediate(0)); |
178 } | 177 } |
179 } | 178 } |
180 | 179 |
181 | 180 |
182 void InstructionSelector::VisitStore(Node* node) { | 181 void InstructionSelector::VisitStore(Node* node) { |
183 Mips64OperandGenerator g(this); | 182 Mips64OperandGenerator g(this); |
184 Node* base = node->InputAt(0); | 183 Node* base = node->InputAt(0); |
185 Node* index = node->InputAt(1); | 184 Node* index = node->InputAt(1); |
186 Node* value = node->InputAt(2); | 185 Node* value = node->InputAt(2); |
187 | 186 |
188 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 187 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
189 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 188 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
190 MachineType rep = RepresentationOf(store_rep.machine_type()); | 189 MachineRepresentation rep = store_rep.machine_type().representation(); |
191 | 190 |
192 // TODO(mips): I guess this could be done in a better way. | 191 // TODO(mips): I guess this could be done in a better way. |
193 if (write_barrier_kind != kNoWriteBarrier) { | 192 if (write_barrier_kind != kNoWriteBarrier) { |
194 DCHECK_EQ(kRepTagged, rep); | 193 DCHECK_EQ(MachineRepresentation::kTagged, rep); |
195 InstructionOperand inputs[3]; | 194 InstructionOperand inputs[3]; |
196 size_t input_count = 0; | 195 size_t input_count = 0; |
197 inputs[input_count++] = g.UseUniqueRegister(base); | 196 inputs[input_count++] = g.UseUniqueRegister(base); |
198 inputs[input_count++] = g.UseUniqueRegister(index); | 197 inputs[input_count++] = g.UseUniqueRegister(index); |
199 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) | 198 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) |
200 ? g.UseRegister(value) | 199 ? g.UseRegister(value) |
201 : g.UseUniqueRegister(value); | 200 : g.UseUniqueRegister(value); |
202 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; | 201 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; |
203 switch (write_barrier_kind) { | 202 switch (write_barrier_kind) { |
204 case kNoWriteBarrier: | 203 case kNoWriteBarrier: |
(...skipping 10 matching lines...) Expand all Loading... |
215 break; | 214 break; |
216 } | 215 } |
217 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 216 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
218 size_t const temp_count = arraysize(temps); | 217 size_t const temp_count = arraysize(temps); |
219 InstructionCode code = kArchStoreWithWriteBarrier; | 218 InstructionCode code = kArchStoreWithWriteBarrier; |
220 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 219 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
221 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 220 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
222 } else { | 221 } else { |
223 ArchOpcode opcode; | 222 ArchOpcode opcode; |
224 switch (rep) { | 223 switch (rep) { |
225 case kRepFloat32: | 224 case MachineRepresentation::kFloat32: |
226 opcode = kMips64Swc1; | 225 opcode = kMips64Swc1; |
227 break; | 226 break; |
228 case kRepFloat64: | 227 case MachineRepresentation::kFloat64: |
229 opcode = kMips64Sdc1; | 228 opcode = kMips64Sdc1; |
230 break; | 229 break; |
231 case kRepBit: // Fall through. | 230 case MachineRepresentation::kBit: // Fall through. |
232 case kRepWord8: | 231 case MachineRepresentation::kWord8: |
233 opcode = kMips64Sb; | 232 opcode = kMips64Sb; |
234 break; | 233 break; |
235 case kRepWord16: | 234 case MachineRepresentation::kWord16: |
236 opcode = kMips64Sh; | 235 opcode = kMips64Sh; |
237 break; | 236 break; |
238 case kRepWord32: | 237 case MachineRepresentation::kWord32: |
239 opcode = kMips64Sw; | 238 opcode = kMips64Sw; |
240 break; | 239 break; |
241 case kRepTagged: // Fall through. | 240 case MachineRepresentation::kTagged: // Fall through. |
242 case kRepWord64: | 241 case MachineRepresentation::kWord64: |
243 opcode = kMips64Sd; | 242 opcode = kMips64Sd; |
244 break; | 243 break; |
245 default: | 244 default: |
246 UNREACHABLE(); | 245 UNREACHABLE(); |
247 return; | 246 return; |
248 } | 247 } |
249 | 248 |
250 if (g.CanBeImmediate(index, opcode)) { | 249 if (g.CanBeImmediate(index, opcode)) { |
251 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 250 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
252 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); | 251 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); |
(...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1220 } | 1219 } |
1221 } | 1220 } |
1222 } | 1221 } |
1223 } | 1222 } |
1224 | 1223 |
1225 | 1224 |
1226 bool InstructionSelector::IsTailCallAddressImmediate() { return false; } | 1225 bool InstructionSelector::IsTailCallAddressImmediate() { return false; } |
1227 | 1226 |
1228 | 1227 |
1229 void InstructionSelector::VisitCheckedLoad(Node* node) { | 1228 void InstructionSelector::VisitCheckedLoad(Node* node) { |
1230 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 1229 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
1231 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | |
1232 Mips64OperandGenerator g(this); | 1230 Mips64OperandGenerator g(this); |
1233 Node* const buffer = node->InputAt(0); | 1231 Node* const buffer = node->InputAt(0); |
1234 Node* const offset = node->InputAt(1); | 1232 Node* const offset = node->InputAt(1); |
1235 Node* const length = node->InputAt(2); | 1233 Node* const length = node->InputAt(2); |
1236 ArchOpcode opcode; | 1234 ArchOpcode opcode; |
1237 switch (rep) { | 1235 switch (load_rep.representation()) { |
1238 case kRepWord8: | 1236 case MachineRepresentation::kWord8: |
1239 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; | 1237 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
1240 break; | 1238 break; |
1241 case kRepWord16: | 1239 case MachineRepresentation::kWord16: |
1242 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; | 1240 opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; |
1243 break; | 1241 break; |
1244 case kRepWord32: | 1242 case MachineRepresentation::kWord32: |
1245 opcode = kCheckedLoadWord32; | 1243 opcode = kCheckedLoadWord32; |
1246 break; | 1244 break; |
1247 case kRepWord64: | 1245 case MachineRepresentation::kWord64: |
1248 opcode = kCheckedLoadWord64; | 1246 opcode = kCheckedLoadWord64; |
1249 break; | 1247 break; |
1250 case kRepFloat32: | 1248 case MachineRepresentation::kFloat32: |
1251 opcode = kCheckedLoadFloat32; | 1249 opcode = kCheckedLoadFloat32; |
1252 break; | 1250 break; |
1253 case kRepFloat64: | 1251 case MachineRepresentation::kFloat64: |
1254 opcode = kCheckedLoadFloat64; | 1252 opcode = kCheckedLoadFloat64; |
1255 break; | 1253 break; |
1256 default: | 1254 default: |
1257 UNREACHABLE(); | 1255 UNREACHABLE(); |
1258 return; | 1256 return; |
1259 } | 1257 } |
1260 InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) | 1258 InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) |
1261 ? g.UseImmediate(offset) | 1259 ? g.UseImmediate(offset) |
1262 : g.UseRegister(offset); | 1260 : g.UseRegister(offset); |
1263 | 1261 |
1264 InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode)) | 1262 InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode)) |
1265 ? g.CanBeImmediate(length, opcode) | 1263 ? g.CanBeImmediate(length, opcode) |
1266 ? g.UseImmediate(length) | 1264 ? g.UseImmediate(length) |
1267 : g.UseRegister(length) | 1265 : g.UseRegister(length) |
1268 : g.UseRegister(length); | 1266 : g.UseRegister(length); |
1269 | 1267 |
1270 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 1268 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
1271 g.DefineAsRegister(node), offset_operand, length_operand, | 1269 g.DefineAsRegister(node), offset_operand, length_operand, |
1272 g.UseRegister(buffer)); | 1270 g.UseRegister(buffer)); |
1273 } | 1271 } |
1274 | 1272 |
1275 | 1273 |
1276 void InstructionSelector::VisitCheckedStore(Node* node) { | 1274 void InstructionSelector::VisitCheckedStore(Node* node) { |
1277 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 1275 MachineRepresentation rep = |
| 1276 CheckedStoreRepresentationOf(node->op()).representation(); |
1278 Mips64OperandGenerator g(this); | 1277 Mips64OperandGenerator g(this); |
1279 Node* const buffer = node->InputAt(0); | 1278 Node* const buffer = node->InputAt(0); |
1280 Node* const offset = node->InputAt(1); | 1279 Node* const offset = node->InputAt(1); |
1281 Node* const length = node->InputAt(2); | 1280 Node* const length = node->InputAt(2); |
1282 Node* const value = node->InputAt(3); | 1281 Node* const value = node->InputAt(3); |
1283 ArchOpcode opcode; | 1282 ArchOpcode opcode; |
1284 switch (rep) { | 1283 switch (rep) { |
1285 case kRepWord8: | 1284 case MachineRepresentation::kWord8: |
1286 opcode = kCheckedStoreWord8; | 1285 opcode = kCheckedStoreWord8; |
1287 break; | 1286 break; |
1288 case kRepWord16: | 1287 case MachineRepresentation::kWord16: |
1289 opcode = kCheckedStoreWord16; | 1288 opcode = kCheckedStoreWord16; |
1290 break; | 1289 break; |
1291 case kRepWord32: | 1290 case MachineRepresentation::kWord32: |
1292 opcode = kCheckedStoreWord32; | 1291 opcode = kCheckedStoreWord32; |
1293 break; | 1292 break; |
1294 case kRepWord64: | 1293 case MachineRepresentation::kWord64: |
1295 opcode = kCheckedStoreWord64; | 1294 opcode = kCheckedStoreWord64; |
1296 break; | 1295 break; |
1297 case kRepFloat32: | 1296 case MachineRepresentation::kFloat32: |
1298 opcode = kCheckedStoreFloat32; | 1297 opcode = kCheckedStoreFloat32; |
1299 break; | 1298 break; |
1300 case kRepFloat64: | 1299 case MachineRepresentation::kFloat64: |
1301 opcode = kCheckedStoreFloat64; | 1300 opcode = kCheckedStoreFloat64; |
1302 break; | 1301 break; |
1303 default: | 1302 default: |
1304 UNREACHABLE(); | 1303 UNREACHABLE(); |
1305 return; | 1304 return; |
1306 } | 1305 } |
1307 InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) | 1306 InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) |
1308 ? g.UseImmediate(offset) | 1307 ? g.UseImmediate(offset) |
1309 : g.UseRegister(offset); | 1308 : g.UseRegister(offset); |
1310 | 1309 |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1777 MachineOperatorBuilder::kFloat32RoundUp | | 1776 MachineOperatorBuilder::kFloat32RoundUp | |
1778 MachineOperatorBuilder::kFloat64RoundTruncate | | 1777 MachineOperatorBuilder::kFloat64RoundTruncate | |
1779 MachineOperatorBuilder::kFloat32RoundTruncate | | 1778 MachineOperatorBuilder::kFloat32RoundTruncate | |
1780 MachineOperatorBuilder::kFloat64RoundTiesEven | | 1779 MachineOperatorBuilder::kFloat64RoundTiesEven | |
1781 MachineOperatorBuilder::kFloat32RoundTiesEven; | 1780 MachineOperatorBuilder::kFloat32RoundTiesEven; |
1782 } | 1781 } |
1783 | 1782 |
1784 } // namespace compiler | 1783 } // namespace compiler |
1785 } // namespace internal | 1784 } // namespace internal |
1786 } // namespace v8 | 1785 } // namespace v8 |
OLD | NEW |