Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(808)

Side by Side Diff: src/compiler/arm64/instruction-selector-arm64.cc

Issue 1064813003: ARM64: Support sign extend for add and subtract (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 kMode_Operand2_R_LSR_I) || 150 kMode_Operand2_R_LSR_I) ||
151 TryMatchShift<Int64BinopMatcher>(selector, node, opcode, 151 TryMatchShift<Int64BinopMatcher>(selector, node, opcode,
152 IrOpcode::kWord64Sar, kShift64Imm, 152 IrOpcode::kWord64Sar, kShift64Imm,
153 kMode_Operand2_R_ASR_I) || 153 kMode_Operand2_R_ASR_I) ||
154 (try_ror && TryMatchShift<Int64BinopMatcher>( 154 (try_ror && TryMatchShift<Int64BinopMatcher>(
155 selector, node, opcode, IrOpcode::kWord64Ror, 155 selector, node, opcode, IrOpcode::kWord64Ror,
156 kShift64Imm, kMode_Operand2_R_ROR_I)); 156 kShift64Imm, kMode_Operand2_R_ROR_I));
157 } 157 }
158 158
159 159
160 bool TryMatchAnyExtend(InstructionSelector* selector, Node* node, 160 bool TryMatchAnyExtend(Arm64OperandGenerator* g, InstructionSelector* selector,
161 InstructionCode* opcode) { 161 Node* left_node, Node* right_node,
162 NodeMatcher nm(node); 162 InstructionOperand* left_op,
163 InstructionOperand* right_op, InstructionCode* opcode) {
164 NodeMatcher nm(right_node);
165
163 if (nm.IsWord32And()) { 166 if (nm.IsWord32And()) {
164 Int32BinopMatcher m(node); 167 Int32BinopMatcher mright(right_node);
165 if (m.right().HasValue()) { 168 if (mright.right().Is(0xff) || mright.right().Is(0xffff)) {
166 if (m.right().Value() == 0xff) { 169 int32_t mask = mright.right().Value();
167 *opcode |= AddressingModeField::encode(kMode_Operand2_R_UXTB); 170 *left_op = g->UseRegister(left_node);
168 return true; 171 *right_op = g->UseRegister(mright.left().node());
169 } else if (m.right().Value() == 0xffff) { 172 *opcode |= AddressingModeField::encode(
170 *opcode |= AddressingModeField::encode(kMode_Operand2_R_UXTH); 173 (mask == 0xff) ? kMode_Operand2_R_UXTB : kMode_Operand2_R_UXTH);
174 return true;
175 }
176 } else if (nm.IsWord32Sar()) {
177 Int32BinopMatcher mright(right_node);
178 if (selector->CanCover(mright.node(), mright.left().node()) &&
179 mright.left().IsWord32Shl()) {
180 Int32BinopMatcher mleft_of_right(mright.left().node());
181 if ((mright.right().Is(16) && mleft_of_right.right().Is(16)) ||
182 (mright.right().Is(24) && mleft_of_right.right().Is(24))) {
183 int32_t shift = mright.right().Value();
184 *left_op = g->UseRegister(left_node);
185 *right_op = g->UseRegister(mleft_of_right.left().node());
186 *opcode |= AddressingModeField::encode(
187 (shift == 24) ? kMode_Operand2_R_SXTB : kMode_Operand2_R_SXTH);
171 return true; 188 return true;
172 } 189 }
173 } 190 }
174 } 191 }
175 return false; 192 return false;
176 } 193 }
177 194
178 195
179 // Shared routine for multiple binary operations. 196 // Shared routine for multiple binary operations.
180 template <typename Matcher> 197 template <typename Matcher>
181 void VisitBinop(InstructionSelector* selector, Node* node, 198 void VisitBinop(InstructionSelector* selector, Node* node,
182 InstructionCode opcode, ImmediateMode operand_mode, 199 InstructionCode opcode, ImmediateMode operand_mode,
183 FlagsContinuation* cont) { 200 FlagsContinuation* cont) {
184 Arm64OperandGenerator g(selector); 201 Arm64OperandGenerator g(selector);
185 Matcher m(node); 202 Matcher m(node);
186 InstructionOperand inputs[4]; 203 InstructionOperand inputs[4];
187 size_t input_count = 0; 204 size_t input_count = 0;
188 InstructionOperand outputs[2]; 205 InstructionOperand outputs[2];
189 size_t output_count = 0; 206 size_t output_count = 0;
190 bool is_add_sub = false; 207 bool is_add_sub = false;
191 208
192 if (m.IsInt32Add() || m.IsInt64Add() || m.IsInt32Sub() || m.IsInt64Sub()) { 209 if (m.IsInt32Add() || m.IsInt64Add() || m.IsInt32Sub() || m.IsInt64Sub()) {
193 is_add_sub = true; 210 is_add_sub = true;
194 } 211 }
195 212
196 if (g.CanBeImmediate(m.right().node(), operand_mode)) { 213 Node* left_node = m.left().node();
197 inputs[input_count++] = g.UseRegister(m.left().node()); 214 Node* right_node = m.right().node();
198 inputs[input_count++] = g.UseImmediate(m.right().node()); 215
199 } else if (TryMatchAnyShift(selector, m.right().node(), &opcode, 216 if (g.CanBeImmediate(right_node, operand_mode)) {
200 !is_add_sub)) { 217 inputs[input_count++] = g.UseRegister(left_node);
201 Matcher m_shift(m.right().node()); 218 inputs[input_count++] = g.UseImmediate(right_node);
202 inputs[input_count++] = g.UseRegister(m.left().node()); 219 } else if (is_add_sub &&
220 TryMatchAnyExtend(&g, selector, left_node, right_node, &inputs[0],
221 &inputs[1], &opcode)) {
222 input_count += 2;
223 } else if (is_add_sub && m.HasProperty(Operator::kCommutative) &&
224 TryMatchAnyExtend(&g, selector, right_node, left_node, &inputs[0],
225 &inputs[1], &opcode)) {
226 input_count += 2;
227 } else if (TryMatchAnyShift(selector, right_node, &opcode, !is_add_sub)) {
228 Matcher m_shift(right_node);
229 inputs[input_count++] = g.UseRegister(left_node);
203 inputs[input_count++] = g.UseRegister(m_shift.left().node()); 230 inputs[input_count++] = g.UseRegister(m_shift.left().node());
204 inputs[input_count++] = g.UseImmediate(m_shift.right().node()); 231 inputs[input_count++] = g.UseImmediate(m_shift.right().node());
205 } else if (m.HasProperty(Operator::kCommutative) && 232 } else if (m.HasProperty(Operator::kCommutative) &&
206 TryMatchAnyShift(selector, m.left().node(), &opcode, 233 TryMatchAnyShift(selector, left_node, &opcode, !is_add_sub)) {
207 !is_add_sub)) { 234 Matcher m_shift(left_node);
208 Matcher m_shift(m.left().node()); 235 inputs[input_count++] = g.UseRegister(right_node);
209 inputs[input_count++] = g.UseRegister(m.right().node());
210 inputs[input_count++] = g.UseRegister(m_shift.left().node()); 236 inputs[input_count++] = g.UseRegister(m_shift.left().node());
211 inputs[input_count++] = g.UseImmediate(m_shift.right().node()); 237 inputs[input_count++] = g.UseImmediate(m_shift.right().node());
212 } else if (is_add_sub &&
213 TryMatchAnyExtend(selector, m.right().node(), &opcode)) {
214 Matcher mright(m.right().node());
215 inputs[input_count++] = g.UseRegister(m.left().node());
216 inputs[input_count++] = g.UseRegister(mright.left().node());
217 } else if (is_add_sub && m.HasProperty(Operator::kCommutative) &&
218 TryMatchAnyExtend(selector, m.left().node(), &opcode)) {
219 Matcher mleft(m.left().node());
220 inputs[input_count++] = g.UseRegister(m.right().node());
221 inputs[input_count++] = g.UseRegister(mleft.left().node());
222 } else { 238 } else {
223 inputs[input_count++] = g.UseRegister(m.left().node()); 239 inputs[input_count++] = g.UseRegister(left_node);
224 inputs[input_count++] = g.UseRegister(m.right().node()); 240 inputs[input_count++] = g.UseRegister(right_node);
225 } 241 }
226 242
227 if (cont->IsBranch()) { 243 if (cont->IsBranch()) {
228 inputs[input_count++] = g.Label(cont->true_block()); 244 inputs[input_count++] = g.Label(cont->true_block());
229 inputs[input_count++] = g.Label(cont->false_block()); 245 inputs[input_count++] = g.Label(cont->false_block());
230 } 246 }
231 247
232 outputs[output_count++] = g.DefineAsRegister(node); 248 outputs[output_count++] = g.DefineAsRegister(node);
233 if (cont->IsSet()) { 249 if (cont->IsSet()) {
234 outputs[output_count++] = g.DefineAsRegister(cont->result()); 250 outputs[output_count++] = g.DefineAsRegister(cont->result());
(...skipping 1510 matching lines...) Expand 10 before | Expand all | Expand 10 after
1745 MachineOperatorBuilder::kFloat64RoundTruncate | 1761 MachineOperatorBuilder::kFloat64RoundTruncate |
1746 MachineOperatorBuilder::kFloat64RoundTiesAway | 1762 MachineOperatorBuilder::kFloat64RoundTiesAway |
1747 MachineOperatorBuilder::kWord32ShiftIsSafe | 1763 MachineOperatorBuilder::kWord32ShiftIsSafe |
1748 MachineOperatorBuilder::kInt32DivIsSafe | 1764 MachineOperatorBuilder::kInt32DivIsSafe |
1749 MachineOperatorBuilder::kUint32DivIsSafe; 1765 MachineOperatorBuilder::kUint32DivIsSafe;
1750 } 1766 }
1751 1767
1752 } // namespace compiler 1768 } // namespace compiler
1753 } // namespace internal 1769 } // namespace internal
1754 } // namespace v8 1770 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/arm64/instruction-codes-arm64.h ('k') | test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698