| 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 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 } else { | 162 } else { |
| 163 selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input)); | 163 selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input)); |
| 164 } | 164 } |
| 165 } | 165 } |
| 166 | 166 |
| 167 | 167 |
| 168 } // namespace | 168 } // namespace |
| 169 | 169 |
| 170 | 170 |
| 171 void InstructionSelector::VisitLoad(Node* node) { | 171 void InstructionSelector::VisitLoad(Node* node) { |
| 172 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 172 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
| 173 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | |
| 174 | 173 |
| 175 ArchOpcode opcode; | 174 ArchOpcode opcode; |
| 176 switch (rep) { | 175 switch (load_rep.representation()) { |
| 177 case kRepFloat32: | 176 case MachineRepresentation::kFloat32: |
| 178 opcode = kIA32Movss; | 177 opcode = kIA32Movss; |
| 179 break; | 178 break; |
| 180 case kRepFloat64: | 179 case MachineRepresentation::kFloat64: |
| 181 opcode = kIA32Movsd; | 180 opcode = kIA32Movsd; |
| 182 break; | 181 break; |
| 183 case kRepBit: // Fall through. | 182 case MachineRepresentation::kBit: // Fall through. |
| 184 case kRepWord8: | 183 case MachineRepresentation::kWord8: |
| 185 opcode = typ == kTypeInt32 ? kIA32Movsxbl : kIA32Movzxbl; | 184 opcode = load_rep.IsSigned() ? kIA32Movsxbl : kIA32Movzxbl; |
| 186 break; | 185 break; |
| 187 case kRepWord16: | 186 case MachineRepresentation::kWord16: |
| 188 opcode = typ == kTypeInt32 ? kIA32Movsxwl : kIA32Movzxwl; | 187 opcode = load_rep.IsSigned() ? kIA32Movsxwl : kIA32Movzxwl; |
| 189 break; | 188 break; |
| 190 case kRepTagged: // Fall through. | 189 case MachineRepresentation::kTagged: // Fall through. |
| 191 case kRepWord32: | 190 case MachineRepresentation::kWord32: |
| 192 opcode = kIA32Movl; | 191 opcode = kIA32Movl; |
| 193 break; | 192 break; |
| 194 default: | 193 default: |
| 195 UNREACHABLE(); | 194 UNREACHABLE(); |
| 196 return; | 195 return; |
| 197 } | 196 } |
| 198 | 197 |
| 199 IA32OperandGenerator g(this); | 198 IA32OperandGenerator g(this); |
| 200 InstructionOperand outputs[1]; | 199 InstructionOperand outputs[1]; |
| 201 outputs[0] = g.DefineAsRegister(node); | 200 outputs[0] = g.DefineAsRegister(node); |
| 202 InstructionOperand inputs[3]; | 201 InstructionOperand inputs[3]; |
| 203 size_t input_count = 0; | 202 size_t input_count = 0; |
| 204 AddressingMode mode = | 203 AddressingMode mode = |
| 205 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 204 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
| 206 InstructionCode code = opcode | AddressingModeField::encode(mode); | 205 InstructionCode code = opcode | AddressingModeField::encode(mode); |
| 207 Emit(code, 1, outputs, input_count, inputs); | 206 Emit(code, 1, outputs, input_count, inputs); |
| 208 } | 207 } |
| 209 | 208 |
| 210 | 209 |
| 211 void InstructionSelector::VisitStore(Node* node) { | 210 void InstructionSelector::VisitStore(Node* node) { |
| 212 IA32OperandGenerator g(this); | 211 IA32OperandGenerator g(this); |
| 213 Node* base = node->InputAt(0); | 212 Node* base = node->InputAt(0); |
| 214 Node* index = node->InputAt(1); | 213 Node* index = node->InputAt(1); |
| 215 Node* value = node->InputAt(2); | 214 Node* value = node->InputAt(2); |
| 216 | 215 |
| 217 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 216 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
| 218 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 217 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
| 219 MachineType rep = RepresentationOf(store_rep.machine_type()); | 218 MachineRepresentation rep = store_rep.machine_type().representation(); |
| 220 | 219 |
| 221 if (write_barrier_kind != kNoWriteBarrier) { | 220 if (write_barrier_kind != kNoWriteBarrier) { |
| 222 DCHECK_EQ(kRepTagged, rep); | 221 DCHECK_EQ(MachineRepresentation::kTagged, rep); |
| 223 AddressingMode addressing_mode; | 222 AddressingMode addressing_mode; |
| 224 InstructionOperand inputs[3]; | 223 InstructionOperand inputs[3]; |
| 225 size_t input_count = 0; | 224 size_t input_count = 0; |
| 226 inputs[input_count++] = g.UseUniqueRegister(base); | 225 inputs[input_count++] = g.UseUniqueRegister(base); |
| 227 if (g.CanBeImmediate(index)) { | 226 if (g.CanBeImmediate(index)) { |
| 228 inputs[input_count++] = g.UseImmediate(index); | 227 inputs[input_count++] = g.UseImmediate(index); |
| 229 addressing_mode = kMode_MRI; | 228 addressing_mode = kMode_MRI; |
| 230 } else { | 229 } else { |
| 231 inputs[input_count++] = g.UseUniqueRegister(index); | 230 inputs[input_count++] = g.UseUniqueRegister(index); |
| 232 addressing_mode = kMode_MR1; | 231 addressing_mode = kMode_MR1; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 251 } | 250 } |
| 252 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 251 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
| 253 size_t const temp_count = arraysize(temps); | 252 size_t const temp_count = arraysize(temps); |
| 254 InstructionCode code = kArchStoreWithWriteBarrier; | 253 InstructionCode code = kArchStoreWithWriteBarrier; |
| 255 code |= AddressingModeField::encode(addressing_mode); | 254 code |= AddressingModeField::encode(addressing_mode); |
| 256 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 255 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
| 257 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 256 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
| 258 } else { | 257 } else { |
| 259 ArchOpcode opcode; | 258 ArchOpcode opcode; |
| 260 switch (rep) { | 259 switch (rep) { |
| 261 case kRepFloat32: | 260 case MachineRepresentation::kFloat32: |
| 262 opcode = kIA32Movss; | 261 opcode = kIA32Movss; |
| 263 break; | 262 break; |
| 264 case kRepFloat64: | 263 case MachineRepresentation::kFloat64: |
| 265 opcode = kIA32Movsd; | 264 opcode = kIA32Movsd; |
| 266 break; | 265 break; |
| 267 case kRepBit: // Fall through. | 266 case MachineRepresentation::kBit: // Fall through. |
| 268 case kRepWord8: | 267 case MachineRepresentation::kWord8: |
| 269 opcode = kIA32Movb; | 268 opcode = kIA32Movb; |
| 270 break; | 269 break; |
| 271 case kRepWord16: | 270 case MachineRepresentation::kWord16: |
| 272 opcode = kIA32Movw; | 271 opcode = kIA32Movw; |
| 273 break; | 272 break; |
| 274 case kRepTagged: // Fall through. | 273 case MachineRepresentation::kTagged: // Fall through. |
| 275 case kRepWord32: | 274 case MachineRepresentation::kWord32: |
| 276 opcode = kIA32Movl; | 275 opcode = kIA32Movl; |
| 277 break; | 276 break; |
| 278 default: | 277 default: |
| 279 UNREACHABLE(); | 278 UNREACHABLE(); |
| 280 return; | 279 return; |
| 281 } | 280 } |
| 282 | 281 |
| 283 InstructionOperand val; | 282 InstructionOperand val; |
| 284 if (g.CanBeImmediate(value)) { | 283 if (g.CanBeImmediate(value)) { |
| 285 val = g.UseImmediate(value); | 284 val = g.UseImmediate(value); |
| 286 } else if (rep == kRepWord8 || rep == kRepBit) { | 285 } else if (rep == MachineRepresentation::kWord8 || |
| 286 rep == MachineRepresentation::kBit) { |
| 287 val = g.UseByteRegister(value); | 287 val = g.UseByteRegister(value); |
| 288 } else { | 288 } else { |
| 289 val = g.UseRegister(value); | 289 val = g.UseRegister(value); |
| 290 } | 290 } |
| 291 | 291 |
| 292 InstructionOperand inputs[4]; | 292 InstructionOperand inputs[4]; |
| 293 size_t input_count = 0; | 293 size_t input_count = 0; |
| 294 AddressingMode addressing_mode = | 294 AddressingMode addressing_mode = |
| 295 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 295 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
| 296 InstructionCode code = | 296 InstructionCode code = |
| 297 opcode | AddressingModeField::encode(addressing_mode); | 297 opcode | AddressingModeField::encode(addressing_mode); |
| 298 inputs[input_count++] = val; | 298 inputs[input_count++] = val; |
| 299 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs); | 299 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs); |
| 300 } | 300 } |
| 301 } | 301 } |
| 302 | 302 |
| 303 | 303 |
| 304 void InstructionSelector::VisitCheckedLoad(Node* node) { | 304 void InstructionSelector::VisitCheckedLoad(Node* node) { |
| 305 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 305 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
| 306 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | |
| 307 IA32OperandGenerator g(this); | 306 IA32OperandGenerator g(this); |
| 308 Node* const buffer = node->InputAt(0); | 307 Node* const buffer = node->InputAt(0); |
| 309 Node* const offset = node->InputAt(1); | 308 Node* const offset = node->InputAt(1); |
| 310 Node* const length = node->InputAt(2); | 309 Node* const length = node->InputAt(2); |
| 311 ArchOpcode opcode; | 310 ArchOpcode opcode; |
| 312 switch (rep) { | 311 switch (load_rep.representation()) { |
| 313 case kRepWord8: | 312 case MachineRepresentation::kWord8: |
| 314 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; | 313 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
| 315 break; | 314 break; |
| 316 case kRepWord16: | 315 case MachineRepresentation::kWord16: |
| 317 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; | 316 opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; |
| 318 break; | 317 break; |
| 319 case kRepWord32: | 318 case MachineRepresentation::kWord32: |
| 320 opcode = kCheckedLoadWord32; | 319 opcode = kCheckedLoadWord32; |
| 321 break; | 320 break; |
| 322 case kRepFloat32: | 321 case MachineRepresentation::kFloat32: |
| 323 opcode = kCheckedLoadFloat32; | 322 opcode = kCheckedLoadFloat32; |
| 324 break; | 323 break; |
| 325 case kRepFloat64: | 324 case MachineRepresentation::kFloat64: |
| 326 opcode = kCheckedLoadFloat64; | 325 opcode = kCheckedLoadFloat64; |
| 327 break; | 326 break; |
| 328 default: | 327 default: |
| 329 UNREACHABLE(); | 328 UNREACHABLE(); |
| 330 return; | 329 return; |
| 331 } | 330 } |
| 332 InstructionOperand offset_operand = g.UseRegister(offset); | 331 InstructionOperand offset_operand = g.UseRegister(offset); |
| 333 InstructionOperand length_operand = | 332 InstructionOperand length_operand = |
| 334 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); | 333 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); |
| 335 if (g.CanBeImmediate(buffer)) { | 334 if (g.CanBeImmediate(buffer)) { |
| 336 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 335 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
| 337 g.DefineAsRegister(node), offset_operand, length_operand, | 336 g.DefineAsRegister(node), offset_operand, length_operand, |
| 338 offset_operand, g.UseImmediate(buffer)); | 337 offset_operand, g.UseImmediate(buffer)); |
| 339 } else { | 338 } else { |
| 340 Emit(opcode | AddressingModeField::encode(kMode_MR1), | 339 Emit(opcode | AddressingModeField::encode(kMode_MR1), |
| 341 g.DefineAsRegister(node), offset_operand, length_operand, | 340 g.DefineAsRegister(node), offset_operand, length_operand, |
| 342 g.UseRegister(buffer), offset_operand); | 341 g.UseRegister(buffer), offset_operand); |
| 343 } | 342 } |
| 344 } | 343 } |
| 345 | 344 |
| 346 | 345 |
| 347 void InstructionSelector::VisitCheckedStore(Node* node) { | 346 void InstructionSelector::VisitCheckedStore(Node* node) { |
| 348 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 347 MachineRepresentation rep = |
| 348 CheckedStoreRepresentationOf(node->op()).representation(); |
| 349 IA32OperandGenerator g(this); | 349 IA32OperandGenerator g(this); |
| 350 Node* const buffer = node->InputAt(0); | 350 Node* const buffer = node->InputAt(0); |
| 351 Node* const offset = node->InputAt(1); | 351 Node* const offset = node->InputAt(1); |
| 352 Node* const length = node->InputAt(2); | 352 Node* const length = node->InputAt(2); |
| 353 Node* const value = node->InputAt(3); | 353 Node* const value = node->InputAt(3); |
| 354 ArchOpcode opcode; | 354 ArchOpcode opcode; |
| 355 switch (rep) { | 355 switch (rep) { |
| 356 case kRepWord8: | 356 case MachineRepresentation::kWord8: |
| 357 opcode = kCheckedStoreWord8; | 357 opcode = kCheckedStoreWord8; |
| 358 break; | 358 break; |
| 359 case kRepWord16: | 359 case MachineRepresentation::kWord16: |
| 360 opcode = kCheckedStoreWord16; | 360 opcode = kCheckedStoreWord16; |
| 361 break; | 361 break; |
| 362 case kRepWord32: | 362 case MachineRepresentation::kWord32: |
| 363 opcode = kCheckedStoreWord32; | 363 opcode = kCheckedStoreWord32; |
| 364 break; | 364 break; |
| 365 case kRepFloat32: | 365 case MachineRepresentation::kFloat32: |
| 366 opcode = kCheckedStoreFloat32; | 366 opcode = kCheckedStoreFloat32; |
| 367 break; | 367 break; |
| 368 case kRepFloat64: | 368 case MachineRepresentation::kFloat64: |
| 369 opcode = kCheckedStoreFloat64; | 369 opcode = kCheckedStoreFloat64; |
| 370 break; | 370 break; |
| 371 default: | 371 default: |
| 372 UNREACHABLE(); | 372 UNREACHABLE(); |
| 373 return; | 373 return; |
| 374 } | 374 } |
| 375 InstructionOperand value_operand = | 375 InstructionOperand value_operand = |
| 376 g.CanBeImmediate(value) | 376 g.CanBeImmediate(value) ? g.UseImmediate(value) |
| 377 ? g.UseImmediate(value) | 377 : ((rep == MachineRepresentation::kWord8 || |
| 378 : ((rep == kRepWord8 || rep == kRepBit) ? g.UseByteRegister(value) | 378 rep == MachineRepresentation::kBit) |
| 379 : g.UseRegister(value)); | 379 ? g.UseByteRegister(value) |
| 380 : g.UseRegister(value)); |
| 380 InstructionOperand offset_operand = g.UseRegister(offset); | 381 InstructionOperand offset_operand = g.UseRegister(offset); |
| 381 InstructionOperand length_operand = | 382 InstructionOperand length_operand = |
| 382 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); | 383 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); |
| 383 if (g.CanBeImmediate(buffer)) { | 384 if (g.CanBeImmediate(buffer)) { |
| 384 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 385 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
| 385 offset_operand, length_operand, value_operand, offset_operand, | 386 offset_operand, length_operand, value_operand, offset_operand, |
| 386 g.UseImmediate(buffer)); | 387 g.UseImmediate(buffer)); |
| 387 } else { | 388 } else { |
| 388 Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(), | 389 Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(), |
| 389 offset_operand, length_operand, value_operand, g.UseRegister(buffer), | 390 offset_operand, length_operand, value_operand, g.UseRegister(buffer), |
| (...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1312 MachineOperatorBuilder::kFloat64RoundTruncate | | 1313 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 1313 MachineOperatorBuilder::kFloat32RoundTiesEven | | 1314 MachineOperatorBuilder::kFloat32RoundTiesEven | |
| 1314 MachineOperatorBuilder::kFloat64RoundTiesEven; | 1315 MachineOperatorBuilder::kFloat64RoundTiesEven; |
| 1315 } | 1316 } |
| 1316 return flags; | 1317 return flags; |
| 1317 } | 1318 } |
| 1318 | 1319 |
| 1319 } // namespace compiler | 1320 } // namespace compiler |
| 1320 } // namespace internal | 1321 } // namespace internal |
| 1321 } // namespace v8 | 1322 } // namespace v8 |
| OLD | NEW |