| 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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 } | 123 } |
| 124 } | 124 } |
| 125 | 125 |
| 126 bool CanBeBetterLeftOperand(Node* node) const { | 126 bool CanBeBetterLeftOperand(Node* node) const { |
| 127 return !selector()->IsLive(node); | 127 return !selector()->IsLive(node); |
| 128 } | 128 } |
| 129 }; | 129 }; |
| 130 | 130 |
| 131 | 131 |
| 132 void InstructionSelector::VisitLoad(Node* node) { | 132 void InstructionSelector::VisitLoad(Node* node) { |
| 133 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 133 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
| 134 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | |
| 135 | 134 |
| 136 ArchOpcode opcode; | 135 ArchOpcode opcode; |
| 137 switch (rep) { | 136 switch (load_rep.representation()) { |
| 138 case kRepFloat32: | 137 case MachineRepresentation::kFloat32: |
| 139 opcode = kX87Movss; | 138 opcode = kX87Movss; |
| 140 break; | 139 break; |
| 141 case kRepFloat64: | 140 case MachineRepresentation::kFloat64: |
| 142 opcode = kX87Movsd; | 141 opcode = kX87Movsd; |
| 143 break; | 142 break; |
| 144 case kRepBit: // Fall through. | 143 case MachineRepresentation::kBit: // Fall through. |
| 145 case kRepWord8: | 144 case MachineRepresentation::kWord8: |
| 146 opcode = typ == kTypeInt32 ? kX87Movsxbl : kX87Movzxbl; | 145 opcode = load_rep.IsSigned() ? kX87Movsxbl : kX87Movzxbl; |
| 147 break; | 146 break; |
| 148 case kRepWord16: | 147 case MachineRepresentation::kWord16: |
| 149 opcode = typ == kTypeInt32 ? kX87Movsxwl : kX87Movzxwl; | 148 opcode = load_rep.IsSigned() ? kX87Movsxwl : kX87Movzxwl; |
| 150 break; | 149 break; |
| 151 case kRepTagged: // Fall through. | 150 case MachineRepresentation::kTagged: // Fall through. |
| 152 case kRepWord32: | 151 case MachineRepresentation::kWord32: |
| 153 opcode = kX87Movl; | 152 opcode = kX87Movl; |
| 154 break; | 153 break; |
| 155 default: | 154 default: |
| 156 UNREACHABLE(); | 155 UNREACHABLE(); |
| 157 return; | 156 return; |
| 158 } | 157 } |
| 159 | 158 |
| 160 X87OperandGenerator g(this); | 159 X87OperandGenerator g(this); |
| 161 InstructionOperand outputs[1]; | 160 InstructionOperand outputs[1]; |
| 162 outputs[0] = g.DefineAsRegister(node); | 161 outputs[0] = g.DefineAsRegister(node); |
| 163 InstructionOperand inputs[3]; | 162 InstructionOperand inputs[3]; |
| 164 size_t input_count = 0; | 163 size_t input_count = 0; |
| 165 AddressingMode mode = | 164 AddressingMode mode = |
| 166 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 165 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
| 167 InstructionCode code = opcode | AddressingModeField::encode(mode); | 166 InstructionCode code = opcode | AddressingModeField::encode(mode); |
| 168 Emit(code, 1, outputs, input_count, inputs); | 167 Emit(code, 1, outputs, input_count, inputs); |
| 169 } | 168 } |
| 170 | 169 |
| 171 | 170 |
| 172 void InstructionSelector::VisitStore(Node* node) { | 171 void InstructionSelector::VisitStore(Node* node) { |
| 173 X87OperandGenerator g(this); | 172 X87OperandGenerator g(this); |
| 174 Node* base = node->InputAt(0); | 173 Node* base = node->InputAt(0); |
| 175 Node* index = node->InputAt(1); | 174 Node* index = node->InputAt(1); |
| 176 Node* value = node->InputAt(2); | 175 Node* value = node->InputAt(2); |
| 177 | 176 |
| 178 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 177 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
| 179 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 178 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
| 180 MachineType rep = RepresentationOf(store_rep.machine_type()); | 179 MachineRepresentation rep = store_rep.machine_type().representation(); |
| 181 | 180 |
| 182 if (write_barrier_kind != kNoWriteBarrier) { | 181 if (write_barrier_kind != kNoWriteBarrier) { |
| 183 DCHECK_EQ(kRepTagged, rep); | 182 DCHECK_EQ(MachineRepresentation::kTagged, rep); |
| 184 AddressingMode addressing_mode; | 183 AddressingMode addressing_mode; |
| 185 InstructionOperand inputs[3]; | 184 InstructionOperand inputs[3]; |
| 186 size_t input_count = 0; | 185 size_t input_count = 0; |
| 187 inputs[input_count++] = g.UseUniqueRegister(base); | 186 inputs[input_count++] = g.UseUniqueRegister(base); |
| 188 if (g.CanBeImmediate(index)) { | 187 if (g.CanBeImmediate(index)) { |
| 189 inputs[input_count++] = g.UseImmediate(index); | 188 inputs[input_count++] = g.UseImmediate(index); |
| 190 addressing_mode = kMode_MRI; | 189 addressing_mode = kMode_MRI; |
| 191 } else { | 190 } else { |
| 192 inputs[input_count++] = g.UseUniqueRegister(index); | 191 inputs[input_count++] = g.UseUniqueRegister(index); |
| 193 addressing_mode = kMode_MR1; | 192 addressing_mode = kMode_MR1; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 212 } | 211 } |
| 213 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 212 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
| 214 size_t const temp_count = arraysize(temps); | 213 size_t const temp_count = arraysize(temps); |
| 215 InstructionCode code = kArchStoreWithWriteBarrier; | 214 InstructionCode code = kArchStoreWithWriteBarrier; |
| 216 code |= AddressingModeField::encode(addressing_mode); | 215 code |= AddressingModeField::encode(addressing_mode); |
| 217 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 216 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
| 218 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 217 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
| 219 } else { | 218 } else { |
| 220 ArchOpcode opcode; | 219 ArchOpcode opcode; |
| 221 switch (rep) { | 220 switch (rep) { |
| 222 case kRepFloat32: | 221 case MachineRepresentation::kFloat32: |
| 223 opcode = kX87Movss; | 222 opcode = kX87Movss; |
| 224 break; | 223 break; |
| 225 case kRepFloat64: | 224 case MachineRepresentation::kFloat64: |
| 226 opcode = kX87Movsd; | 225 opcode = kX87Movsd; |
| 227 break; | 226 break; |
| 228 case kRepBit: // Fall through. | 227 case MachineRepresentation::kBit: // Fall through. |
| 229 case kRepWord8: | 228 case MachineRepresentation::kWord8: |
| 230 opcode = kX87Movb; | 229 opcode = kX87Movb; |
| 231 break; | 230 break; |
| 232 case kRepWord16: | 231 case MachineRepresentation::kWord16: |
| 233 opcode = kX87Movw; | 232 opcode = kX87Movw; |
| 234 break; | 233 break; |
| 235 case kRepTagged: // Fall through. | 234 case MachineRepresentation::kTagged: // Fall through. |
| 236 case kRepWord32: | 235 case MachineRepresentation::kWord32: |
| 237 opcode = kX87Movl; | 236 opcode = kX87Movl; |
| 238 break; | 237 break; |
| 239 default: | 238 default: |
| 240 UNREACHABLE(); | 239 UNREACHABLE(); |
| 241 return; | 240 return; |
| 242 } | 241 } |
| 243 | 242 |
| 244 InstructionOperand val; | 243 InstructionOperand val; |
| 245 if (g.CanBeImmediate(value)) { | 244 if (g.CanBeImmediate(value)) { |
| 246 val = g.UseImmediate(value); | 245 val = g.UseImmediate(value); |
| 247 } else if (rep == kRepWord8 || rep == kRepBit) { | 246 } else if (rep == MachineRepresentation::kWord8 || |
| 247 rep == MachineRepresentation::kBit) { |
| 248 val = g.UseByteRegister(value); | 248 val = g.UseByteRegister(value); |
| 249 } else { | 249 } else { |
| 250 val = g.UseRegister(value); | 250 val = g.UseRegister(value); |
| 251 } | 251 } |
| 252 | 252 |
| 253 InstructionOperand inputs[4]; | 253 InstructionOperand inputs[4]; |
| 254 size_t input_count = 0; | 254 size_t input_count = 0; |
| 255 AddressingMode addressing_mode = | 255 AddressingMode addressing_mode = |
| 256 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 256 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
| 257 InstructionCode code = | 257 InstructionCode code = |
| 258 opcode | AddressingModeField::encode(addressing_mode); | 258 opcode | AddressingModeField::encode(addressing_mode); |
| 259 inputs[input_count++] = val; | 259 inputs[input_count++] = val; |
| 260 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs); | 260 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs); |
| 261 } | 261 } |
| 262 } | 262 } |
| 263 | 263 |
| 264 | 264 |
| 265 void InstructionSelector::VisitCheckedLoad(Node* node) { | 265 void InstructionSelector::VisitCheckedLoad(Node* node) { |
| 266 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 266 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
| 267 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | |
| 268 X87OperandGenerator g(this); | 267 X87OperandGenerator g(this); |
| 269 Node* const buffer = node->InputAt(0); | 268 Node* const buffer = node->InputAt(0); |
| 270 Node* const offset = node->InputAt(1); | 269 Node* const offset = node->InputAt(1); |
| 271 Node* const length = node->InputAt(2); | 270 Node* const length = node->InputAt(2); |
| 272 ArchOpcode opcode; | 271 ArchOpcode opcode; |
| 273 switch (rep) { | 272 switch (load_rep.representation()) { |
| 274 case kRepWord8: | 273 case MachineRepresentation::kWord8: |
| 275 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; | 274 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
| 276 break; | 275 break; |
| 277 case kRepWord16: | 276 case MachineRepresentation::kWord16: |
| 278 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; | 277 opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; |
| 279 break; | 278 break; |
| 280 case kRepWord32: | 279 case MachineRepresentation::kWord32: |
| 281 opcode = kCheckedLoadWord32; | 280 opcode = kCheckedLoadWord32; |
| 282 break; | 281 break; |
| 283 case kRepFloat32: | 282 case MachineRepresentation::kFloat32: |
| 284 opcode = kCheckedLoadFloat32; | 283 opcode = kCheckedLoadFloat32; |
| 285 break; | 284 break; |
| 286 case kRepFloat64: | 285 case MachineRepresentation::kFloat64: |
| 287 opcode = kCheckedLoadFloat64; | 286 opcode = kCheckedLoadFloat64; |
| 288 break; | 287 break; |
| 289 default: | 288 default: |
| 290 UNREACHABLE(); | 289 UNREACHABLE(); |
| 291 return; | 290 return; |
| 292 } | 291 } |
| 293 InstructionOperand offset_operand = g.UseRegister(offset); | 292 InstructionOperand offset_operand = g.UseRegister(offset); |
| 294 InstructionOperand length_operand = | 293 InstructionOperand length_operand = |
| 295 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); | 294 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); |
| 296 if (g.CanBeImmediate(buffer)) { | 295 if (g.CanBeImmediate(buffer)) { |
| 297 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 296 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
| 298 g.DefineAsRegister(node), offset_operand, length_operand, | 297 g.DefineAsRegister(node), offset_operand, length_operand, |
| 299 offset_operand, g.UseImmediate(buffer)); | 298 offset_operand, g.UseImmediate(buffer)); |
| 300 } else { | 299 } else { |
| 301 Emit(opcode | AddressingModeField::encode(kMode_MR1), | 300 Emit(opcode | AddressingModeField::encode(kMode_MR1), |
| 302 g.DefineAsRegister(node), offset_operand, length_operand, | 301 g.DefineAsRegister(node), offset_operand, length_operand, |
| 303 g.UseRegister(buffer), offset_operand); | 302 g.UseRegister(buffer), offset_operand); |
| 304 } | 303 } |
| 305 } | 304 } |
| 306 | 305 |
| 307 | 306 |
| 308 void InstructionSelector::VisitCheckedStore(Node* node) { | 307 void InstructionSelector::VisitCheckedStore(Node* node) { |
| 309 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 308 MachineRepresentation rep = |
| 309 CheckedStoreRepresentationOf(node->op()).representation(); |
| 310 X87OperandGenerator g(this); | 310 X87OperandGenerator g(this); |
| 311 Node* const buffer = node->InputAt(0); | 311 Node* const buffer = node->InputAt(0); |
| 312 Node* const offset = node->InputAt(1); | 312 Node* const offset = node->InputAt(1); |
| 313 Node* const length = node->InputAt(2); | 313 Node* const length = node->InputAt(2); |
| 314 Node* const value = node->InputAt(3); | 314 Node* const value = node->InputAt(3); |
| 315 ArchOpcode opcode; | 315 ArchOpcode opcode; |
| 316 switch (rep) { | 316 switch (rep) { |
| 317 case kRepWord8: | 317 case MachineRepresentation::kWord8: |
| 318 opcode = kCheckedStoreWord8; | 318 opcode = kCheckedStoreWord8; |
| 319 break; | 319 break; |
| 320 case kRepWord16: | 320 case MachineRepresentation::kWord16: |
| 321 opcode = kCheckedStoreWord16; | 321 opcode = kCheckedStoreWord16; |
| 322 break; | 322 break; |
| 323 case kRepWord32: | 323 case MachineRepresentation::kWord32: |
| 324 opcode = kCheckedStoreWord32; | 324 opcode = kCheckedStoreWord32; |
| 325 break; | 325 break; |
| 326 case kRepFloat32: | 326 case MachineRepresentation::kFloat32: |
| 327 opcode = kCheckedStoreFloat32; | 327 opcode = kCheckedStoreFloat32; |
| 328 break; | 328 break; |
| 329 case kRepFloat64: | 329 case MachineRepresentation::kFloat64: |
| 330 opcode = kCheckedStoreFloat64; | 330 opcode = kCheckedStoreFloat64; |
| 331 break; | 331 break; |
| 332 default: | 332 default: |
| 333 UNREACHABLE(); | 333 UNREACHABLE(); |
| 334 return; | 334 return; |
| 335 } | 335 } |
| 336 InstructionOperand value_operand = | 336 InstructionOperand value_operand = |
| 337 g.CanBeImmediate(value) | 337 g.CanBeImmediate(value) ? g.UseImmediate(value) |
| 338 ? g.UseImmediate(value) | 338 : ((rep == MachineRepresentation::kWord8 || |
| 339 : ((rep == kRepWord8 || rep == kRepBit) ? g.UseByteRegister(value) | 339 rep == MachineRepresentation::kBit) |
| 340 : g.UseRegister(value)); | 340 ? g.UseByteRegister(value) |
| 341 : g.UseRegister(value)); |
| 341 InstructionOperand offset_operand = g.UseRegister(offset); | 342 InstructionOperand offset_operand = g.UseRegister(offset); |
| 342 InstructionOperand length_operand = | 343 InstructionOperand length_operand = |
| 343 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); | 344 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); |
| 344 if (g.CanBeImmediate(buffer)) { | 345 if (g.CanBeImmediate(buffer)) { |
| 345 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 346 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
| 346 offset_operand, length_operand, value_operand, offset_operand, | 347 offset_operand, length_operand, value_operand, offset_operand, |
| 347 g.UseImmediate(buffer)); | 348 g.UseImmediate(buffer)); |
| 348 } else { | 349 } else { |
| 349 Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(), | 350 Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(), |
| 350 offset_operand, length_operand, value_operand, g.UseRegister(buffer), | 351 offset_operand, length_operand, value_operand, g.UseRegister(buffer), |
| (...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1326 MachineOperatorBuilder::kFloat32RoundTruncate | | 1327 MachineOperatorBuilder::kFloat32RoundTruncate | |
| 1327 MachineOperatorBuilder::kFloat64RoundTruncate | | 1328 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 1328 MachineOperatorBuilder::kFloat32RoundTiesEven | | 1329 MachineOperatorBuilder::kFloat32RoundTiesEven | |
| 1329 MachineOperatorBuilder::kFloat64RoundTiesEven; | 1330 MachineOperatorBuilder::kFloat64RoundTiesEven; |
| 1330 return flags; | 1331 return flags; |
| 1331 } | 1332 } |
| 1332 | 1333 |
| 1333 } // namespace compiler | 1334 } // namespace compiler |
| 1334 } // namespace internal | 1335 } // namespace internal |
| 1335 } // namespace v8 | 1336 } // namespace v8 |
| OLD | NEW |