| 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/compiler/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
| 6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
| 7 | 7 |
| 8 namespace v8 { | 8 namespace v8 { |
| 9 namespace internal { | 9 namespace internal { |
| 10 namespace compiler { | 10 namespace compiler { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 inputs[(*input_count)++] = UseImmediate(displacement); | 60 inputs[(*input_count)++] = UseImmediate(displacement); |
| 61 mode = kMode_MRI; | 61 mode = kMode_MRI; |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 } else { | 64 } else { |
| 65 DCHECK(index != NULL); | 65 DCHECK(index != NULL); |
| 66 DCHECK(scale_exponent >= 0 && scale_exponent <= 3); | 66 DCHECK(scale_exponent >= 0 && scale_exponent <= 3); |
| 67 inputs[(*input_count)++] = UseRegister(index); | 67 inputs[(*input_count)++] = UseRegister(index); |
| 68 if (displacement != NULL) { | 68 if (displacement != NULL) { |
| 69 inputs[(*input_count)++] = UseImmediate(displacement); | 69 inputs[(*input_count)++] = UseImmediate(displacement); |
| 70 static const AddressingMode kMnI_modes[] = {kMode_M1I, kMode_M2I, | 70 static const AddressingMode kMnI_modes[] = {kMode_MRI, kMode_M2I, |
| 71 kMode_M4I, kMode_M8I}; | 71 kMode_M4I, kMode_M8I}; |
| 72 mode = kMnI_modes[scale_exponent]; | 72 mode = kMnI_modes[scale_exponent]; |
| 73 } else { | 73 } else { |
| 74 static const AddressingMode kMn_modes[] = {kMode_M1, kMode_MR1, | 74 static const AddressingMode kMn_modes[] = {kMode_MR, kMode_MR1, |
| 75 kMode_M4, kMode_M8}; | 75 kMode_M4, kMode_M8}; |
| 76 mode = kMn_modes[scale_exponent]; | 76 mode = kMn_modes[scale_exponent]; |
| 77 if (mode == kMode_MR1) { | 77 if (mode == kMode_MR1) { |
| 78 // [%r1 + %r1*1] has a smaller encoding than [%r1*2+0] | 78 // [%r1 + %r1*1] has a smaller encoding than [%r1*2+0] |
| 79 inputs[(*input_count)++] = UseRegister(index); | 79 inputs[(*input_count)++] = UseRegister(index); |
| 80 } | 80 } |
| 81 } | 81 } |
| 82 } | 82 } |
| 83 return mode; | 83 return mode; |
| 84 } | 84 } |
| 85 | 85 |
| 86 AddressingMode GetEffectiveAddressMemoryOperand(Node* operand, |
| 87 InstructionOperand* inputs[], |
| 88 size_t* input_count) { |
| 89 BaseWithIndexAndDisplacement64Matcher m(operand, true); |
| 90 DCHECK(m.matches()); |
| 91 if ((m.displacement() == NULL || CanBeImmediate(m.displacement()))) { |
| 92 return GenerateMemoryOperandInputs(m.index(), m.scale(), m.base(), |
| 93 m.displacement(), inputs, input_count); |
| 94 } else { |
| 95 inputs[(*input_count)++] = UseRegister(operand->InputAt(0)); |
| 96 inputs[(*input_count)++] = UseRegister(operand->InputAt(1)); |
| 97 return kMode_MR1; |
| 98 } |
| 99 } |
| 100 |
| 86 bool CanBeBetterLeftOperand(Node* node) const { | 101 bool CanBeBetterLeftOperand(Node* node) const { |
| 87 return !selector()->IsLive(node); | 102 return !selector()->IsLive(node); |
| 88 } | 103 } |
| 89 }; | 104 }; |
| 90 | 105 |
| 91 | 106 |
| 92 void InstructionSelector::VisitLoad(Node* node) { | 107 void InstructionSelector::VisitLoad(Node* node) { |
| 93 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 108 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); |
| 94 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | 109 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); |
| 95 X64OperandGenerator g(this); | 110 X64OperandGenerator g(this); |
| 96 Node* const base = node->InputAt(0); | |
| 97 Node* const index = node->InputAt(1); | |
| 98 | 111 |
| 99 ArchOpcode opcode; | 112 ArchOpcode opcode; |
| 100 switch (rep) { | 113 switch (rep) { |
| 101 case kRepFloat32: | 114 case kRepFloat32: |
| 102 opcode = kX64Movss; | 115 opcode = kX64Movss; |
| 103 break; | 116 break; |
| 104 case kRepFloat64: | 117 case kRepFloat64: |
| 105 opcode = kX64Movsd; | 118 opcode = kX64Movsd; |
| 106 break; | 119 break; |
| 107 case kRepBit: // Fall through. | 120 case kRepBit: // Fall through. |
| 108 case kRepWord8: | 121 case kRepWord8: |
| 109 opcode = typ == kTypeInt32 ? kX64Movsxbl : kX64Movzxbl; | 122 opcode = typ == kTypeInt32 ? kX64Movsxbl : kX64Movzxbl; |
| 110 break; | 123 break; |
| 111 case kRepWord16: | 124 case kRepWord16: |
| 112 opcode = typ == kTypeInt32 ? kX64Movsxwl : kX64Movzxwl; | 125 opcode = typ == kTypeInt32 ? kX64Movsxwl : kX64Movzxwl; |
| 113 break; | 126 break; |
| 114 case kRepWord32: | 127 case kRepWord32: |
| 115 opcode = kX64Movl; | 128 opcode = kX64Movl; |
| 116 break; | 129 break; |
| 117 case kRepTagged: // Fall through. | 130 case kRepTagged: // Fall through. |
| 118 case kRepWord64: | 131 case kRepWord64: |
| 119 opcode = kX64Movq; | 132 opcode = kX64Movq; |
| 120 break; | 133 break; |
| 121 default: | 134 default: |
| 122 UNREACHABLE(); | 135 UNREACHABLE(); |
| 123 return; | 136 return; |
| 124 } | 137 } |
| 125 if (g.CanBeImmediate(index)) { | 138 |
| 126 // load [%base + #index] | 139 InstructionOperand* outputs[1]; |
| 127 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 140 outputs[0] = g.DefineAsRegister(node); |
| 128 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); | 141 InstructionOperand* inputs[3]; |
| 129 } else if (g.CanBeImmediate(base)) { | 142 size_t input_count = 0; |
| 130 // load [#base + %index] | 143 AddressingMode mode = |
| 131 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 144 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
| 132 g.DefineAsRegister(node), g.UseRegister(index), g.UseImmediate(base)); | 145 InstructionCode code = opcode | AddressingModeField::encode(mode); |
| 133 } else { | 146 Emit(code, 1, outputs, input_count, inputs); |
| 134 // load [%base + %index*1] | |
| 135 Emit(opcode | AddressingModeField::encode(kMode_MR1), | |
| 136 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index)); | |
| 137 } | |
| 138 } | 147 } |
| 139 | 148 |
| 140 | 149 |
| 141 void InstructionSelector::VisitStore(Node* node) { | 150 void InstructionSelector::VisitStore(Node* node) { |
| 142 X64OperandGenerator g(this); | 151 X64OperandGenerator g(this); |
| 143 Node* base = node->InputAt(0); | 152 Node* base = node->InputAt(0); |
| 144 Node* index = node->InputAt(1); | 153 Node* index = node->InputAt(1); |
| 145 Node* value = node->InputAt(2); | 154 Node* value = node->InputAt(2); |
| 146 | 155 |
| 147 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 156 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 177 opcode = kX64Movl; | 186 opcode = kX64Movl; |
| 178 break; | 187 break; |
| 179 case kRepTagged: // Fall through. | 188 case kRepTagged: // Fall through. |
| 180 case kRepWord64: | 189 case kRepWord64: |
| 181 opcode = kX64Movq; | 190 opcode = kX64Movq; |
| 182 break; | 191 break; |
| 183 default: | 192 default: |
| 184 UNREACHABLE(); | 193 UNREACHABLE(); |
| 185 return; | 194 return; |
| 186 } | 195 } |
| 196 InstructionOperand* inputs[4]; |
| 197 size_t input_count = 0; |
| 198 AddressingMode mode = |
| 199 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
| 200 InstructionCode code = opcode | AddressingModeField::encode(mode); |
| 187 InstructionOperand* value_operand = | 201 InstructionOperand* value_operand = |
| 188 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); | 202 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); |
| 189 if (g.CanBeImmediate(index)) { | 203 inputs[input_count++] = value_operand; |
| 190 // store [%base + #index], %|#value | 204 Emit(code, 0, static_cast<InstructionOperand**>(NULL), input_count, inputs); |
| 191 Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, | |
| 192 g.UseRegister(base), g.UseImmediate(index), value_operand); | |
| 193 } else if (g.CanBeImmediate(base)) { | |
| 194 // store [#base + %index], %|#value | |
| 195 Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, | |
| 196 g.UseRegister(index), g.UseImmediate(base), value_operand); | |
| 197 } else { | |
| 198 // store [%base + %index*1], %|#value | |
| 199 Emit(opcode | AddressingModeField::encode(kMode_MR1), nullptr, | |
| 200 g.UseRegister(base), g.UseRegister(index), value_operand); | |
| 201 } | |
| 202 } | 205 } |
| 203 | 206 |
| 204 | 207 |
| 205 void InstructionSelector::VisitCheckedLoad(Node* node) { | 208 void InstructionSelector::VisitCheckedLoad(Node* node) { |
| 206 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 209 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); |
| 207 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | 210 MachineType typ = TypeOf(OpParameter<MachineType>(node)); |
| 208 X64OperandGenerator g(this); | 211 X64OperandGenerator g(this); |
| 209 Node* const buffer = node->InputAt(0); | 212 Node* const buffer = node->InputAt(0); |
| 210 Node* const offset = node->InputAt(1); | 213 Node* const offset = node->InputAt(1); |
| 211 Node* const length = node->InputAt(2); | 214 Node* const length = node->InputAt(2); |
| (...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1314 MachineOperatorBuilder::kFloat64Ceil | | 1317 MachineOperatorBuilder::kFloat64Ceil | |
| 1315 MachineOperatorBuilder::kFloat64RoundTruncate | | 1318 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 1316 MachineOperatorBuilder::kWord32ShiftIsSafe; | 1319 MachineOperatorBuilder::kWord32ShiftIsSafe; |
| 1317 } | 1320 } |
| 1318 return MachineOperatorBuilder::kNoFlags; | 1321 return MachineOperatorBuilder::kNoFlags; |
| 1319 } | 1322 } |
| 1320 | 1323 |
| 1321 } // namespace compiler | 1324 } // namespace compiler |
| 1322 } // namespace internal | 1325 } // namespace internal |
| 1323 } // namespace v8 | 1326 } // namespace v8 |
| OLD | NEW |