| 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 | 
|---|