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 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 | 154 |
155 | 155 |
156 void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node, | 156 void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node, |
157 ImmediateMode operand_mode) { | 157 ImmediateMode operand_mode) { |
158 Arm64OperandGenerator g(selector); | 158 Arm64OperandGenerator g(selector); |
159 selector->Emit(opcode, g.DefineAsRegister(node), | 159 selector->Emit(opcode, g.DefineAsRegister(node), |
160 g.UseRegister(node->InputAt(0)), | 160 g.UseRegister(node->InputAt(0)), |
161 g.UseOperand(node->InputAt(1), operand_mode)); | 161 g.UseOperand(node->InputAt(1), operand_mode)); |
162 } | 162 } |
163 | 163 |
| 164 struct ExtendingLoadMatcher { |
| 165 ExtendingLoadMatcher(Node* node, InstructionSelector* selector) |
| 166 : matches_(false), selector_(selector), base_(nullptr), immediate_(0) { |
| 167 Initialize(node); |
| 168 } |
| 169 |
| 170 bool Matches() const { return matches_; } |
| 171 |
| 172 Node* base() const { |
| 173 DCHECK(Matches()); |
| 174 return base_; |
| 175 } |
| 176 int64_t immediate() const { |
| 177 DCHECK(Matches()); |
| 178 return immediate_; |
| 179 } |
| 180 ArchOpcode opcode() const { |
| 181 DCHECK(Matches()); |
| 182 return opcode_; |
| 183 } |
| 184 |
| 185 private: |
| 186 bool matches_; |
| 187 InstructionSelector* selector_; |
| 188 Node* base_; |
| 189 int64_t immediate_; |
| 190 ArchOpcode opcode_; |
| 191 |
| 192 void Initialize(Node* node) { |
| 193 Int64BinopMatcher m(node); |
| 194 // When loading a 64-bit value and shifting by 32, we should |
| 195 // just load and sign-extend the interesting 4 bytes instead. |
| 196 // This happens, for example, when we're loading and untagging SMIs. |
| 197 DCHECK(m.IsWord64Sar()); |
| 198 if (m.left().IsLoad() && m.right().Is(32) && |
| 199 selector_->CanCover(m.node(), m.left().node())) { |
| 200 Arm64OperandGenerator g(selector_); |
| 201 Node* load = m.left().node(); |
| 202 Node* offset = load->InputAt(1); |
| 203 base_ = load->InputAt(0); |
| 204 opcode_ = kArm64Ldrsw; |
| 205 if (g.IsIntegerConstant(offset)) { |
| 206 immediate_ = g.GetIntegerConstantValue(offset) + 4; |
| 207 matches_ = g.CanBeImmediate(immediate_, kLoadStoreImm32); |
| 208 } |
| 209 } |
| 210 } |
| 211 }; |
| 212 |
| 213 bool TryMatchExtendingLoad(InstructionSelector* selector, Node* node) { |
| 214 ExtendingLoadMatcher m(node, selector); |
| 215 return m.Matches(); |
| 216 } |
| 217 |
| 218 bool TryEmitExtendingLoad(InstructionSelector* selector, Node* node) { |
| 219 ExtendingLoadMatcher m(node, selector); |
| 220 Arm64OperandGenerator g(selector); |
| 221 if (m.Matches()) { |
| 222 InstructionOperand inputs[2]; |
| 223 inputs[0] = g.UseRegister(m.base()); |
| 224 InstructionCode opcode = |
| 225 m.opcode() | AddressingModeField::encode(kMode_MRI); |
| 226 DCHECK(is_int32(m.immediate())); |
| 227 inputs[1] = g.TempImmediate(static_cast<int32_t>(m.immediate())); |
| 228 InstructionOperand outputs[] = {g.DefineAsRegister(node)}; |
| 229 selector->Emit(opcode, arraysize(outputs), outputs, arraysize(inputs), |
| 230 inputs); |
| 231 return true; |
| 232 } |
| 233 return false; |
| 234 } |
| 235 |
164 bool TryMatchAnyShift(InstructionSelector* selector, Node* node, | 236 bool TryMatchAnyShift(InstructionSelector* selector, Node* node, |
165 Node* input_node, InstructionCode* opcode, bool try_ror) { | 237 Node* input_node, InstructionCode* opcode, bool try_ror) { |
166 Arm64OperandGenerator g(selector); | 238 Arm64OperandGenerator g(selector); |
167 | 239 |
168 if (!selector->CanCover(node, input_node)) return false; | 240 if (!selector->CanCover(node, input_node)) return false; |
169 if (input_node->InputCount() != 2) return false; | 241 if (input_node->InputCount() != 2) return false; |
170 if (!g.IsIntegerConstant(input_node->InputAt(1))) return false; | 242 if (!g.IsIntegerConstant(input_node->InputAt(1))) return false; |
171 | 243 |
172 switch (input_node->opcode()) { | 244 switch (input_node->opcode()) { |
173 case IrOpcode::kWord32Shl: | 245 case IrOpcode::kWord32Shl: |
174 case IrOpcode::kWord64Shl: | 246 case IrOpcode::kWord64Shl: |
175 *opcode |= AddressingModeField::encode(kMode_Operand2_R_LSL_I); | 247 *opcode |= AddressingModeField::encode(kMode_Operand2_R_LSL_I); |
176 return true; | 248 return true; |
177 case IrOpcode::kWord32Shr: | 249 case IrOpcode::kWord32Shr: |
178 case IrOpcode::kWord64Shr: | 250 case IrOpcode::kWord64Shr: |
179 *opcode |= AddressingModeField::encode(kMode_Operand2_R_LSR_I); | 251 *opcode |= AddressingModeField::encode(kMode_Operand2_R_LSR_I); |
180 return true; | 252 return true; |
181 case IrOpcode::kWord32Sar: | 253 case IrOpcode::kWord32Sar: |
| 254 *opcode |= AddressingModeField::encode(kMode_Operand2_R_ASR_I); |
| 255 return true; |
182 case IrOpcode::kWord64Sar: | 256 case IrOpcode::kWord64Sar: |
| 257 if (TryMatchExtendingLoad(selector, input_node)) return false; |
183 *opcode |= AddressingModeField::encode(kMode_Operand2_R_ASR_I); | 258 *opcode |= AddressingModeField::encode(kMode_Operand2_R_ASR_I); |
184 return true; | 259 return true; |
185 case IrOpcode::kWord32Ror: | 260 case IrOpcode::kWord32Ror: |
186 case IrOpcode::kWord64Ror: | 261 case IrOpcode::kWord64Ror: |
187 if (try_ror) { | 262 if (try_ror) { |
188 *opcode |= AddressingModeField::encode(kMode_Operand2_R_ROR_I); | 263 *opcode |= AddressingModeField::encode(kMode_Operand2_R_ROR_I); |
189 return true; | 264 return true; |
190 } | 265 } |
191 return false; | 266 return false; |
192 default: | 267 default: |
(...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1123 g.UseImmediate(node->InputAt(1))); | 1198 g.UseImmediate(node->InputAt(1))); |
1124 return; | 1199 return; |
1125 } | 1200 } |
1126 } | 1201 } |
1127 | 1202 |
1128 VisitRRO(this, kArm64Asr32, node, kShift32Imm); | 1203 VisitRRO(this, kArm64Asr32, node, kShift32Imm); |
1129 } | 1204 } |
1130 | 1205 |
1131 | 1206 |
1132 void InstructionSelector::VisitWord64Sar(Node* node) { | 1207 void InstructionSelector::VisitWord64Sar(Node* node) { |
| 1208 if (TryEmitExtendingLoad(this, node)) return; |
1133 VisitRRO(this, kArm64Asr, node, kShift64Imm); | 1209 VisitRRO(this, kArm64Asr, node, kShift64Imm); |
1134 } | 1210 } |
1135 | 1211 |
1136 | 1212 |
1137 void InstructionSelector::VisitWord32Ror(Node* node) { | 1213 void InstructionSelector::VisitWord32Ror(Node* node) { |
1138 VisitRRO(this, kArm64Ror32, node, kShift32Imm); | 1214 VisitRRO(this, kArm64Ror32, node, kShift32Imm); |
1139 } | 1215 } |
1140 | 1216 |
1141 | 1217 |
1142 void InstructionSelector::VisitWord64Ror(Node* node) { | 1218 void InstructionSelector::VisitWord64Ror(Node* node) { |
(...skipping 1570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2713 // static | 2789 // static |
2714 MachineOperatorBuilder::AlignmentRequirements | 2790 MachineOperatorBuilder::AlignmentRequirements |
2715 InstructionSelector::AlignmentRequirements() { | 2791 InstructionSelector::AlignmentRequirements() { |
2716 return MachineOperatorBuilder::AlignmentRequirements:: | 2792 return MachineOperatorBuilder::AlignmentRequirements:: |
2717 FullUnalignedAccessSupport(); | 2793 FullUnalignedAccessSupport(); |
2718 } | 2794 } |
2719 | 2795 |
2720 } // namespace compiler | 2796 } // namespace compiler |
2721 } // namespace internal | 2797 } // namespace internal |
2722 } // namespace v8 | 2798 } // namespace v8 |
OLD | NEW |