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 |