| 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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 }; | 136 }; |
| 137 | 137 |
| 138 | 138 |
| 139 namespace { | 139 namespace { |
| 140 | 140 |
| 141 bool HasImmediateInput(Instruction* instr, size_t index) { | 141 bool HasImmediateInput(Instruction* instr, size_t index) { |
| 142 return instr->InputAt(index)->IsImmediate(); | 142 return instr->InputAt(index)->IsImmediate(); |
| 143 } | 143 } |
| 144 | 144 |
| 145 | 145 |
| 146 class OutOfLineLoadZero FINAL : public OutOfLineCode { | 146 class OutOfLineLoadZero final : public OutOfLineCode { |
| 147 public: | 147 public: |
| 148 OutOfLineLoadZero(CodeGenerator* gen, Register result) | 148 OutOfLineLoadZero(CodeGenerator* gen, Register result) |
| 149 : OutOfLineCode(gen), result_(result) {} | 149 : OutOfLineCode(gen), result_(result) {} |
| 150 | 150 |
| 151 void Generate() FINAL { __ xorl(result_, result_); } | 151 void Generate() final { __ xorl(result_, result_); } |
| 152 | 152 |
| 153 private: | 153 private: |
| 154 Register const result_; | 154 Register const result_; |
| 155 }; | 155 }; |
| 156 | 156 |
| 157 | 157 |
| 158 class OutOfLineLoadNaN FINAL : public OutOfLineCode { | 158 class OutOfLineLoadNaN final : public OutOfLineCode { |
| 159 public: | 159 public: |
| 160 OutOfLineLoadNaN(CodeGenerator* gen, XMMRegister result) | 160 OutOfLineLoadNaN(CodeGenerator* gen, XMMRegister result) |
| 161 : OutOfLineCode(gen), result_(result) {} | 161 : OutOfLineCode(gen), result_(result) {} |
| 162 | 162 |
| 163 void Generate() FINAL { __ pcmpeqd(result_, result_); } | 163 void Generate() final { __ pcmpeqd(result_, result_); } |
| 164 | 164 |
| 165 private: | 165 private: |
| 166 XMMRegister const result_; | 166 XMMRegister const result_; |
| 167 }; | 167 }; |
| 168 | 168 |
| 169 | 169 |
| 170 class OutOfLineTruncateDoubleToI FINAL : public OutOfLineCode { | 170 class OutOfLineTruncateDoubleToI final : public OutOfLineCode { |
| 171 public: | 171 public: |
| 172 OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result, | 172 OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result, |
| 173 XMMRegister input) | 173 XMMRegister input) |
| 174 : OutOfLineCode(gen), result_(result), input_(input) {} | 174 : OutOfLineCode(gen), result_(result), input_(input) {} |
| 175 | 175 |
| 176 void Generate() FINAL { | 176 void Generate() final { |
| 177 __ subp(rsp, Immediate(kDoubleSize)); | 177 __ subp(rsp, Immediate(kDoubleSize)); |
| 178 __ movsd(MemOperand(rsp, 0), input_); | 178 __ movsd(MemOperand(rsp, 0), input_); |
| 179 __ SlowTruncateToI(result_, rsp, 0); | 179 __ SlowTruncateToI(result_, rsp, 0); |
| 180 __ addp(rsp, Immediate(kDoubleSize)); | 180 __ addp(rsp, Immediate(kDoubleSize)); |
| 181 } | 181 } |
| 182 | 182 |
| 183 private: | 183 private: |
| 184 Register const result_; | 184 Register const result_; |
| 185 XMMRegister const input_; | 185 XMMRegister const input_; |
| 186 }; | 186 }; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 OutOfLineCode* ool; \ | 308 OutOfLineCode* ool; \ |
| 309 if (instr->InputAt(3)->IsRegister()) { \ | 309 if (instr->InputAt(3)->IsRegister()) { \ |
| 310 auto length = i.InputRegister(3); \ | 310 auto length = i.InputRegister(3); \ |
| 311 DCHECK_EQ(0, index2); \ | 311 DCHECK_EQ(0, index2); \ |
| 312 __ cmpl(index1, length); \ | 312 __ cmpl(index1, length); \ |
| 313 ool = new (zone()) OutOfLineLoadNaN(this, result); \ | 313 ool = new (zone()) OutOfLineLoadNaN(this, result); \ |
| 314 } else { \ | 314 } else { \ |
| 315 auto length = i.InputInt32(3); \ | 315 auto length = i.InputInt32(3); \ |
| 316 DCHECK_LE(index2, length); \ | 316 DCHECK_LE(index2, length); \ |
| 317 __ cmpq(index1, Immediate(length - index2)); \ | 317 __ cmpq(index1, Immediate(length - index2)); \ |
| 318 class OutOfLineLoadFloat FINAL : public OutOfLineCode { \ | 318 class OutOfLineLoadFloat final : public OutOfLineCode { \ |
| 319 public: \ | 319 public: \ |
| 320 OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result, \ | 320 OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result, \ |
| 321 Register buffer, Register index1, int32_t index2, \ | 321 Register buffer, Register index1, int32_t index2, \ |
| 322 int32_t length) \ | 322 int32_t length) \ |
| 323 : OutOfLineCode(gen), \ | 323 : OutOfLineCode(gen), \ |
| 324 result_(result), \ | 324 result_(result), \ |
| 325 buffer_(buffer), \ | 325 buffer_(buffer), \ |
| 326 index1_(index1), \ | 326 index1_(index1), \ |
| 327 index2_(index2), \ | 327 index2_(index2), \ |
| 328 length_(length) {} \ | 328 length_(length) {} \ |
| 329 \ | 329 \ |
| 330 void Generate() FINAL { \ | 330 void Generate() final { \ |
| 331 __ leal(kScratchRegister, Operand(index1_, index2_)); \ | 331 __ leal(kScratchRegister, Operand(index1_, index2_)); \ |
| 332 __ pcmpeqd(result_, result_); \ | 332 __ pcmpeqd(result_, result_); \ |
| 333 __ cmpl(kScratchRegister, Immediate(length_)); \ | 333 __ cmpl(kScratchRegister, Immediate(length_)); \ |
| 334 __ j(above_equal, exit()); \ | 334 __ j(above_equal, exit()); \ |
| 335 __ asm_instr(result_, \ | 335 __ asm_instr(result_, \ |
| 336 Operand(buffer_, kScratchRegister, times_1, 0)); \ | 336 Operand(buffer_, kScratchRegister, times_1, 0)); \ |
| 337 } \ | 337 } \ |
| 338 \ | 338 \ |
| 339 private: \ | 339 private: \ |
| 340 XMMRegister const result_; \ | 340 XMMRegister const result_; \ |
| (...skipping 20 matching lines...) Expand all Loading... |
| 361 OutOfLineCode* ool; \ | 361 OutOfLineCode* ool; \ |
| 362 if (instr->InputAt(3)->IsRegister()) { \ | 362 if (instr->InputAt(3)->IsRegister()) { \ |
| 363 auto length = i.InputRegister(3); \ | 363 auto length = i.InputRegister(3); \ |
| 364 DCHECK_EQ(0, index2); \ | 364 DCHECK_EQ(0, index2); \ |
| 365 __ cmpl(index1, length); \ | 365 __ cmpl(index1, length); \ |
| 366 ool = new (zone()) OutOfLineLoadZero(this, result); \ | 366 ool = new (zone()) OutOfLineLoadZero(this, result); \ |
| 367 } else { \ | 367 } else { \ |
| 368 auto length = i.InputInt32(3); \ | 368 auto length = i.InputInt32(3); \ |
| 369 DCHECK_LE(index2, length); \ | 369 DCHECK_LE(index2, length); \ |
| 370 __ cmpq(index1, Immediate(length - index2)); \ | 370 __ cmpq(index1, Immediate(length - index2)); \ |
| 371 class OutOfLineLoadInteger FINAL : public OutOfLineCode { \ | 371 class OutOfLineLoadInteger final : public OutOfLineCode { \ |
| 372 public: \ | 372 public: \ |
| 373 OutOfLineLoadInteger(CodeGenerator* gen, Register result, \ | 373 OutOfLineLoadInteger(CodeGenerator* gen, Register result, \ |
| 374 Register buffer, Register index1, int32_t index2, \ | 374 Register buffer, Register index1, int32_t index2, \ |
| 375 int32_t length) \ | 375 int32_t length) \ |
| 376 : OutOfLineCode(gen), \ | 376 : OutOfLineCode(gen), \ |
| 377 result_(result), \ | 377 result_(result), \ |
| 378 buffer_(buffer), \ | 378 buffer_(buffer), \ |
| 379 index1_(index1), \ | 379 index1_(index1), \ |
| 380 index2_(index2), \ | 380 index2_(index2), \ |
| 381 length_(length) {} \ | 381 length_(length) {} \ |
| 382 \ | 382 \ |
| 383 void Generate() FINAL { \ | 383 void Generate() final { \ |
| 384 Label oob; \ | 384 Label oob; \ |
| 385 __ leal(kScratchRegister, Operand(index1_, index2_)); \ | 385 __ leal(kScratchRegister, Operand(index1_, index2_)); \ |
| 386 __ cmpl(kScratchRegister, Immediate(length_)); \ | 386 __ cmpl(kScratchRegister, Immediate(length_)); \ |
| 387 __ j(above_equal, &oob, Label::kNear); \ | 387 __ j(above_equal, &oob, Label::kNear); \ |
| 388 __ asm_instr(result_, \ | 388 __ asm_instr(result_, \ |
| 389 Operand(buffer_, kScratchRegister, times_1, 0)); \ | 389 Operand(buffer_, kScratchRegister, times_1, 0)); \ |
| 390 __ jmp(exit()); \ | 390 __ jmp(exit()); \ |
| 391 __ bind(&oob); \ | 391 __ bind(&oob); \ |
| 392 __ xorl(result_, result_); \ | 392 __ xorl(result_, result_); \ |
| 393 } \ | 393 } \ |
| (...skipping 25 matching lines...) Expand all Loading... |
| 419 DCHECK_EQ(0, index2); \ | 419 DCHECK_EQ(0, index2); \ |
| 420 Label done; \ | 420 Label done; \ |
| 421 __ cmpl(index1, length); \ | 421 __ cmpl(index1, length); \ |
| 422 __ j(above_equal, &done, Label::kNear); \ | 422 __ j(above_equal, &done, Label::kNear); \ |
| 423 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ | 423 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ |
| 424 __ bind(&done); \ | 424 __ bind(&done); \ |
| 425 } else { \ | 425 } else { \ |
| 426 auto length = i.InputInt32(3); \ | 426 auto length = i.InputInt32(3); \ |
| 427 DCHECK_LE(index2, length); \ | 427 DCHECK_LE(index2, length); \ |
| 428 __ cmpq(index1, Immediate(length - index2)); \ | 428 __ cmpq(index1, Immediate(length - index2)); \ |
| 429 class OutOfLineStoreFloat FINAL : public OutOfLineCode { \ | 429 class OutOfLineStoreFloat final : public OutOfLineCode { \ |
| 430 public: \ | 430 public: \ |
| 431 OutOfLineStoreFloat(CodeGenerator* gen, Register buffer, \ | 431 OutOfLineStoreFloat(CodeGenerator* gen, Register buffer, \ |
| 432 Register index1, int32_t index2, int32_t length, \ | 432 Register index1, int32_t index2, int32_t length, \ |
| 433 XMMRegister value) \ | 433 XMMRegister value) \ |
| 434 : OutOfLineCode(gen), \ | 434 : OutOfLineCode(gen), \ |
| 435 buffer_(buffer), \ | 435 buffer_(buffer), \ |
| 436 index1_(index1), \ | 436 index1_(index1), \ |
| 437 index2_(index2), \ | 437 index2_(index2), \ |
| 438 length_(length), \ | 438 length_(length), \ |
| 439 value_(value) {} \ | 439 value_(value) {} \ |
| 440 \ | 440 \ |
| 441 void Generate() FINAL { \ | 441 void Generate() final { \ |
| 442 __ leal(kScratchRegister, Operand(index1_, index2_)); \ | 442 __ leal(kScratchRegister, Operand(index1_, index2_)); \ |
| 443 __ cmpl(kScratchRegister, Immediate(length_)); \ | 443 __ cmpl(kScratchRegister, Immediate(length_)); \ |
| 444 __ j(above_equal, exit()); \ | 444 __ j(above_equal, exit()); \ |
| 445 __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0), \ | 445 __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0), \ |
| 446 value_); \ | 446 value_); \ |
| 447 } \ | 447 } \ |
| 448 \ | 448 \ |
| 449 private: \ | 449 private: \ |
| 450 Register const buffer_; \ | 450 Register const buffer_; \ |
| 451 Register const index1_; \ | 451 Register const index1_; \ |
| (...skipping 20 matching lines...) Expand all Loading... |
| 472 DCHECK_EQ(0, index2); \ | 472 DCHECK_EQ(0, index2); \ |
| 473 Label done; \ | 473 Label done; \ |
| 474 __ cmpl(index1, length); \ | 474 __ cmpl(index1, length); \ |
| 475 __ j(above_equal, &done, Label::kNear); \ | 475 __ j(above_equal, &done, Label::kNear); \ |
| 476 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ | 476 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ |
| 477 __ bind(&done); \ | 477 __ bind(&done); \ |
| 478 } else { \ | 478 } else { \ |
| 479 auto length = i.InputInt32(3); \ | 479 auto length = i.InputInt32(3); \ |
| 480 DCHECK_LE(index2, length); \ | 480 DCHECK_LE(index2, length); \ |
| 481 __ cmpq(index1, Immediate(length - index2)); \ | 481 __ cmpq(index1, Immediate(length - index2)); \ |
| 482 class OutOfLineStoreInteger FINAL : public OutOfLineCode { \ | 482 class OutOfLineStoreInteger final : public OutOfLineCode { \ |
| 483 public: \ | 483 public: \ |
| 484 OutOfLineStoreInteger(CodeGenerator* gen, Register buffer, \ | 484 OutOfLineStoreInteger(CodeGenerator* gen, Register buffer, \ |
| 485 Register index1, int32_t index2, int32_t length, \ | 485 Register index1, int32_t index2, int32_t length, \ |
| 486 Value value) \ | 486 Value value) \ |
| 487 : OutOfLineCode(gen), \ | 487 : OutOfLineCode(gen), \ |
| 488 buffer_(buffer), \ | 488 buffer_(buffer), \ |
| 489 index1_(index1), \ | 489 index1_(index1), \ |
| 490 index2_(index2), \ | 490 index2_(index2), \ |
| 491 length_(length), \ | 491 length_(length), \ |
| 492 value_(value) {} \ | 492 value_(value) {} \ |
| 493 \ | 493 \ |
| 494 void Generate() FINAL { \ | 494 void Generate() final { \ |
| 495 __ leal(kScratchRegister, Operand(index1_, index2_)); \ | 495 __ leal(kScratchRegister, Operand(index1_, index2_)); \ |
| 496 __ cmpl(kScratchRegister, Immediate(length_)); \ | 496 __ cmpl(kScratchRegister, Immediate(length_)); \ |
| 497 __ j(above_equal, exit()); \ | 497 __ j(above_equal, exit()); \ |
| 498 __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0), \ | 498 __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0), \ |
| 499 value_); \ | 499 value_); \ |
| 500 } \ | 500 } \ |
| 501 \ | 501 \ |
| 502 private: \ | 502 private: \ |
| 503 Register const buffer_; \ | 503 Register const buffer_; \ |
| 504 Register const index1_; \ | 504 Register const index1_; \ |
| (...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1665 } | 1665 } |
| 1666 } | 1666 } |
| 1667 MarkLazyDeoptSite(); | 1667 MarkLazyDeoptSite(); |
| 1668 } | 1668 } |
| 1669 | 1669 |
| 1670 #undef __ | 1670 #undef __ |
| 1671 | 1671 |
| 1672 } // namespace internal | 1672 } // namespace internal |
| 1673 } // namespace compiler | 1673 } // namespace compiler |
| 1674 } // namespace v8 | 1674 } // namespace v8 |
| OLD | NEW |