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/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 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
9 #include "src/ppc/frames-ppc.h" | 9 #include "src/ppc/frames-ppc.h" |
10 | 10 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode, | 135 void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode, |
136 ImmediateMode operand_mode) { | 136 ImmediateMode operand_mode) { |
137 FlagsContinuation cont; | 137 FlagsContinuation cont; |
138 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); | 138 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); |
139 } | 139 } |
140 | 140 |
141 } // namespace | 141 } // namespace |
142 | 142 |
143 | 143 |
144 void InstructionSelector::VisitLoad(Node* node) { | 144 void InstructionSelector::VisitLoad(Node* node) { |
145 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 145 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
146 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | |
147 PPCOperandGenerator g(this); | 146 PPCOperandGenerator g(this); |
148 Node* base = node->InputAt(0); | 147 Node* base = node->InputAt(0); |
149 Node* offset = node->InputAt(1); | 148 Node* offset = node->InputAt(1); |
150 | |
151 ArchOpcode opcode; | 149 ArchOpcode opcode; |
152 ImmediateMode mode = kInt16Imm; | 150 ImmediateMode mode = kInt16Imm; |
153 switch (rep) { | 151 switch (load_rep.representation()) { |
154 case kRepFloat32: | 152 case MachineRepresentation::kFloat32: |
155 opcode = kPPC_LoadFloat32; | 153 opcode = kPPC_LoadFloat32; |
156 break; | 154 break; |
157 case kRepFloat64: | 155 case MachineRepresentation::kFloat64: |
158 opcode = kPPC_LoadDouble; | 156 opcode = kPPC_LoadDouble; |
159 break; | 157 break; |
160 case kRepBit: // Fall through. | 158 case MachineRepresentation::kBit: // Fall through. |
161 case kRepWord8: | 159 case MachineRepresentation::kWord8: |
162 opcode = (typ == kTypeInt32) ? kPPC_LoadWordS8 : kPPC_LoadWordU8; | 160 opcode = load_rep.IsSigned() ? kPPC_LoadWordS8 : kPPC_LoadWordU8; |
163 break; | 161 break; |
164 case kRepWord16: | 162 case MachineRepresentation::kWord16: |
165 opcode = (typ == kTypeInt32) ? kPPC_LoadWordS16 : kPPC_LoadWordU16; | 163 opcode = load_rep.IsSigned() ? kPPC_LoadWordS16 : kPPC_LoadWordU16; |
166 break; | 164 break; |
167 #if !V8_TARGET_ARCH_PPC64 | 165 #if !V8_TARGET_ARCH_PPC64 |
168 case kRepTagged: // Fall through. | 166 case MachineRepresentation::kTagged: // Fall through. |
169 #endif | 167 #endif |
170 case kRepWord32: | 168 case MachineRepresentation::kWord32: |
171 opcode = kPPC_LoadWordS32; | 169 opcode = kPPC_LoadWordS32; |
172 #if V8_TARGET_ARCH_PPC64 | 170 #if V8_TARGET_ARCH_PPC64 |
173 // TODO(mbrandy): this applies to signed loads only (lwa) | 171 // TODO(mbrandy): this applies to signed loads only (lwa) |
174 mode = kInt16Imm_4ByteAligned; | 172 mode = kInt16Imm_4ByteAligned; |
175 #endif | 173 #endif |
176 break; | 174 break; |
177 #if V8_TARGET_ARCH_PPC64 | 175 #if V8_TARGET_ARCH_PPC64 |
178 case kRepTagged: // Fall through. | 176 case MachineRepresentation::kTagged: // Fall through. |
179 case kRepWord64: | 177 case MachineRepresentation::kWord64: |
180 opcode = kPPC_LoadWord64; | 178 opcode = kPPC_LoadWord64; |
181 mode = kInt16Imm_4ByteAligned; | 179 mode = kInt16Imm_4ByteAligned; |
182 break; | 180 break; |
183 #endif | 181 #endif |
184 default: | 182 default: |
185 UNREACHABLE(); | 183 UNREACHABLE(); |
186 return; | 184 return; |
187 } | 185 } |
188 if (g.CanBeImmediate(offset, mode)) { | 186 if (g.CanBeImmediate(offset, mode)) { |
189 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 187 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
190 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(offset)); | 188 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(offset)); |
191 } else if (g.CanBeImmediate(base, mode)) { | 189 } else if (g.CanBeImmediate(base, mode)) { |
192 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 190 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
193 g.DefineAsRegister(node), g.UseRegister(offset), g.UseImmediate(base)); | 191 g.DefineAsRegister(node), g.UseRegister(offset), g.UseImmediate(base)); |
194 } else { | 192 } else { |
195 Emit(opcode | AddressingModeField::encode(kMode_MRR), | 193 Emit(opcode | AddressingModeField::encode(kMode_MRR), |
196 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(offset)); | 194 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(offset)); |
197 } | 195 } |
198 } | 196 } |
199 | 197 |
200 | 198 |
201 void InstructionSelector::VisitStore(Node* node) { | 199 void InstructionSelector::VisitStore(Node* node) { |
202 PPCOperandGenerator g(this); | 200 PPCOperandGenerator g(this); |
203 Node* base = node->InputAt(0); | 201 Node* base = node->InputAt(0); |
204 Node* offset = node->InputAt(1); | 202 Node* offset = node->InputAt(1); |
205 Node* value = node->InputAt(2); | 203 Node* value = node->InputAt(2); |
206 | 204 |
207 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 205 StoreRepresentation store_rep = StoreRepresentationOf(node->op()); |
208 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 206 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
209 MachineType rep = RepresentationOf(store_rep.machine_type()); | 207 MachineRepresentation rep = store_rep.representation(); |
210 | 208 |
211 // TODO(ppc): I guess this could be done in a better way. | 209 // TODO(ppc): I guess this could be done in a better way. |
212 if (write_barrier_kind != kNoWriteBarrier) { | 210 if (write_barrier_kind != kNoWriteBarrier) { |
213 DCHECK_EQ(kRepTagged, rep); | 211 DCHECK_EQ(MachineRepresentation::kTagged, rep); |
214 InstructionOperand inputs[3]; | 212 InstructionOperand inputs[3]; |
215 size_t input_count = 0; | 213 size_t input_count = 0; |
216 inputs[input_count++] = g.UseUniqueRegister(base); | 214 inputs[input_count++] = g.UseUniqueRegister(base); |
217 inputs[input_count++] = g.UseUniqueRegister(offset); | 215 inputs[input_count++] = g.UseUniqueRegister(offset); |
218 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) | 216 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) |
219 ? g.UseRegister(value) | 217 ? g.UseRegister(value) |
220 : g.UseUniqueRegister(value); | 218 : g.UseUniqueRegister(value); |
221 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; | 219 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; |
222 switch (write_barrier_kind) { | 220 switch (write_barrier_kind) { |
223 case kNoWriteBarrier: | 221 case kNoWriteBarrier: |
(...skipping 11 matching lines...) Expand all Loading... |
235 } | 233 } |
236 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 234 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
237 size_t const temp_count = arraysize(temps); | 235 size_t const temp_count = arraysize(temps); |
238 InstructionCode code = kArchStoreWithWriteBarrier; | 236 InstructionCode code = kArchStoreWithWriteBarrier; |
239 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 237 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
240 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 238 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
241 } else { | 239 } else { |
242 ArchOpcode opcode; | 240 ArchOpcode opcode; |
243 ImmediateMode mode = kInt16Imm; | 241 ImmediateMode mode = kInt16Imm; |
244 switch (rep) { | 242 switch (rep) { |
245 case kRepFloat32: | 243 case MachineRepresentation::kFloat32: |
246 opcode = kPPC_StoreFloat32; | 244 opcode = kPPC_StoreFloat32; |
247 break; | 245 break; |
248 case kRepFloat64: | 246 case MachineRepresentation::kFloat64: |
249 opcode = kPPC_StoreDouble; | 247 opcode = kPPC_StoreDouble; |
250 break; | 248 break; |
251 case kRepBit: // Fall through. | 249 case MachineRepresentation::kBit: // Fall through. |
252 case kRepWord8: | 250 case MachineRepresentation::kWord8: |
253 opcode = kPPC_StoreWord8; | 251 opcode = kPPC_StoreWord8; |
254 break; | 252 break; |
255 case kRepWord16: | 253 case MachineRepresentation::kWord16: |
256 opcode = kPPC_StoreWord16; | 254 opcode = kPPC_StoreWord16; |
257 break; | 255 break; |
258 #if !V8_TARGET_ARCH_PPC64 | 256 #if !V8_TARGET_ARCH_PPC64 |
259 case kRepTagged: // Fall through. | 257 case MachineRepresentation::kTagged: // Fall through. |
260 #endif | 258 #endif |
261 case kRepWord32: | 259 case MachineRepresentation::kWord32: |
262 opcode = kPPC_StoreWord32; | 260 opcode = kPPC_StoreWord32; |
263 break; | 261 break; |
264 #if V8_TARGET_ARCH_PPC64 | 262 #if V8_TARGET_ARCH_PPC64 |
265 case kRepTagged: // Fall through. | 263 case MachineRepresentation::kTagged: // Fall through. |
266 case kRepWord64: | 264 case MachineRepresentation::kWord64: |
267 opcode = kPPC_StoreWord64; | 265 opcode = kPPC_StoreWord64; |
268 mode = kInt16Imm_4ByteAligned; | 266 mode = kInt16Imm_4ByteAligned; |
269 break; | 267 break; |
270 #endif | 268 #endif |
271 default: | 269 default: |
272 UNREACHABLE(); | 270 UNREACHABLE(); |
273 return; | 271 return; |
274 } | 272 } |
275 if (g.CanBeImmediate(offset, mode)) { | 273 if (g.CanBeImmediate(offset, mode)) { |
276 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 274 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
277 g.UseRegister(base), g.UseImmediate(offset), g.UseRegister(value)); | 275 g.UseRegister(base), g.UseImmediate(offset), g.UseRegister(value)); |
278 } else if (g.CanBeImmediate(base, mode)) { | 276 } else if (g.CanBeImmediate(base, mode)) { |
279 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 277 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
280 g.UseRegister(offset), g.UseImmediate(base), g.UseRegister(value)); | 278 g.UseRegister(offset), g.UseImmediate(base), g.UseRegister(value)); |
281 } else { | 279 } else { |
282 Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(), | 280 Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(), |
283 g.UseRegister(base), g.UseRegister(offset), g.UseRegister(value)); | 281 g.UseRegister(base), g.UseRegister(offset), g.UseRegister(value)); |
284 } | 282 } |
285 } | 283 } |
286 } | 284 } |
287 | 285 |
288 | 286 |
289 void InstructionSelector::VisitCheckedLoad(Node* node) { | 287 void InstructionSelector::VisitCheckedLoad(Node* node) { |
290 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 288 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
291 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | |
292 PPCOperandGenerator g(this); | 289 PPCOperandGenerator g(this); |
293 Node* const base = node->InputAt(0); | 290 Node* const base = node->InputAt(0); |
294 Node* const offset = node->InputAt(1); | 291 Node* const offset = node->InputAt(1); |
295 Node* const length = node->InputAt(2); | 292 Node* const length = node->InputAt(2); |
296 ArchOpcode opcode; | 293 ArchOpcode opcode; |
297 switch (rep) { | 294 switch (load_rep.representation()) { |
298 case kRepWord8: | 295 case MachineRepresentation::kWord8: |
299 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; | 296 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
300 break; | 297 break; |
301 case kRepWord16: | 298 case MachineRepresentation::kWord16: |
302 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; | 299 opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; |
303 break; | 300 break; |
304 case kRepWord32: | 301 case MachineRepresentation::kWord32: |
305 opcode = kCheckedLoadWord32; | 302 opcode = kCheckedLoadWord32; |
306 break; | 303 break; |
307 case kRepWord64: | 304 case MachineRepresentation::kWord64: |
308 opcode = kCheckedLoadWord64; | 305 opcode = kCheckedLoadWord64; |
309 break; | 306 break; |
310 case kRepFloat32: | 307 case MachineRepresentation::kFloat32: |
311 opcode = kCheckedLoadFloat32; | 308 opcode = kCheckedLoadFloat32; |
312 break; | 309 break; |
313 case kRepFloat64: | 310 case MachineRepresentation::kFloat64: |
314 opcode = kCheckedLoadFloat64; | 311 opcode = kCheckedLoadFloat64; |
315 break; | 312 break; |
316 default: | 313 default: |
317 UNREACHABLE(); | 314 UNREACHABLE(); |
318 return; | 315 return; |
319 } | 316 } |
320 AddressingMode addressingMode = kMode_MRR; | 317 AddressingMode addressingMode = kMode_MRR; |
321 Emit(opcode | AddressingModeField::encode(addressingMode), | 318 Emit(opcode | AddressingModeField::encode(addressingMode), |
322 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(offset), | 319 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(offset), |
323 g.UseOperand(length, kInt16Imm_Unsigned)); | 320 g.UseOperand(length, kInt16Imm_Unsigned)); |
324 } | 321 } |
325 | 322 |
326 | 323 |
327 void InstructionSelector::VisitCheckedStore(Node* node) { | 324 void InstructionSelector::VisitCheckedStore(Node* node) { |
328 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 325 MachineRepresentation rep = CheckedStoreRepresentationOf(node->op()); |
329 PPCOperandGenerator g(this); | 326 PPCOperandGenerator g(this); |
330 Node* const base = node->InputAt(0); | 327 Node* const base = node->InputAt(0); |
331 Node* const offset = node->InputAt(1); | 328 Node* const offset = node->InputAt(1); |
332 Node* const length = node->InputAt(2); | 329 Node* const length = node->InputAt(2); |
333 Node* const value = node->InputAt(3); | 330 Node* const value = node->InputAt(3); |
334 ArchOpcode opcode; | 331 ArchOpcode opcode; |
335 switch (rep) { | 332 switch (rep) { |
336 case kRepWord8: | 333 case MachineRepresentation::kWord8: |
337 opcode = kCheckedStoreWord8; | 334 opcode = kCheckedStoreWord8; |
338 break; | 335 break; |
339 case kRepWord16: | 336 case MachineRepresentation::kWord16: |
340 opcode = kCheckedStoreWord16; | 337 opcode = kCheckedStoreWord16; |
341 break; | 338 break; |
342 case kRepWord32: | 339 case MachineRepresentation::kWord32: |
343 opcode = kCheckedStoreWord32; | 340 opcode = kCheckedStoreWord32; |
344 break; | 341 break; |
345 case kRepWord64: | 342 case MachineRepresentation::kWord64: |
346 opcode = kCheckedStoreWord64; | 343 opcode = kCheckedStoreWord64; |
347 break; | 344 break; |
348 case kRepFloat32: | 345 case MachineRepresentation::kFloat32: |
349 opcode = kCheckedStoreFloat32; | 346 opcode = kCheckedStoreFloat32; |
350 break; | 347 break; |
351 case kRepFloat64: | 348 case MachineRepresentation::kFloat64: |
352 opcode = kCheckedStoreFloat64; | 349 opcode = kCheckedStoreFloat64; |
353 break; | 350 break; |
354 default: | 351 default: |
355 UNREACHABLE(); | 352 UNREACHABLE(); |
356 return; | 353 return; |
357 } | 354 } |
358 AddressingMode addressingMode = kMode_MRR; | 355 AddressingMode addressingMode = kMode_MRR; |
359 Emit(opcode | AddressingModeField::encode(addressingMode), g.NoOutput(), | 356 Emit(opcode | AddressingModeField::encode(addressingMode), g.NoOutput(), |
360 g.UseRegister(base), g.UseRegister(offset), | 357 g.UseRegister(base), g.UseRegister(offset), |
361 g.UseOperand(length, kInt16Imm_Unsigned), g.UseRegister(value)); | 358 g.UseOperand(length, kInt16Imm_Unsigned), g.UseRegister(value)); |
(...skipping 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1723 MachineOperatorBuilder::kFloat64RoundTruncate | | 1720 MachineOperatorBuilder::kFloat64RoundTruncate | |
1724 MachineOperatorBuilder::kFloat64RoundTiesAway | | 1721 MachineOperatorBuilder::kFloat64RoundTiesAway | |
1725 MachineOperatorBuilder::kWord32Popcnt | | 1722 MachineOperatorBuilder::kWord32Popcnt | |
1726 MachineOperatorBuilder::kWord64Popcnt; | 1723 MachineOperatorBuilder::kWord64Popcnt; |
1727 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. | 1724 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. |
1728 } | 1725 } |
1729 | 1726 |
1730 } // namespace compiler | 1727 } // namespace compiler |
1731 } // namespace internal | 1728 } // namespace internal |
1732 } // namespace v8 | 1729 } // namespace v8 |
OLD | NEW |