| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |