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

Side by Side Diff: src/compiler/mips/code-generator-mips.cc

Issue 1242303005: [turbofan]: Elide extra move when accessing stack or frame register (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: src/compiler/code-generator.cc Created 5 years, 5 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
« no previous file with comments | « src/compiler/instruction-selector-impl.h ('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/compiler/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 #include "src/compiler/code-generator-impl.h" 6 #include "src/compiler/code-generator-impl.h"
7 #include "src/compiler/gap-resolver.h" 7 #include "src/compiler/gap-resolver.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/mips/macro-assembler-mips.h" 9 #include "src/mips/macro-assembler-mips.h"
10 #include "src/scopes.h" 10 #include "src/scopes.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 case Constant::kRpoNumber: 73 case Constant::kRpoNumber:
74 UNREACHABLE(); // TODO(titzer): RPO immediates on mips? 74 UNREACHABLE(); // TODO(titzer): RPO immediates on mips?
75 break; 75 break;
76 } 76 }
77 UNREACHABLE(); 77 UNREACHABLE();
78 return Operand(zero_reg); 78 return Operand(zero_reg);
79 } 79 }
80 80
81 Operand InputOperand(size_t index) { 81 Operand InputOperand(size_t index) {
82 InstructionOperand* op = instr_->InputAt(index); 82 InstructionOperand* op = instr_->InputAt(index);
83 if (op->IsRegister()) { 83 if (op->GeneratesRegister()) {
84 return Operand(ToRegister(op)); 84 return Operand(ToRegister(op));
85 } 85 }
86 return InputImmediate(index); 86 return InputImmediate(index);
87 } 87 }
88 88
89 MemOperand MemoryOperand(size_t* first_index) { 89 MemOperand MemoryOperand(size_t* first_index) {
90 const size_t index = *first_index; 90 const size_t index = *first_index;
91 switch (AddressingModeField::decode(instr_->opcode())) { 91 switch (AddressingModeField::decode(instr_->opcode())) {
92 case kMode_None: 92 case kMode_None:
93 break; 93 break;
94 case kMode_MRI: 94 case kMode_MRI:
95 *first_index += 2; 95 *first_index += 2;
96 return MemOperand(InputRegister(index + 0), InputInt32(index + 1)); 96 return MemOperand(InputRegister(index + 0), InputInt32(index + 1));
97 case kMode_MRR: 97 case kMode_MRR:
98 // TODO(plind): r6 address mode, to be implemented ... 98 // TODO(plind): r6 address mode, to be implemented ...
99 UNREACHABLE(); 99 UNREACHABLE();
100 } 100 }
101 UNREACHABLE(); 101 UNREACHABLE();
102 return MemOperand(no_reg); 102 return MemOperand(no_reg);
103 } 103 }
104 104
105 MemOperand MemoryOperand(size_t index = 0) { return MemoryOperand(&index); } 105 MemOperand MemoryOperand(size_t index = 0) { return MemoryOperand(&index); }
106 106
107 MemOperand ToMemOperand(InstructionOperand* op) const { 107 MemOperand ToMemOperand(InstructionOperand* op) const {
108 DCHECK(op != NULL); 108 DCHECK(op != NULL);
109 DCHECK(!op->IsRegister()); 109 DCHECK(!op->GeneratesRegister());
110 DCHECK(!op->IsDoubleRegister()); 110 DCHECK(!op->IsDoubleRegister());
111 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); 111 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
112 // The linkage computes where all spill slots are located. 112 // The linkage computes where all spill slots are located.
113 FrameOffset offset = linkage()->GetFrameOffset( 113 FrameOffset offset = linkage()->GetFrameOffset(
114 AllocatedOperand::cast(op)->index(), frame(), 0); 114 AllocatedOperand::cast(op)->index(), frame(), 0);
115 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); 115 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
116 } 116 }
117 }; 117 };
118 118
119 119
120 static inline bool HasRegisterInput(Instruction* instr, size_t index) { 120 static inline bool HasRegisterInput(Instruction* instr, size_t index) {
121 return instr->InputAt(index)->IsRegister(); 121 return instr->InputAt(index)->GeneratesRegister();
122 } 122 }
123 123
124 124
125 namespace { 125 namespace {
126 126
127 class OutOfLineLoadSingle final : public OutOfLineCode { 127 class OutOfLineLoadSingle final : public OutOfLineCode {
128 public: 128 public:
129 OutOfLineLoadSingle(CodeGenerator* gen, FloatRegister result) 129 OutOfLineLoadSingle(CodeGenerator* gen, FloatRegister result)
130 : OutOfLineCode(gen), result_(result) {} 130 : OutOfLineCode(gen), result_(result) {}
131 131
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 return kNoFPUCondition; 296 return kNoFPUCondition;
297 } 297 }
298 298
299 } // namespace 299 } // namespace
300 300
301 301
302 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ 302 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \
303 do { \ 303 do { \
304 auto result = i.Output##width##Register(); \ 304 auto result = i.Output##width##Register(); \
305 auto ool = new (zone()) OutOfLineLoad##width(this, result); \ 305 auto ool = new (zone()) OutOfLineLoad##width(this, result); \
306 if (instr->InputAt(0)->IsRegister()) { \ 306 if (instr->InputAt(0)->GeneratesRegister()) { \
307 auto offset = i.InputRegister(0); \ 307 auto offset = i.InputRegister(0); \
308 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ 308 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
309 __ addu(at, i.InputRegister(2), offset); \ 309 __ addu(at, i.InputRegister(2), offset); \
310 __ asm_instr(result, MemOperand(at, 0)); \ 310 __ asm_instr(result, MemOperand(at, 0)); \
311 } else { \ 311 } else { \
312 auto offset = i.InputOperand(0).immediate(); \ 312 auto offset = i.InputOperand(0).immediate(); \
313 __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \ 313 __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \
314 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \ 314 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \
315 } \ 315 } \
316 __ bind(ool->exit()); \ 316 __ bind(ool->exit()); \
317 } while (0) 317 } while (0)
318 318
319 319
320 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ 320 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \
321 do { \ 321 do { \
322 auto result = i.OutputRegister(); \ 322 auto result = i.OutputRegister(); \
323 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \ 323 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \
324 if (instr->InputAt(0)->IsRegister()) { \ 324 if (instr->InputAt(0)->GeneratesRegister()) { \
325 auto offset = i.InputRegister(0); \ 325 auto offset = i.InputRegister(0); \
326 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \ 326 __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
327 __ addu(at, i.InputRegister(2), offset); \ 327 __ addu(at, i.InputRegister(2), offset); \
328 __ asm_instr(result, MemOperand(at, 0)); \ 328 __ asm_instr(result, MemOperand(at, 0)); \
329 } else { \ 329 } else { \
330 auto offset = i.InputOperand(0).immediate(); \ 330 auto offset = i.InputOperand(0).immediate(); \
331 __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \ 331 __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \
332 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \ 332 __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \
333 } \ 333 } \
334 __ bind(ool->exit()); \ 334 __ bind(ool->exit()); \
335 } while (0) 335 } while (0)
336 336
337 337
338 #define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \ 338 #define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \
339 do { \ 339 do { \
340 Label done; \ 340 Label done; \
341 if (instr->InputAt(0)->IsRegister()) { \ 341 if (instr->InputAt(0)->GeneratesRegister()) { \
342 auto offset = i.InputRegister(0); \ 342 auto offset = i.InputRegister(0); \
343 auto value = i.Input##width##Register(2); \ 343 auto value = i.Input##width##Register(2); \
344 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ 344 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
345 __ addu(at, i.InputRegister(3), offset); \ 345 __ addu(at, i.InputRegister(3), offset); \
346 __ asm_instr(value, MemOperand(at, 0)); \ 346 __ asm_instr(value, MemOperand(at, 0)); \
347 } else { \ 347 } else { \
348 auto offset = i.InputOperand(0).immediate(); \ 348 auto offset = i.InputOperand(0).immediate(); \
349 auto value = i.Input##width##Register(2); \ 349 auto value = i.Input##width##Register(2); \
350 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ 350 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \
351 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ 351 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \
352 } \ 352 } \
353 __ bind(&done); \ 353 __ bind(&done); \
354 } while (0) 354 } while (0)
355 355
356 356
357 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ 357 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
358 do { \ 358 do { \
359 Label done; \ 359 Label done; \
360 if (instr->InputAt(0)->IsRegister()) { \ 360 if (instr->InputAt(0)->GeneratesRegister()) { \
361 auto offset = i.InputRegister(0); \ 361 auto offset = i.InputRegister(0); \
362 auto value = i.InputRegister(2); \ 362 auto value = i.InputRegister(2); \
363 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \ 363 __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
364 __ addu(at, i.InputRegister(3), offset); \ 364 __ addu(at, i.InputRegister(3), offset); \
365 __ asm_instr(value, MemOperand(at, 0)); \ 365 __ asm_instr(value, MemOperand(at, 0)); \
366 } else { \ 366 } else { \
367 auto offset = i.InputOperand(0).immediate(); \ 367 auto offset = i.InputOperand(0).immediate(); \
368 auto value = i.InputRegister(2); \ 368 auto value = i.InputRegister(2); \
369 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \ 369 __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \
370 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \ 370 __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 case kMipsOr: 546 case kMipsOr:
547 __ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); 547 __ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
548 break; 548 break;
549 case kMipsXor: 549 case kMipsXor:
550 __ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); 550 __ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
551 break; 551 break;
552 case kMipsClz: 552 case kMipsClz:
553 __ Clz(i.OutputRegister(), i.InputRegister(0)); 553 __ Clz(i.OutputRegister(), i.InputRegister(0));
554 break; 554 break;
555 case kMipsShl: 555 case kMipsShl:
556 if (instr->InputAt(1)->IsRegister()) { 556 if (instr->InputAt(1)->GeneratesRegister()) {
557 __ sllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); 557 __ sllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
558 } else { 558 } else {
559 int32_t imm = i.InputOperand(1).immediate(); 559 int32_t imm = i.InputOperand(1).immediate();
560 __ sll(i.OutputRegister(), i.InputRegister(0), imm); 560 __ sll(i.OutputRegister(), i.InputRegister(0), imm);
561 } 561 }
562 break; 562 break;
563 case kMipsShr: 563 case kMipsShr:
564 if (instr->InputAt(1)->IsRegister()) { 564 if (instr->InputAt(1)->GeneratesRegister()) {
565 __ srlv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); 565 __ srlv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
566 } else { 566 } else {
567 int32_t imm = i.InputOperand(1).immediate(); 567 int32_t imm = i.InputOperand(1).immediate();
568 __ srl(i.OutputRegister(), i.InputRegister(0), imm); 568 __ srl(i.OutputRegister(), i.InputRegister(0), imm);
569 } 569 }
570 break; 570 break;
571 case kMipsSar: 571 case kMipsSar:
572 if (instr->InputAt(1)->IsRegister()) { 572 if (instr->InputAt(1)->GeneratesRegister()) {
573 __ srav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); 573 __ srav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
574 } else { 574 } else {
575 int32_t imm = i.InputOperand(1).immediate(); 575 int32_t imm = i.InputOperand(1).immediate();
576 __ sra(i.OutputRegister(), i.InputRegister(0), imm); 576 __ sra(i.OutputRegister(), i.InputRegister(0), imm);
577 } 577 }
578 break; 578 break;
579 case kMipsRor: 579 case kMipsRor:
580 __ Ror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1)); 580 __ Ror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
581 break; 581 break;
582 case kMipsTst: 582 case kMipsTst:
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
1167 __ Ret(); 1167 __ Ret();
1168 } 1168 }
1169 } 1169 }
1170 1170
1171 1171
1172 void CodeGenerator::AssembleMove(InstructionOperand* source, 1172 void CodeGenerator::AssembleMove(InstructionOperand* source,
1173 InstructionOperand* destination) { 1173 InstructionOperand* destination) {
1174 MipsOperandConverter g(this, NULL); 1174 MipsOperandConverter g(this, NULL);
1175 // Dispatch on the source and destination operand kinds. Not all 1175 // Dispatch on the source and destination operand kinds. Not all
1176 // combinations are possible. 1176 // combinations are possible.
1177 if (source->IsRegister()) { 1177 if (source->GeneratesRegister()) {
1178 DCHECK(destination->IsRegister() || destination->IsStackSlot()); 1178 DCHECK(destination->GeneratesRegister() || destination->IsStackSlot());
1179 Register src = g.ToRegister(source); 1179 Register src = g.ToRegister(source);
1180 if (destination->IsRegister()) { 1180 if (destination->GeneratesRegister()) {
1181 __ mov(g.ToRegister(destination), src); 1181 __ mov(g.ToRegister(destination), src);
1182 } else { 1182 } else {
1183 __ sw(src, g.ToMemOperand(destination)); 1183 __ sw(src, g.ToMemOperand(destination));
1184 } 1184 }
1185 } else if (source->IsStackSlot()) { 1185 } else if (source->IsStackSlot()) {
1186 DCHECK(destination->IsRegister() || destination->IsStackSlot()); 1186 DCHECK(destination->GeneratesRegister() || destination->IsStackSlot());
1187 MemOperand src = g.ToMemOperand(source); 1187 MemOperand src = g.ToMemOperand(source);
1188 if (destination->IsRegister()) { 1188 if (destination->GeneratesRegister()) {
1189 __ lw(g.ToRegister(destination), src); 1189 __ lw(g.ToRegister(destination), src);
1190 } else { 1190 } else {
1191 Register temp = kScratchReg; 1191 Register temp = kScratchReg;
1192 __ lw(temp, src); 1192 __ lw(temp, src);
1193 __ sw(temp, g.ToMemOperand(destination)); 1193 __ sw(temp, g.ToMemOperand(destination));
1194 } 1194 }
1195 } else if (source->IsConstant()) { 1195 } else if (source->IsConstant()) {
1196 Constant src = g.ToConstant(source); 1196 Constant src = g.ToConstant(source);
1197 if (destination->IsRegister() || destination->IsStackSlot()) { 1197 if (destination->GeneratesRegister() || destination->IsStackSlot()) {
1198 Register dst = 1198 Register dst = destination->GeneratesRegister()
1199 destination->IsRegister() ? g.ToRegister(destination) : kScratchReg; 1199 ? g.ToRegister(destination)
1200 : kScratchReg;
1200 switch (src.type()) { 1201 switch (src.type()) {
1201 case Constant::kInt32: 1202 case Constant::kInt32:
1202 __ li(dst, Operand(src.ToInt32())); 1203 __ li(dst, Operand(src.ToInt32()));
1203 break; 1204 break;
1204 case Constant::kFloat32: 1205 case Constant::kFloat32:
1205 __ li(dst, isolate()->factory()->NewNumber(src.ToFloat32(), TENURED)); 1206 __ li(dst, isolate()->factory()->NewNumber(src.ToFloat32(), TENURED));
1206 break; 1207 break;
1207 case Constant::kInt64: 1208 case Constant::kInt64:
1208 UNREACHABLE(); 1209 UNREACHABLE();
1209 break; 1210 break;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 UNREACHABLE(); 1274 UNREACHABLE();
1274 } 1275 }
1275 } 1276 }
1276 1277
1277 1278
1278 void CodeGenerator::AssembleSwap(InstructionOperand* source, 1279 void CodeGenerator::AssembleSwap(InstructionOperand* source,
1279 InstructionOperand* destination) { 1280 InstructionOperand* destination) {
1280 MipsOperandConverter g(this, NULL); 1281 MipsOperandConverter g(this, NULL);
1281 // Dispatch on the source and destination operand kinds. Not all 1282 // Dispatch on the source and destination operand kinds. Not all
1282 // combinations are possible. 1283 // combinations are possible.
1283 if (source->IsRegister()) { 1284 if (source->GeneratesRegister()) {
1284 // Register-register. 1285 // Register-register.
1285 Register temp = kScratchReg; 1286 Register temp = kScratchReg;
1286 Register src = g.ToRegister(source); 1287 Register src = g.ToRegister(source);
1287 if (destination->IsRegister()) { 1288 if (destination->GeneratesRegister()) {
1288 Register dst = g.ToRegister(destination); 1289 Register dst = g.ToRegister(destination);
1289 __ Move(temp, src); 1290 __ Move(temp, src);
1290 __ Move(src, dst); 1291 __ Move(src, dst);
1291 __ Move(dst, temp); 1292 __ Move(dst, temp);
1292 } else { 1293 } else {
1293 DCHECK(destination->IsStackSlot()); 1294 DCHECK(destination->IsStackSlot());
1294 MemOperand dst = g.ToMemOperand(destination); 1295 MemOperand dst = g.ToMemOperand(destination);
1295 __ mov(temp, src); 1296 __ mov(temp, src);
1296 __ lw(src, dst); 1297 __ lw(src, dst);
1297 __ sw(temp, dst); 1298 __ sw(temp, dst);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 } 1374 }
1374 } 1375 }
1375 } 1376 }
1376 } 1377 }
1377 1378
1378 #undef __ 1379 #undef __
1379 1380
1380 } // namespace compiler 1381 } // namespace compiler
1381 } // namespace internal 1382 } // namespace internal
1382 } // namespace v8 1383 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/instruction-selector-impl.h ('k') | src/compiler/mips64/code-generator-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698