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

Side by Side Diff: src/compiler/x64/code-generator-x64.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
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 6
7 #include "src/compiler/code-generator-impl.h" 7 #include "src/compiler/code-generator-impl.h"
8 #include "src/compiler/gap-resolver.h" 8 #include "src/compiler/gap-resolver.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/scopes.h" 10 #include "src/scopes.h"
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 } 186 }
187 187
188 private: 188 private:
189 Register const result_; 189 Register const result_;
190 XMMRegister const input_; 190 XMMRegister const input_;
191 }; 191 };
192 192
193 } // namespace 193 } // namespace
194 194
195 195
196 #define ASSEMBLE_UNOP(asm_instr) \ 196 #define ASSEMBLE_UNOP(asm_instr) \
197 do { \ 197 do { \
198 if (instr->Output()->IsRegister()) { \ 198 if (instr->Output()->GeneratesRegister()) { \
199 __ asm_instr(i.OutputRegister()); \ 199 __ asm_instr(i.OutputRegister()); \
200 } else { \ 200 } else { \
201 __ asm_instr(i.OutputOperand()); \ 201 __ asm_instr(i.OutputOperand()); \
202 } \ 202 } \
203 } while (0) 203 } while (0)
204 204
205 205
206 #define ASSEMBLE_BINOP(asm_instr) \ 206 #define ASSEMBLE_BINOP(asm_instr) \
207 do { \ 207 do { \
208 if (HasImmediateInput(instr, 1)) { \ 208 if (HasImmediateInput(instr, 1)) { \
209 if (instr->InputAt(0)->IsRegister()) { \ 209 if (instr->InputAt(0)->GeneratesRegister()) { \
210 __ asm_instr(i.InputRegister(0), i.InputImmediate(1)); \ 210 __ asm_instr(i.InputRegister(0), i.InputImmediate(1)); \
211 } else { \ 211 } else { \
212 __ asm_instr(i.InputOperand(0), i.InputImmediate(1)); \ 212 __ asm_instr(i.InputOperand(0), i.InputImmediate(1)); \
213 } \ 213 } \
214 } else { \ 214 } else { \
215 if (instr->InputAt(1)->IsRegister()) { \ 215 if (instr->InputAt(1)->GeneratesRegister()) { \
216 __ asm_instr(i.InputRegister(0), i.InputRegister(1)); \ 216 __ asm_instr(i.InputRegister(0), i.InputRegister(1)); \
217 } else { \ 217 } else { \
218 __ asm_instr(i.InputRegister(0), i.InputOperand(1)); \ 218 __ asm_instr(i.InputRegister(0), i.InputOperand(1)); \
219 } \ 219 } \
220 } \ 220 } \
221 } while (0) 221 } while (0)
222 222
223 223
224 #define ASSEMBLE_MULT(asm_instr) \ 224 #define ASSEMBLE_MULT(asm_instr) \
225 do { \ 225 do { \
226 if (HasImmediateInput(instr, 1)) { \ 226 if (HasImmediateInput(instr, 1)) { \
227 if (instr->InputAt(0)->IsRegister()) { \ 227 if (instr->InputAt(0)->GeneratesRegister()) { \
228 __ asm_instr(i.OutputRegister(), i.InputRegister(0), \ 228 __ asm_instr(i.OutputRegister(), i.InputRegister(0), \
229 i.InputImmediate(1)); \ 229 i.InputImmediate(1)); \
230 } else { \ 230 } else { \
231 __ asm_instr(i.OutputRegister(), i.InputOperand(0), \ 231 __ asm_instr(i.OutputRegister(), i.InputOperand(0), \
232 i.InputImmediate(1)); \ 232 i.InputImmediate(1)); \
233 } \ 233 } \
234 } else { \ 234 } else { \
235 if (instr->InputAt(1)->IsRegister()) { \ 235 if (instr->InputAt(1)->GeneratesRegister()) { \
236 __ asm_instr(i.OutputRegister(), i.InputRegister(1)); \ 236 __ asm_instr(i.OutputRegister(), i.InputRegister(1)); \
237 } else { \ 237 } else { \
238 __ asm_instr(i.OutputRegister(), i.InputOperand(1)); \ 238 __ asm_instr(i.OutputRegister(), i.InputOperand(1)); \
239 } \ 239 } \
240 } \ 240 } \
241 } while (0) 241 } while (0)
242 242
243 243
244 #define ASSEMBLE_SHIFT(asm_instr, width) \ 244 #define ASSEMBLE_SHIFT(asm_instr, width) \
245 do { \ 245 do { \
246 if (HasImmediateInput(instr, 1)) { \ 246 if (HasImmediateInput(instr, 1)) { \
247 if (instr->Output()->IsRegister()) { \ 247 if (instr->Output()->GeneratesRegister()) { \
248 __ asm_instr(i.OutputRegister(), Immediate(i.InputInt##width(1))); \ 248 __ asm_instr(i.OutputRegister(), Immediate(i.InputInt##width(1))); \
249 } else { \ 249 } else { \
250 __ asm_instr(i.OutputOperand(), Immediate(i.InputInt##width(1))); \ 250 __ asm_instr(i.OutputOperand(), Immediate(i.InputInt##width(1))); \
251 } \ 251 } \
252 } else { \ 252 } else { \
253 if (instr->Output()->IsRegister()) { \ 253 if (instr->Output()->GeneratesRegister()) { \
254 __ asm_instr##_cl(i.OutputRegister()); \ 254 __ asm_instr##_cl(i.OutputRegister()); \
255 } else { \ 255 } else { \
256 __ asm_instr##_cl(i.OutputOperand()); \ 256 __ asm_instr##_cl(i.OutputOperand()); \
257 } \ 257 } \
258 } \ 258 } \
259 } while (0) 259 } while (0)
260 260
261 261
262 #define ASSEMBLE_MOVX(asm_instr) \ 262 #define ASSEMBLE_MOVX(asm_instr) \
263 do { \ 263 do { \
264 if (instr->addressing_mode() != kMode_None) { \ 264 if (instr->addressing_mode() != kMode_None) { \
265 __ asm_instr(i.OutputRegister(), i.MemoryOperand()); \ 265 __ asm_instr(i.OutputRegister(), i.MemoryOperand()); \
266 } else if (instr->InputAt(0)->IsRegister()) { \ 266 } else if (instr->InputAt(0)->GeneratesRegister()) { \
267 __ asm_instr(i.OutputRegister(), i.InputRegister(0)); \ 267 __ asm_instr(i.OutputRegister(), i.InputRegister(0)); \
268 } else { \ 268 } else { \
269 __ asm_instr(i.OutputRegister(), i.InputOperand(0)); \ 269 __ asm_instr(i.OutputRegister(), i.InputOperand(0)); \
270 } \ 270 } \
271 } while (0) 271 } while (0)
272 272
273 273
274 #define ASSEMBLE_SSE_BINOP(asm_instr) \ 274 #define ASSEMBLE_SSE_BINOP(asm_instr) \
275 do { \ 275 do { \
276 if (instr->InputAt(1)->IsDoubleRegister()) { \ 276 if (instr->InputAt(1)->IsDoubleRegister()) { \
(...skipping 27 matching lines...) Expand all
304 } while (0) 304 } while (0)
305 305
306 306
307 #define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \ 307 #define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \
308 do { \ 308 do { \
309 auto result = i.OutputDoubleRegister(); \ 309 auto result = i.OutputDoubleRegister(); \
310 auto buffer = i.InputRegister(0); \ 310 auto buffer = i.InputRegister(0); \
311 auto index1 = i.InputRegister(1); \ 311 auto index1 = i.InputRegister(1); \
312 auto index2 = i.InputInt32(2); \ 312 auto index2 = i.InputInt32(2); \
313 OutOfLineCode* ool; \ 313 OutOfLineCode* ool; \
314 if (instr->InputAt(3)->IsRegister()) { \ 314 if (instr->InputAt(3)->GeneratesRegister()) { \
315 auto length = i.InputRegister(3); \ 315 auto length = i.InputRegister(3); \
316 DCHECK_EQ(0, index2); \ 316 DCHECK_EQ(0, index2); \
317 __ cmpl(index1, length); \ 317 __ cmpl(index1, length); \
318 ool = new (zone()) OutOfLineLoadNaN(this, result); \ 318 ool = new (zone()) OutOfLineLoadNaN(this, result); \
319 } else { \ 319 } else { \
320 auto length = i.InputInt32(3); \ 320 auto length = i.InputInt32(3); \
321 DCHECK_LE(index2, length); \ 321 DCHECK_LE(index2, length); \
322 __ cmpq(index1, Immediate(length - index2)); \ 322 __ cmpq(index1, Immediate(length - index2)); \
323 class OutOfLineLoadFloat final : public OutOfLineCode { \ 323 class OutOfLineLoadFloat final : public OutOfLineCode { \
324 public: \ 324 public: \
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 } while (false) 357 } while (false)
358 358
359 359
360 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ 360 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \
361 do { \ 361 do { \
362 auto result = i.OutputRegister(); \ 362 auto result = i.OutputRegister(); \
363 auto buffer = i.InputRegister(0); \ 363 auto buffer = i.InputRegister(0); \
364 auto index1 = i.InputRegister(1); \ 364 auto index1 = i.InputRegister(1); \
365 auto index2 = i.InputInt32(2); \ 365 auto index2 = i.InputInt32(2); \
366 OutOfLineCode* ool; \ 366 OutOfLineCode* ool; \
367 if (instr->InputAt(3)->IsRegister()) { \ 367 if (instr->InputAt(3)->GeneratesRegister()) { \
368 auto length = i.InputRegister(3); \ 368 auto length = i.InputRegister(3); \
369 DCHECK_EQ(0, index2); \ 369 DCHECK_EQ(0, index2); \
370 __ cmpl(index1, length); \ 370 __ cmpl(index1, length); \
371 ool = new (zone()) OutOfLineLoadZero(this, result); \ 371 ool = new (zone()) OutOfLineLoadZero(this, result); \
372 } else { \ 372 } else { \
373 auto length = i.InputInt32(3); \ 373 auto length = i.InputInt32(3); \
374 DCHECK_LE(index2, length); \ 374 DCHECK_LE(index2, length); \
375 __ cmpq(index1, Immediate(length - index2)); \ 375 __ cmpq(index1, Immediate(length - index2)); \
376 class OutOfLineLoadInteger final : public OutOfLineCode { \ 376 class OutOfLineLoadInteger final : public OutOfLineCode { \
377 public: \ 377 public: \
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 __ bind(ool->exit()); \ 412 __ bind(ool->exit()); \
413 } while (false) 413 } while (false)
414 414
415 415
416 #define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \ 416 #define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \
417 do { \ 417 do { \
418 auto buffer = i.InputRegister(0); \ 418 auto buffer = i.InputRegister(0); \
419 auto index1 = i.InputRegister(1); \ 419 auto index1 = i.InputRegister(1); \
420 auto index2 = i.InputInt32(2); \ 420 auto index2 = i.InputInt32(2); \
421 auto value = i.InputDoubleRegister(4); \ 421 auto value = i.InputDoubleRegister(4); \
422 if (instr->InputAt(3)->IsRegister()) { \ 422 if (instr->InputAt(3)->GeneratesRegister()) { \
423 auto length = i.InputRegister(3); \ 423 auto length = i.InputRegister(3); \
424 DCHECK_EQ(0, index2); \ 424 DCHECK_EQ(0, index2); \
425 Label done; \ 425 Label done; \
426 __ cmpl(index1, length); \ 426 __ cmpl(index1, length); \
427 __ j(above_equal, &done, Label::kNear); \ 427 __ j(above_equal, &done, Label::kNear); \
428 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ 428 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \
429 __ bind(&done); \ 429 __ bind(&done); \
430 } else { \ 430 } else { \
431 auto length = i.InputInt32(3); \ 431 auto length = i.InputInt32(3); \
432 DCHECK_LE(index2, length); \ 432 DCHECK_LE(index2, length); \
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 __ bind(ool->exit()); \ 465 __ bind(ool->exit()); \
466 } \ 466 } \
467 } while (false) 467 } while (false)
468 468
469 469
470 #define ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Value) \ 470 #define ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Value) \
471 do { \ 471 do { \
472 auto buffer = i.InputRegister(0); \ 472 auto buffer = i.InputRegister(0); \
473 auto index1 = i.InputRegister(1); \ 473 auto index1 = i.InputRegister(1); \
474 auto index2 = i.InputInt32(2); \ 474 auto index2 = i.InputInt32(2); \
475 if (instr->InputAt(3)->IsRegister()) { \ 475 if (instr->InputAt(3)->GeneratesRegister()) { \
476 auto length = i.InputRegister(3); \ 476 auto length = i.InputRegister(3); \
477 DCHECK_EQ(0, index2); \ 477 DCHECK_EQ(0, index2); \
478 Label done; \ 478 Label done; \
479 __ cmpl(index1, length); \ 479 __ cmpl(index1, length); \
480 __ j(above_equal, &done, Label::kNear); \ 480 __ j(above_equal, &done, Label::kNear); \
481 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ 481 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \
482 __ bind(&done); \ 482 __ bind(&done); \
483 } else { \ 483 } else { \
484 auto length = i.InputInt32(3); \ 484 auto length = i.InputInt32(3); \
485 DCHECK_LE(index2, length); \ 485 DCHECK_LE(index2, length); \
(...skipping 29 matching lines...) Expand all
515 OutOfLineStoreInteger(this, buffer, index1, index2, length, value); \ 515 OutOfLineStoreInteger(this, buffer, index1, index2, length, value); \
516 __ j(above_equal, ool->entry()); \ 516 __ j(above_equal, ool->entry()); \
517 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ 517 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \
518 __ bind(ool->exit()); \ 518 __ bind(ool->exit()); \
519 } \ 519 } \
520 } while (false) 520 } while (false)
521 521
522 522
523 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ 523 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
524 do { \ 524 do { \
525 if (instr->InputAt(4)->IsRegister()) { \ 525 if (instr->InputAt(4)->GeneratesRegister()) { \
526 Register value = i.InputRegister(4); \ 526 Register value = i.InputRegister(4); \
527 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register); \ 527 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register); \
528 } else { \ 528 } else { \
529 Immediate value = i.InputImmediate(4); \ 529 Immediate value = i.InputImmediate(4); \
530 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \ 530 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \
531 } \ 531 } \
532 } while (false) 532 } while (false)
533 533
534 534
535 void CodeGenerator::AssembleDeconstructActivationRecord() { 535 void CodeGenerator::AssembleDeconstructActivationRecord() {
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 case kX64Test: 678 case kX64Test:
679 ASSEMBLE_BINOP(testq); 679 ASSEMBLE_BINOP(testq);
680 break; 680 break;
681 case kX64Imul32: 681 case kX64Imul32:
682 ASSEMBLE_MULT(imull); 682 ASSEMBLE_MULT(imull);
683 break; 683 break;
684 case kX64Imul: 684 case kX64Imul:
685 ASSEMBLE_MULT(imulq); 685 ASSEMBLE_MULT(imulq);
686 break; 686 break;
687 case kX64ImulHigh32: 687 case kX64ImulHigh32:
688 if (instr->InputAt(1)->IsRegister()) { 688 if (instr->InputAt(1)->GeneratesRegister()) {
689 __ imull(i.InputRegister(1)); 689 __ imull(i.InputRegister(1));
690 } else { 690 } else {
691 __ imull(i.InputOperand(1)); 691 __ imull(i.InputOperand(1));
692 } 692 }
693 break; 693 break;
694 case kX64UmulHigh32: 694 case kX64UmulHigh32:
695 if (instr->InputAt(1)->IsRegister()) { 695 if (instr->InputAt(1)->GeneratesRegister()) {
696 __ mull(i.InputRegister(1)); 696 __ mull(i.InputRegister(1));
697 } else { 697 } else {
698 __ mull(i.InputOperand(1)); 698 __ mull(i.InputOperand(1));
699 } 699 }
700 break; 700 break;
701 case kX64Idiv32: 701 case kX64Idiv32:
702 __ cdq(); 702 __ cdq();
703 __ idivl(i.InputRegister(1)); 703 __ idivl(i.InputRegister(1));
704 break; 704 break;
705 case kX64Idiv: 705 case kX64Idiv:
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 case kX64Sar: 756 case kX64Sar:
757 ASSEMBLE_SHIFT(sarq, 6); 757 ASSEMBLE_SHIFT(sarq, 6);
758 break; 758 break;
759 case kX64Ror32: 759 case kX64Ror32:
760 ASSEMBLE_SHIFT(rorl, 5); 760 ASSEMBLE_SHIFT(rorl, 5);
761 break; 761 break;
762 case kX64Ror: 762 case kX64Ror:
763 ASSEMBLE_SHIFT(rorq, 6); 763 ASSEMBLE_SHIFT(rorq, 6);
764 break; 764 break;
765 case kX64Lzcnt32: 765 case kX64Lzcnt32:
766 if (instr->InputAt(0)->IsRegister()) { 766 if (instr->InputAt(0)->GeneratesRegister()) {
767 __ Lzcntl(i.OutputRegister(), i.InputRegister(0)); 767 __ Lzcntl(i.OutputRegister(), i.InputRegister(0));
768 } else { 768 } else {
769 __ Lzcntl(i.OutputRegister(), i.InputOperand(0)); 769 __ Lzcntl(i.OutputRegister(), i.InputOperand(0));
770 } 770 }
771 break; 771 break;
772 case kSSEFloat32Cmp: 772 case kSSEFloat32Cmp:
773 ASSEMBLE_SSE_BINOP(ucomiss); 773 ASSEMBLE_SSE_BINOP(ucomiss);
774 break; 774 break;
775 case kSSEFloat32Add: 775 case kSSEFloat32Add:
776 ASSEMBLE_SSE_BINOP(addss); 776 ASSEMBLE_SSE_BINOP(addss);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 case kSSEFloat64ToUint32: { 906 case kSSEFloat64ToUint32: {
907 if (instr->InputAt(0)->IsDoubleRegister()) { 907 if (instr->InputAt(0)->IsDoubleRegister()) {
908 __ cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0)); 908 __ cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0));
909 } else { 909 } else {
910 __ cvttsd2siq(i.OutputRegister(), i.InputOperand(0)); 910 __ cvttsd2siq(i.OutputRegister(), i.InputOperand(0));
911 } 911 }
912 __ AssertZeroExtended(i.OutputRegister()); 912 __ AssertZeroExtended(i.OutputRegister());
913 break; 913 break;
914 } 914 }
915 case kSSEInt32ToFloat64: 915 case kSSEInt32ToFloat64:
916 if (instr->InputAt(0)->IsRegister()) { 916 if (instr->InputAt(0)->GeneratesRegister()) {
917 __ cvtlsi2sd(i.OutputDoubleRegister(), i.InputRegister(0)); 917 __ cvtlsi2sd(i.OutputDoubleRegister(), i.InputRegister(0));
918 } else { 918 } else {
919 __ cvtlsi2sd(i.OutputDoubleRegister(), i.InputOperand(0)); 919 __ cvtlsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
920 } 920 }
921 break; 921 break;
922 case kSSEUint32ToFloat64: 922 case kSSEUint32ToFloat64:
923 if (instr->InputAt(0)->IsRegister()) { 923 if (instr->InputAt(0)->GeneratesRegister()) {
924 __ movl(kScratchRegister, i.InputRegister(0)); 924 __ movl(kScratchRegister, i.InputRegister(0));
925 } else { 925 } else {
926 __ movl(kScratchRegister, i.InputOperand(0)); 926 __ movl(kScratchRegister, i.InputOperand(0));
927 } 927 }
928 __ cvtqsi2sd(i.OutputDoubleRegister(), kScratchRegister); 928 __ cvtqsi2sd(i.OutputDoubleRegister(), kScratchRegister);
929 break; 929 break;
930 case kSSEFloat64ExtractLowWord32: 930 case kSSEFloat64ExtractLowWord32:
931 if (instr->InputAt(0)->IsDoubleStackSlot()) { 931 if (instr->InputAt(0)->IsDoubleStackSlot()) {
932 __ movl(i.OutputRegister(), i.InputOperand(0)); 932 __ movl(i.OutputRegister(), i.InputOperand(0));
933 } else { 933 } else {
934 __ movd(i.OutputRegister(), i.InputDoubleRegister(0)); 934 __ movd(i.OutputRegister(), i.InputDoubleRegister(0));
935 } 935 }
936 break; 936 break;
937 case kSSEFloat64ExtractHighWord32: 937 case kSSEFloat64ExtractHighWord32:
938 if (instr->InputAt(0)->IsDoubleStackSlot()) { 938 if (instr->InputAt(0)->IsDoubleStackSlot()) {
939 __ movl(i.OutputRegister(), i.InputOperand(0, kDoubleSize / 2)); 939 __ movl(i.OutputRegister(), i.InputOperand(0, kDoubleSize / 2));
940 } else { 940 } else {
941 __ Pextrd(i.OutputRegister(), i.InputDoubleRegister(0), 1); 941 __ Pextrd(i.OutputRegister(), i.InputDoubleRegister(0), 1);
942 } 942 }
943 break; 943 break;
944 case kSSEFloat64InsertLowWord32: 944 case kSSEFloat64InsertLowWord32:
945 if (instr->InputAt(1)->IsRegister()) { 945 if (instr->InputAt(1)->GeneratesRegister()) {
946 __ Pinsrd(i.OutputDoubleRegister(), i.InputRegister(1), 0); 946 __ Pinsrd(i.OutputDoubleRegister(), i.InputRegister(1), 0);
947 } else { 947 } else {
948 __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 0); 948 __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 0);
949 } 949 }
950 break; 950 break;
951 case kSSEFloat64InsertHighWord32: 951 case kSSEFloat64InsertHighWord32:
952 if (instr->InputAt(1)->IsRegister()) { 952 if (instr->InputAt(1)->GeneratesRegister()) {
953 __ Pinsrd(i.OutputDoubleRegister(), i.InputRegister(1), 1); 953 __ Pinsrd(i.OutputDoubleRegister(), i.InputRegister(1), 1);
954 } else { 954 } else {
955 __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 1); 955 __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 1);
956 } 956 }
957 break; 957 break;
958 case kSSEFloat64LoadLowWord32: 958 case kSSEFloat64LoadLowWord32:
959 if (instr->InputAt(0)->IsRegister()) { 959 if (instr->InputAt(0)->GeneratesRegister()) {
960 __ movd(i.OutputDoubleRegister(), i.InputRegister(0)); 960 __ movd(i.OutputDoubleRegister(), i.InputRegister(0));
961 } else { 961 } else {
962 __ movd(i.OutputDoubleRegister(), i.InputOperand(0)); 962 __ movd(i.OutputDoubleRegister(), i.InputOperand(0));
963 } 963 }
964 break; 964 break;
965 case kAVXFloat32Cmp: { 965 case kAVXFloat32Cmp: {
966 CpuFeatureScope avx_scope(masm(), AVX); 966 CpuFeatureScope avx_scope(masm(), AVX);
967 if (instr->InputAt(1)->IsDoubleRegister()) { 967 if (instr->InputAt(1)->IsDoubleRegister()) {
968 __ vucomiss(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 968 __ vucomiss(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
969 } else { 969 } else {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1110 if (HasImmediateInput(instr, index)) { 1110 if (HasImmediateInput(instr, index)) {
1111 __ movw(operand, Immediate(i.InputInt16(index))); 1111 __ movw(operand, Immediate(i.InputInt16(index)));
1112 } else { 1112 } else {
1113 __ movw(operand, i.InputRegister(index)); 1113 __ movw(operand, i.InputRegister(index));
1114 } 1114 }
1115 break; 1115 break;
1116 } 1116 }
1117 case kX64Movl: 1117 case kX64Movl:
1118 if (instr->HasOutput()) { 1118 if (instr->HasOutput()) {
1119 if (instr->addressing_mode() == kMode_None) { 1119 if (instr->addressing_mode() == kMode_None) {
1120 if (instr->InputAt(0)->IsRegister()) { 1120 if (instr->InputAt(0)->GeneratesRegister()) {
1121 __ movl(i.OutputRegister(), i.InputRegister(0)); 1121 __ movl(i.OutputRegister(), i.InputRegister(0));
1122 } else { 1122 } else {
1123 __ movl(i.OutputRegister(), i.InputOperand(0)); 1123 __ movl(i.OutputRegister(), i.InputOperand(0));
1124 } 1124 }
1125 } else { 1125 } else {
1126 __ movl(i.OutputRegister(), i.MemoryOperand()); 1126 __ movl(i.OutputRegister(), i.MemoryOperand());
1127 } 1127 }
1128 __ AssertZeroExtended(i.OutputRegister()); 1128 __ AssertZeroExtended(i.OutputRegister());
1129 } else { 1129 } else {
1130 size_t index = 0; 1130 size_t index = 0;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 case kX64Dec32: 1210 case kX64Dec32:
1211 __ decl(i.OutputRegister()); 1211 __ decl(i.OutputRegister());
1212 break; 1212 break;
1213 case kX64Inc32: 1213 case kX64Inc32:
1214 __ incl(i.OutputRegister()); 1214 __ incl(i.OutputRegister());
1215 break; 1215 break;
1216 case kX64Push: 1216 case kX64Push:
1217 if (HasImmediateInput(instr, 0)) { 1217 if (HasImmediateInput(instr, 0)) {
1218 __ pushq(i.InputImmediate(0)); 1218 __ pushq(i.InputImmediate(0));
1219 } else { 1219 } else {
1220 if (instr->InputAt(0)->IsRegister()) { 1220 if (instr->InputAt(0)->GeneratesRegister()) {
1221 __ pushq(i.InputRegister(0)); 1221 __ pushq(i.InputRegister(0));
1222 } else { 1222 } else {
1223 __ pushq(i.InputOperand(0)); 1223 __ pushq(i.InputOperand(0));
1224 } 1224 }
1225 } 1225 }
1226 break; 1226 break;
1227 case kX64Poke: { 1227 case kX64Poke: {
1228 int const slot = MiscField::decode(instr->opcode()); 1228 int const slot = MiscField::decode(instr->opcode());
1229 if (HasImmediateInput(instr, 0)) { 1229 if (HasImmediateInput(instr, 0)) {
1230 __ movq(Operand(rsp, slot * kPointerSize), i.InputImmediate(0)); 1230 __ movq(Operand(rsp, slot * kPointerSize), i.InputImmediate(0));
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
1584 __ Ret(); 1584 __ Ret();
1585 } 1585 }
1586 } 1586 }
1587 1587
1588 1588
1589 void CodeGenerator::AssembleMove(InstructionOperand* source, 1589 void CodeGenerator::AssembleMove(InstructionOperand* source,
1590 InstructionOperand* destination) { 1590 InstructionOperand* destination) {
1591 X64OperandConverter g(this, NULL); 1591 X64OperandConverter g(this, NULL);
1592 // Dispatch on the source and destination operand kinds. Not all 1592 // Dispatch on the source and destination operand kinds. Not all
1593 // combinations are possible. 1593 // combinations are possible.
1594 if (source->IsRegister()) { 1594 if (source->GeneratesRegister()) {
1595 DCHECK(destination->IsRegister() || destination->IsStackSlot()); 1595 DCHECK(destination->GeneratesRegister() || destination->IsStackSlot());
1596 Register src = g.ToRegister(source); 1596 Register src = g.ToRegister(source);
1597 if (destination->IsRegister()) { 1597 if (destination->GeneratesRegister()) {
1598 __ movq(g.ToRegister(destination), src); 1598 __ movq(g.ToRegister(destination), src);
1599 } else { 1599 } else {
1600 __ movq(g.ToOperand(destination), src); 1600 __ movq(g.ToOperand(destination), src);
1601 } 1601 }
1602 } else if (source->IsStackSlot()) { 1602 } else if (source->IsStackSlot()) {
1603 DCHECK(destination->IsRegister() || destination->IsStackSlot()); 1603 DCHECK(destination->GeneratesRegister() || destination->IsStackSlot());
1604 Operand src = g.ToOperand(source); 1604 Operand src = g.ToOperand(source);
1605 if (destination->IsRegister()) { 1605 if (destination->GeneratesRegister()) {
1606 Register dst = g.ToRegister(destination); 1606 Register dst = g.ToRegister(destination);
1607 __ movq(dst, src); 1607 __ movq(dst, src);
1608 } else { 1608 } else {
1609 // Spill on demand to use a temporary register for memory-to-memory 1609 // Spill on demand to use a temporary register for memory-to-memory
1610 // moves. 1610 // moves.
1611 Register tmp = kScratchRegister; 1611 Register tmp = kScratchRegister;
1612 Operand dst = g.ToOperand(destination); 1612 Operand dst = g.ToOperand(destination);
1613 __ movq(tmp, src); 1613 __ movq(tmp, src);
1614 __ movq(dst, tmp); 1614 __ movq(dst, tmp);
1615 } 1615 }
1616 } else if (source->IsConstant()) { 1616 } else if (source->IsConstant()) {
1617 ConstantOperand* constant_source = ConstantOperand::cast(source); 1617 ConstantOperand* constant_source = ConstantOperand::cast(source);
1618 Constant src = g.ToConstant(constant_source); 1618 Constant src = g.ToConstant(constant_source);
1619 if (destination->IsRegister() || destination->IsStackSlot()) { 1619 if (destination->GeneratesRegister() || destination->IsStackSlot()) {
1620 Register dst = destination->IsRegister() ? g.ToRegister(destination) 1620 Register dst = destination->GeneratesRegister()
1621 : kScratchRegister; 1621 ? g.ToRegister(destination)
1622 : kScratchRegister;
1622 switch (src.type()) { 1623 switch (src.type()) {
1623 case Constant::kInt32: 1624 case Constant::kInt32:
1624 // TODO(dcarney): don't need scratch in this case. 1625 // TODO(dcarney): don't need scratch in this case.
1625 __ Set(dst, src.ToInt32()); 1626 __ Set(dst, src.ToInt32());
1626 break; 1627 break;
1627 case Constant::kInt64: 1628 case Constant::kInt64:
1628 __ Set(dst, src.ToInt64()); 1629 __ Set(dst, src.ToInt64());
1629 break; 1630 break;
1630 case Constant::kFloat32: 1631 case Constant::kFloat32:
1631 __ Move(dst, 1632 __ Move(dst,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1705 UNREACHABLE(); 1706 UNREACHABLE();
1706 } 1707 }
1707 } 1708 }
1708 1709
1709 1710
1710 void CodeGenerator::AssembleSwap(InstructionOperand* source, 1711 void CodeGenerator::AssembleSwap(InstructionOperand* source,
1711 InstructionOperand* destination) { 1712 InstructionOperand* destination) {
1712 X64OperandConverter g(this, NULL); 1713 X64OperandConverter g(this, NULL);
1713 // Dispatch on the source and destination operand kinds. Not all 1714 // Dispatch on the source and destination operand kinds. Not all
1714 // combinations are possible. 1715 // combinations are possible.
1715 if (source->IsRegister() && destination->IsRegister()) { 1716 if (source->GeneratesRegister() && destination->GeneratesRegister()) {
1716 // Register-register. 1717 // Register-register.
1717 __ xchgq(g.ToRegister(source), g.ToRegister(destination)); 1718 __ xchgq(g.ToRegister(source), g.ToRegister(destination));
1718 } else if (source->IsRegister() && destination->IsStackSlot()) { 1719 } else if (source->GeneratesRegister() && destination->IsStackSlot()) {
1719 Register src = g.ToRegister(source); 1720 Register src = g.ToRegister(source);
1720 Operand dst = g.ToOperand(destination); 1721 Operand dst = g.ToOperand(destination);
1721 __ xchgq(src, dst); 1722 __ xchgq(src, dst);
1722 } else if ((source->IsStackSlot() && destination->IsStackSlot()) || 1723 } else if ((source->IsStackSlot() && destination->IsStackSlot()) ||
1723 (source->IsDoubleStackSlot() && 1724 (source->IsDoubleStackSlot() &&
1724 destination->IsDoubleStackSlot())) { 1725 destination->IsDoubleStackSlot())) {
1725 // Memory-memory. 1726 // Memory-memory.
1726 Register tmp = kScratchRegister; 1727 Register tmp = kScratchRegister;
1727 Operand src = g.ToOperand(source); 1728 Operand src = g.ToOperand(source);
1728 Operand dst = g.ToOperand(destination); 1729 Operand dst = g.ToOperand(destination);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1773 __ Nop(padding_size); 1774 __ Nop(padding_size);
1774 } 1775 }
1775 } 1776 }
1776 } 1777 }
1777 1778
1778 #undef __ 1779 #undef __
1779 1780
1780 } // namespace internal 1781 } // namespace internal
1781 } // namespace compiler 1782 } // namespace compiler
1782 } // namespace v8 1783 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/register-allocator-verifier.cc ('k') | src/compiler/x87/instruction-selector-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698