| 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 <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include "src/base/adapters.h" | 7 #include "src/base/adapters.h" |
| 8 #include "src/compiler/instruction-selector-impl.h" | 8 #include "src/compiler/instruction-selector-impl.h" |
| 9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
| 10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 } | 101 } |
| 102 } | 102 } |
| 103 | 103 |
| 104 bool CanBeBetterLeftOperand(Node* node) const { | 104 bool CanBeBetterLeftOperand(Node* node) const { |
| 105 return !selector()->IsLive(node); | 105 return !selector()->IsLive(node); |
| 106 } | 106 } |
| 107 }; | 107 }; |
| 108 | 108 |
| 109 | 109 |
| 110 void InstructionSelector::VisitLoad(Node* node) { | 110 void InstructionSelector::VisitLoad(Node* node) { |
| 111 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 111 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
| 112 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | |
| 113 X64OperandGenerator g(this); | 112 X64OperandGenerator g(this); |
| 114 | 113 |
| 115 ArchOpcode opcode; | 114 ArchOpcode opcode; |
| 116 switch (rep) { | 115 switch (load_rep.representation()) { |
| 117 case kRepFloat32: | 116 case MachineRepresentation::kFloat32: |
| 118 opcode = kX64Movss; | 117 opcode = kX64Movss; |
| 119 break; | 118 break; |
| 120 case kRepFloat64: | 119 case MachineRepresentation::kFloat64: |
| 121 opcode = kX64Movsd; | 120 opcode = kX64Movsd; |
| 122 break; | 121 break; |
| 123 case kRepBit: // Fall through. | 122 case MachineRepresentation::kBit: // Fall through. |
| 124 case kRepWord8: | 123 case MachineRepresentation::kWord8: |
| 125 opcode = typ == kTypeInt32 ? kX64Movsxbl : kX64Movzxbl; | 124 opcode = load_rep.IsSigned() ? kX64Movsxbl : kX64Movzxbl; |
| 126 break; | 125 break; |
| 127 case kRepWord16: | 126 case MachineRepresentation::kWord16: |
| 128 opcode = typ == kTypeInt32 ? kX64Movsxwl : kX64Movzxwl; | 127 opcode = load_rep.IsSigned() ? kX64Movsxwl : kX64Movzxwl; |
| 129 break; | 128 break; |
| 130 case kRepWord32: | 129 case MachineRepresentation::kWord32: |
| 131 opcode = kX64Movl; | 130 opcode = kX64Movl; |
| 132 break; | 131 break; |
| 133 case kRepTagged: // Fall through. | 132 case MachineRepresentation::kTagged: // Fall through. |
| 134 case kRepWord64: | 133 case MachineRepresentation::kWord64: |
| 135 opcode = kX64Movq; | 134 opcode = kX64Movq; |
| 136 break; | 135 break; |
| 137 default: | 136 default: |
| 138 UNREACHABLE(); | 137 UNREACHABLE(); |
| 139 return; | 138 return; |
| 140 } | 139 } |
| 141 | 140 |
| 142 InstructionOperand outputs[1]; | 141 InstructionOperand outputs[1]; |
| 143 outputs[0] = g.DefineAsRegister(node); | 142 outputs[0] = g.DefineAsRegister(node); |
| 144 InstructionOperand inputs[3]; | 143 InstructionOperand inputs[3]; |
| 145 size_t input_count = 0; | 144 size_t input_count = 0; |
| 146 AddressingMode mode = | 145 AddressingMode mode = |
| 147 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 146 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
| 148 InstructionCode code = opcode | AddressingModeField::encode(mode); | 147 InstructionCode code = opcode | AddressingModeField::encode(mode); |
| 149 Emit(code, 1, outputs, input_count, inputs); | 148 Emit(code, 1, outputs, input_count, inputs); |
| 150 } | 149 } |
| 151 | 150 |
| 152 | 151 |
| 153 void InstructionSelector::VisitStore(Node* node) { | 152 void InstructionSelector::VisitStore(Node* node) { |
| 154 X64OperandGenerator g(this); | 153 X64OperandGenerator g(this); |
| 155 Node* base = node->InputAt(0); | 154 Node* base = node->InputAt(0); |
| 156 Node* index = node->InputAt(1); | 155 Node* index = node->InputAt(1); |
| 157 Node* value = node->InputAt(2); | 156 Node* value = node->InputAt(2); |
| 158 | 157 |
| 159 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 158 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
| 160 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 159 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
| 161 MachineType rep = RepresentationOf(store_rep.machine_type()); | 160 MachineRepresentation rep = store_rep.machine_type().representation(); |
| 162 | 161 |
| 163 if (write_barrier_kind != kNoWriteBarrier) { | 162 if (write_barrier_kind != kNoWriteBarrier) { |
| 164 DCHECK_EQ(kRepTagged, rep); | 163 DCHECK_EQ(MachineRepresentation::kTagged, rep); |
| 165 AddressingMode addressing_mode; | 164 AddressingMode addressing_mode; |
| 166 InstructionOperand inputs[3]; | 165 InstructionOperand inputs[3]; |
| 167 size_t input_count = 0; | 166 size_t input_count = 0; |
| 168 inputs[input_count++] = g.UseUniqueRegister(base); | 167 inputs[input_count++] = g.UseUniqueRegister(base); |
| 169 if (g.CanBeImmediate(index)) { | 168 if (g.CanBeImmediate(index)) { |
| 170 inputs[input_count++] = g.UseImmediate(index); | 169 inputs[input_count++] = g.UseImmediate(index); |
| 171 addressing_mode = kMode_MRI; | 170 addressing_mode = kMode_MRI; |
| 172 } else { | 171 } else { |
| 173 inputs[input_count++] = g.UseUniqueRegister(index); | 172 inputs[input_count++] = g.UseUniqueRegister(index); |
| 174 addressing_mode = kMode_MR1; | 173 addressing_mode = kMode_MR1; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 193 } | 192 } |
| 194 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 193 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
| 195 size_t const temp_count = arraysize(temps); | 194 size_t const temp_count = arraysize(temps); |
| 196 InstructionCode code = kArchStoreWithWriteBarrier; | 195 InstructionCode code = kArchStoreWithWriteBarrier; |
| 197 code |= AddressingModeField::encode(addressing_mode); | 196 code |= AddressingModeField::encode(addressing_mode); |
| 198 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 197 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
| 199 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 198 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
| 200 } else { | 199 } else { |
| 201 ArchOpcode opcode; | 200 ArchOpcode opcode; |
| 202 switch (rep) { | 201 switch (rep) { |
| 203 case kRepFloat32: | 202 case MachineRepresentation::kFloat32: |
| 204 opcode = kX64Movss; | 203 opcode = kX64Movss; |
| 205 break; | 204 break; |
| 206 case kRepFloat64: | 205 case MachineRepresentation::kFloat64: |
| 207 opcode = kX64Movsd; | 206 opcode = kX64Movsd; |
| 208 break; | 207 break; |
| 209 case kRepBit: // Fall through. | 208 case MachineRepresentation::kBit: // Fall through. |
| 210 case kRepWord8: | 209 case MachineRepresentation::kWord8: |
| 211 opcode = kX64Movb; | 210 opcode = kX64Movb; |
| 212 break; | 211 break; |
| 213 case kRepWord16: | 212 case MachineRepresentation::kWord16: |
| 214 opcode = kX64Movw; | 213 opcode = kX64Movw; |
| 215 break; | 214 break; |
| 216 case kRepWord32: | 215 case MachineRepresentation::kWord32: |
| 217 opcode = kX64Movl; | 216 opcode = kX64Movl; |
| 218 break; | 217 break; |
| 219 case kRepTagged: // Fall through. | 218 case MachineRepresentation::kTagged: // Fall through. |
| 220 case kRepWord64: | 219 case MachineRepresentation::kWord64: |
| 221 opcode = kX64Movq; | 220 opcode = kX64Movq; |
| 222 break; | 221 break; |
| 223 default: | 222 default: |
| 224 UNREACHABLE(); | 223 UNREACHABLE(); |
| 225 return; | 224 return; |
| 226 } | 225 } |
| 227 InstructionOperand inputs[4]; | 226 InstructionOperand inputs[4]; |
| 228 size_t input_count = 0; | 227 size_t input_count = 0; |
| 229 AddressingMode addressing_mode = | 228 AddressingMode addressing_mode = |
| 230 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 229 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
| 231 InstructionCode code = | 230 InstructionCode code = |
| 232 opcode | AddressingModeField::encode(addressing_mode); | 231 opcode | AddressingModeField::encode(addressing_mode); |
| 233 InstructionOperand value_operand = | 232 InstructionOperand value_operand = |
| 234 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); | 233 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); |
| 235 inputs[input_count++] = value_operand; | 234 inputs[input_count++] = value_operand; |
| 236 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs); | 235 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs); |
| 237 } | 236 } |
| 238 } | 237 } |
| 239 | 238 |
| 240 | 239 |
| 241 void InstructionSelector::VisitCheckedLoad(Node* node) { | 240 void InstructionSelector::VisitCheckedLoad(Node* node) { |
| 242 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 241 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
| 243 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | |
| 244 X64OperandGenerator g(this); | 242 X64OperandGenerator g(this); |
| 245 Node* const buffer = node->InputAt(0); | 243 Node* const buffer = node->InputAt(0); |
| 246 Node* const offset = node->InputAt(1); | 244 Node* const offset = node->InputAt(1); |
| 247 Node* const length = node->InputAt(2); | 245 Node* const length = node->InputAt(2); |
| 248 ArchOpcode opcode; | 246 ArchOpcode opcode; |
| 249 switch (rep) { | 247 switch (load_rep.representation()) { |
| 250 case kRepWord8: | 248 case MachineRepresentation::kWord8: |
| 251 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; | 249 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
| 252 break; | 250 break; |
| 253 case kRepWord16: | 251 case MachineRepresentation::kWord16: |
| 254 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; | 252 opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; |
| 255 break; | 253 break; |
| 256 case kRepWord32: | 254 case MachineRepresentation::kWord32: |
| 257 opcode = kCheckedLoadWord32; | 255 opcode = kCheckedLoadWord32; |
| 258 break; | 256 break; |
| 259 case kRepWord64: | 257 case MachineRepresentation::kWord64: |
| 260 opcode = kCheckedLoadWord64; | 258 opcode = kCheckedLoadWord64; |
| 261 break; | 259 break; |
| 262 case kRepFloat32: | 260 case MachineRepresentation::kFloat32: |
| 263 opcode = kCheckedLoadFloat32; | 261 opcode = kCheckedLoadFloat32; |
| 264 break; | 262 break; |
| 265 case kRepFloat64: | 263 case MachineRepresentation::kFloat64: |
| 266 opcode = kCheckedLoadFloat64; | 264 opcode = kCheckedLoadFloat64; |
| 267 break; | 265 break; |
| 268 default: | 266 default: |
| 269 UNREACHABLE(); | 267 UNREACHABLE(); |
| 270 return; | 268 return; |
| 271 } | 269 } |
| 272 if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { | 270 if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { |
| 273 Int32Matcher mlength(length); | 271 Int32Matcher mlength(length); |
| 274 Int32BinopMatcher moffset(offset); | 272 Int32BinopMatcher moffset(offset); |
| 275 if (mlength.HasValue() && moffset.right().HasValue() && | 273 if (mlength.HasValue() && moffset.right().HasValue() && |
| 276 moffset.right().Value() >= 0 && | 274 moffset.right().Value() >= 0 && |
| 277 mlength.Value() >= moffset.right().Value()) { | 275 mlength.Value() >= moffset.right().Value()) { |
| 278 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), | 276 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), |
| 279 g.UseRegister(moffset.left().node()), | 277 g.UseRegister(moffset.left().node()), |
| 280 g.UseImmediate(moffset.right().node()), g.UseImmediate(length)); | 278 g.UseImmediate(moffset.right().node()), g.UseImmediate(length)); |
| 281 return; | 279 return; |
| 282 } | 280 } |
| 283 } | 281 } |
| 284 InstructionOperand length_operand = | 282 InstructionOperand length_operand = |
| 285 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); | 283 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); |
| 286 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), | 284 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), |
| 287 g.UseRegister(offset), g.TempImmediate(0), length_operand); | 285 g.UseRegister(offset), g.TempImmediate(0), length_operand); |
| 288 } | 286 } |
| 289 | 287 |
| 290 | 288 |
| 291 void InstructionSelector::VisitCheckedStore(Node* node) { | 289 void InstructionSelector::VisitCheckedStore(Node* node) { |
| 292 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 290 MachineRepresentation rep = |
| 291 CheckedStoreRepresentationOf(node->op()).representation(); |
| 293 X64OperandGenerator g(this); | 292 X64OperandGenerator g(this); |
| 294 Node* const buffer = node->InputAt(0); | 293 Node* const buffer = node->InputAt(0); |
| 295 Node* const offset = node->InputAt(1); | 294 Node* const offset = node->InputAt(1); |
| 296 Node* const length = node->InputAt(2); | 295 Node* const length = node->InputAt(2); |
| 297 Node* const value = node->InputAt(3); | 296 Node* const value = node->InputAt(3); |
| 298 ArchOpcode opcode; | 297 ArchOpcode opcode; |
| 299 switch (rep) { | 298 switch (rep) { |
| 300 case kRepWord8: | 299 case MachineRepresentation::kWord8: |
| 301 opcode = kCheckedStoreWord8; | 300 opcode = kCheckedStoreWord8; |
| 302 break; | 301 break; |
| 303 case kRepWord16: | 302 case MachineRepresentation::kWord16: |
| 304 opcode = kCheckedStoreWord16; | 303 opcode = kCheckedStoreWord16; |
| 305 break; | 304 break; |
| 306 case kRepWord32: | 305 case MachineRepresentation::kWord32: |
| 307 opcode = kCheckedStoreWord32; | 306 opcode = kCheckedStoreWord32; |
| 308 break; | 307 break; |
| 309 case kRepWord64: | 308 case MachineRepresentation::kWord64: |
| 310 opcode = kCheckedStoreWord64; | 309 opcode = kCheckedStoreWord64; |
| 311 break; | 310 break; |
| 312 case kRepFloat32: | 311 case MachineRepresentation::kFloat32: |
| 313 opcode = kCheckedStoreFloat32; | 312 opcode = kCheckedStoreFloat32; |
| 314 break; | 313 break; |
| 315 case kRepFloat64: | 314 case MachineRepresentation::kFloat64: |
| 316 opcode = kCheckedStoreFloat64; | 315 opcode = kCheckedStoreFloat64; |
| 317 break; | 316 break; |
| 318 default: | 317 default: |
| 319 UNREACHABLE(); | 318 UNREACHABLE(); |
| 320 return; | 319 return; |
| 321 } | 320 } |
| 322 InstructionOperand value_operand = | 321 InstructionOperand value_operand = |
| 323 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); | 322 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); |
| 324 if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { | 323 if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { |
| 325 Int32Matcher mlength(length); | 324 Int32Matcher mlength(length); |
| (...skipping 1435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1761 MachineOperatorBuilder::kFloat64RoundTruncate | | 1760 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 1762 MachineOperatorBuilder::kFloat32RoundTiesEven | | 1761 MachineOperatorBuilder::kFloat32RoundTiesEven | |
| 1763 MachineOperatorBuilder::kFloat64RoundTiesEven; | 1762 MachineOperatorBuilder::kFloat64RoundTiesEven; |
| 1764 } | 1763 } |
| 1765 return flags; | 1764 return flags; |
| 1766 } | 1765 } |
| 1767 | 1766 |
| 1768 } // namespace compiler | 1767 } // namespace compiler |
| 1769 } // namespace internal | 1768 } // namespace internal |
| 1770 } // namespace v8 | 1769 } // namespace v8 |
| OLD | NEW |