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

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

Issue 2470133005: MIPS[64]: Port '[turbofan] Use zr to store immediate zero' (Closed)
Patch Set: Created 4 years, 1 month 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
« no previous file with comments | « src/compiler/mips/code-generator-mips.cc ('k') | src/compiler/mips64/code-generator-mips64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/base/adapters.h" 5 #include "src/base/adapters.h"
6 #include "src/base/bits.h" 6 #include "src/base/bits.h"
7 #include "src/compiler/instruction-selector-impl.h" 7 #include "src/compiler/instruction-selector-impl.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/node-properties.h" 9 #include "src/compiler/node-properties.h"
10 10
(...skipping 13 matching lines...) Expand all
24 explicit MipsOperandGenerator(InstructionSelector* selector) 24 explicit MipsOperandGenerator(InstructionSelector* selector)
25 : OperandGenerator(selector) {} 25 : OperandGenerator(selector) {}
26 26
27 InstructionOperand UseOperand(Node* node, InstructionCode opcode) { 27 InstructionOperand UseOperand(Node* node, InstructionCode opcode) {
28 if (CanBeImmediate(node, opcode)) { 28 if (CanBeImmediate(node, opcode)) {
29 return UseImmediate(node); 29 return UseImmediate(node);
30 } 30 }
31 return UseRegister(node); 31 return UseRegister(node);
32 } 32 }
33 33
34 // Use the zero register if the node has the immediate value zero, otherwise
35 // assign a register.
36 InstructionOperand UseRegisterOrImmediateZero(Node* node) {
37 if ((IsIntegerConstant(node) && (GetIntegerConstantValue(node) == 0)) ||
38 (IsFloatConstant(node) &&
39 (bit_cast<int64_t>(GetFloatConstantValue(node)) == V8_INT64_C(0)))) {
40 return UseImmediate(node);
41 }
42 return UseRegister(node);
43 }
44
45 bool IsIntegerConstant(Node* node) {
46 return (node->opcode() == IrOpcode::kInt32Constant);
47 }
48
49 int64_t GetIntegerConstantValue(Node* node) {
50 DCHECK(node->opcode() == IrOpcode::kInt32Constant);
51 return OpParameter<int32_t>(node);
52 }
53
54 bool IsFloatConstant(Node* node) {
55 return (node->opcode() == IrOpcode::kFloat32Constant) ||
56 (node->opcode() == IrOpcode::kFloat64Constant);
57 }
58
59 double GetFloatConstantValue(Node* node) {
60 if (node->opcode() == IrOpcode::kFloat32Constant) {
61 return OpParameter<float>(node);
62 }
63 DCHECK_EQ(IrOpcode::kFloat64Constant, node->opcode());
64 return OpParameter<double>(node);
65 }
66
34 bool CanBeImmediate(Node* node, InstructionCode opcode) { 67 bool CanBeImmediate(Node* node, InstructionCode opcode) {
35 Int32Matcher m(node); 68 Int32Matcher m(node);
36 if (!m.HasValue()) return false; 69 if (!m.HasValue()) return false;
37 int32_t value = m.Value(); 70 int32_t value = m.Value();
38 switch (ArchOpcodeField::decode(opcode)) { 71 switch (ArchOpcodeField::decode(opcode)) {
39 case kMipsShl: 72 case kMipsShl:
40 case kMipsSar: 73 case kMipsSar:
41 case kMipsShr: 74 case kMipsShr:
42 return is_uint5(value); 75 return is_uint5(value);
43 case kMipsAdd: 76 case kMipsAdd:
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 break; 326 break;
294 case MachineRepresentation::kWord64: // Fall through. 327 case MachineRepresentation::kWord64: // Fall through.
295 case MachineRepresentation::kSimd128: // Fall through. 328 case MachineRepresentation::kSimd128: // Fall through.
296 case MachineRepresentation::kNone: 329 case MachineRepresentation::kNone:
297 UNREACHABLE(); 330 UNREACHABLE();
298 return; 331 return;
299 } 332 }
300 333
301 if (g.CanBeImmediate(index, opcode)) { 334 if (g.CanBeImmediate(index, opcode)) {
302 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), 335 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
303 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); 336 g.UseRegister(base), g.UseImmediate(index),
337 g.UseRegisterOrImmediateZero(value));
304 } else { 338 } else {
305 InstructionOperand addr_reg = g.TempRegister(); 339 InstructionOperand addr_reg = g.TempRegister();
306 Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, 340 Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
307 g.UseRegister(index), g.UseRegister(base)); 341 g.UseRegister(index), g.UseRegister(base));
308 // Emit desired store opcode, using temp addr_reg. 342 // Emit desired store opcode, using temp addr_reg.
309 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), 343 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
310 addr_reg, g.TempImmediate(0), g.UseRegister(value)); 344 addr_reg, g.TempImmediate(0), g.UseRegisterOrImmediateZero(value));
311 } 345 }
312 } 346 }
313 } 347 }
314 348
315 349
316 void InstructionSelector::VisitWord32And(Node* node) { 350 void InstructionSelector::VisitWord32And(Node* node) {
317 MipsOperandGenerator g(this); 351 MipsOperandGenerator g(this);
318 Int32BinopMatcher m(node); 352 Int32BinopMatcher m(node);
319 if (m.left().IsWord32Shr() && CanCover(node, m.left().node()) && 353 if (m.left().IsWord32Shr() && CanCover(node, m.left().node()) &&
320 m.right().HasValue()) { 354 m.right().HasValue()) {
(...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 break; 1259 break;
1226 case MachineRepresentation::kWord64: // Fall through. 1260 case MachineRepresentation::kWord64: // Fall through.
1227 case MachineRepresentation::kSimd128: // Fall through. 1261 case MachineRepresentation::kSimd128: // Fall through.
1228 case MachineRepresentation::kNone: 1262 case MachineRepresentation::kNone:
1229 UNREACHABLE(); 1263 UNREACHABLE();
1230 return; 1264 return;
1231 } 1265 }
1232 1266
1233 if (g.CanBeImmediate(index, opcode)) { 1267 if (g.CanBeImmediate(index, opcode)) {
1234 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), 1268 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
1235 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); 1269 g.UseRegister(base), g.UseImmediate(index),
1270 g.UseRegisterOrImmediateZero(value));
1236 } else { 1271 } else {
1237 InstructionOperand addr_reg = g.TempRegister(); 1272 InstructionOperand addr_reg = g.TempRegister();
1238 Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, 1273 Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
1239 g.UseRegister(index), g.UseRegister(base)); 1274 g.UseRegister(index), g.UseRegister(base));
1240 // Emit desired store opcode, using temp addr_reg. 1275 // Emit desired store opcode, using temp addr_reg.
1241 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), 1276 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
1242 addr_reg, g.TempImmediate(0), g.UseRegister(value)); 1277 addr_reg, g.TempImmediate(0), g.UseRegisterOrImmediateZero(value));
1243 } 1278 }
1244 } 1279 }
1245 1280
1246 void InstructionSelector::VisitCheckedLoad(Node* node) { 1281 void InstructionSelector::VisitCheckedLoad(Node* node) {
1247 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); 1282 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op());
1248 MipsOperandGenerator g(this); 1283 MipsOperandGenerator g(this);
1249 Node* const buffer = node->InputAt(0); 1284 Node* const buffer = node->InputAt(0);
1250 Node* const offset = node->InputAt(1); 1285 Node* const offset = node->InputAt(1);
1251 Node* const length = node->InputAt(2); 1286 Node* const length = node->InputAt(2);
1252 ArchOpcode opcode = kArchNop; 1287 ArchOpcode opcode = kArchNop;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 ? g.UseImmediate(offset) 1359 ? g.UseImmediate(offset)
1325 : g.UseRegister(offset); 1360 : g.UseRegister(offset);
1326 1361
1327 InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode)) 1362 InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
1328 ? g.CanBeImmediate(length, opcode) 1363 ? g.CanBeImmediate(length, opcode)
1329 ? g.UseImmediate(length) 1364 ? g.UseImmediate(length)
1330 : g.UseRegister(length) 1365 : g.UseRegister(length)
1331 : g.UseRegister(length); 1366 : g.UseRegister(length);
1332 1367
1333 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), 1368 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
1334 offset_operand, length_operand, g.UseRegister(value), 1369 offset_operand, length_operand, g.UseRegisterOrImmediateZero(value),
1335 g.UseRegister(buffer)); 1370 g.UseRegister(buffer));
1336 } 1371 }
1337 1372
1338 1373
1339 namespace { 1374 namespace {
1340 // Shared routine for multiple compare operations. 1375 // Shared routine for multiple compare operations.
1341 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, 1376 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
1342 InstructionOperand left, InstructionOperand right, 1377 InstructionOperand left, InstructionOperand right,
1343 FlagsContinuation* cont) { 1378 FlagsContinuation* cont) {
1344 MipsOperandGenerator g(selector); 1379 MipsOperandGenerator g(selector);
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
1795 case MachineRepresentation::kWord32: 1830 case MachineRepresentation::kWord32:
1796 opcode = kAtomicStoreWord32; 1831 opcode = kAtomicStoreWord32;
1797 break; 1832 break;
1798 default: 1833 default:
1799 UNREACHABLE(); 1834 UNREACHABLE();
1800 return; 1835 return;
1801 } 1836 }
1802 1837
1803 if (g.CanBeImmediate(index, opcode)) { 1838 if (g.CanBeImmediate(index, opcode)) {
1804 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), 1839 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
1805 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); 1840 g.UseRegister(base), g.UseImmediate(index),
1841 g.UseRegisterOrImmediateZero(value));
1806 } else { 1842 } else {
1807 InstructionOperand addr_reg = g.TempRegister(); 1843 InstructionOperand addr_reg = g.TempRegister();
1808 Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, 1844 Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
1809 g.UseRegister(index), g.UseRegister(base)); 1845 g.UseRegister(index), g.UseRegister(base));
1810 // Emit desired store opcode, using temp addr_reg. 1846 // Emit desired store opcode, using temp addr_reg.
1811 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), 1847 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
1812 addr_reg, g.TempImmediate(0), g.UseRegister(value)); 1848 addr_reg, g.TempImmediate(0), g.UseRegisterOrImmediateZero(value));
1813 } 1849 }
1814 } 1850 }
1815 1851
1816 // static 1852 // static
1817 MachineOperatorBuilder::Flags 1853 MachineOperatorBuilder::Flags
1818 InstructionSelector::SupportedMachineOperatorFlags() { 1854 InstructionSelector::SupportedMachineOperatorFlags() {
1819 MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags; 1855 MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags;
1820 if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && 1856 if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
1821 IsFp64Mode()) { 1857 IsFp64Mode()) {
1822 flags |= MachineOperatorBuilder::kFloat64RoundDown | 1858 flags |= MachineOperatorBuilder::kFloat64RoundDown |
(...skipping 25 matching lines...) Expand all
1848 DCHECK(IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r1) || 1884 DCHECK(IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r1) ||
1849 IsMipsArchVariant(kMips32r2)); 1885 IsMipsArchVariant(kMips32r2));
1850 return MachineOperatorBuilder::AlignmentRequirements:: 1886 return MachineOperatorBuilder::AlignmentRequirements::
1851 NoUnalignedAccessSupport(); 1887 NoUnalignedAccessSupport();
1852 } 1888 }
1853 } 1889 }
1854 1890
1855 } // namespace compiler 1891 } // namespace compiler
1856 } // namespace internal 1892 } // namespace internal
1857 } // namespace v8 1893 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/mips/code-generator-mips.cc ('k') | src/compiler/mips64/code-generator-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698