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/compilation-info.h" | 7 #include "src/compilation-info.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 } | 176 } |
177 }; | 177 }; |
178 | 178 |
179 | 179 |
180 namespace { | 180 namespace { |
181 | 181 |
182 bool HasImmediateInput(Instruction* instr, size_t index) { | 182 bool HasImmediateInput(Instruction* instr, size_t index) { |
183 return instr->InputAt(index)->IsImmediate(); | 183 return instr->InputAt(index)->IsImmediate(); |
184 } | 184 } |
185 | 185 |
186 class OutOfLineLoadInteger final : public OutOfLineCode { | 186 class OutOfLineLoadZero final : public OutOfLineCode { |
187 public: | 187 public: |
188 OutOfLineLoadInteger(CodeGenerator* gen, Register result) | 188 OutOfLineLoadZero(CodeGenerator* gen, Register result) |
189 : OutOfLineCode(gen), result_(result) {} | 189 : OutOfLineCode(gen), result_(result) {} |
190 | 190 |
191 void Generate() final { __ xor_(result_, result_); } | 191 void Generate() final { __ xor_(result_, result_); } |
192 | 192 |
193 private: | 193 private: |
194 Register const result_; | 194 Register const result_; |
195 }; | 195 }; |
196 | 196 |
197 class OutOfLineLoadFloat32NaN final : public OutOfLineCode { | 197 class OutOfLineLoadFloat32NaN final : public OutOfLineCode { |
198 public: | 198 public: |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 Register const object_; | 276 Register const object_; |
277 Operand const operand_; | 277 Operand const operand_; |
278 Register const value_; | 278 Register const value_; |
279 Register const scratch0_; | 279 Register const scratch0_; |
280 Register const scratch1_; | 280 Register const scratch1_; |
281 RecordWriteMode const mode_; | 281 RecordWriteMode const mode_; |
282 }; | 282 }; |
283 | 283 |
284 } // namespace | 284 } // namespace |
285 | 285 |
286 #define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr, OutOfLineLoadNaN) \ | 286 #define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr, OutOfLineLoadNaN, \ |
287 do { \ | 287 SingleOrDouble) \ |
288 auto result = i.OutputDoubleRegister(); \ | 288 do { \ |
289 auto offset = i.InputRegister(0); \ | 289 auto result = i.OutputDoubleRegister(); \ |
290 if (instr->InputAt(1)->IsRegister()) { \ | 290 if (instr->InputAt(0)->IsRegister()) { \ |
291 __ cmp(offset, i.InputRegister(1)); \ | 291 auto offset = i.InputRegister(0); \ |
292 } else { \ | 292 if (instr->InputAt(1)->IsRegister()) { \ |
293 __ cmp(offset, i.InputImmediate(1)); \ | 293 __ cmp(offset, i.InputRegister(1)); \ |
294 } \ | 294 } else { \ |
295 OutOfLineCode* ool = new (zone()) OutOfLineLoadNaN(this, result); \ | 295 __ cmp(offset, i.InputImmediate(1)); \ |
296 __ j(above_equal, ool->entry()); \ | 296 } \ |
297 __ asm_instr(result, i.MemoryOperand(2)); \ | 297 OutOfLineCode* ool = new (zone()) OutOfLineLoadNaN(this, result); \ |
298 __ bind(ool->exit()); \ | 298 __ j(above_equal, ool->entry()); \ |
| 299 __ asm_instr(result, i.MemoryOperand(2)); \ |
| 300 __ bind(ool->exit()); \ |
| 301 } else { \ |
| 302 auto index2 = i.InputInt32(0); \ |
| 303 auto length = i.InputInt32(1); \ |
| 304 auto index1 = i.InputRegister(2); \ |
| 305 RelocInfo::Mode rmode_length = i.ToConstant(instr->InputAt(1)).rmode(); \ |
| 306 RelocInfo::Mode rmode_buffer = i.ToConstant(instr->InputAt(3)).rmode(); \ |
| 307 DCHECK_LE(index2, length); \ |
| 308 __ cmp(index1, Immediate(reinterpret_cast<Address>(length - index2), \ |
| 309 rmode_length)); \ |
| 310 class OutOfLineLoadFloat final : public OutOfLineCode { \ |
| 311 public: \ |
| 312 OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result, \ |
| 313 Register buffer, Register index1, int32_t index2, \ |
| 314 int32_t length, RelocInfo::Mode rmode_length, \ |
| 315 RelocInfo::Mode rmode_buffer) \ |
| 316 : OutOfLineCode(gen), \ |
| 317 result_(result), \ |
| 318 buffer_reg_(buffer), \ |
| 319 buffer_int_(0), \ |
| 320 index1_(index1), \ |
| 321 index2_(index2), \ |
| 322 length_(length), \ |
| 323 rmode_length_(rmode_length), \ |
| 324 rmode_buffer_(rmode_buffer) {} \ |
| 325 \ |
| 326 OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result, \ |
| 327 int32_t buffer, Register index1, int32_t index2, \ |
| 328 int32_t length, RelocInfo::Mode rmode_length, \ |
| 329 RelocInfo::Mode rmode_buffer) \ |
| 330 : OutOfLineCode(gen), \ |
| 331 result_(result), \ |
| 332 buffer_reg_({-1}), \ |
| 333 buffer_int_(buffer), \ |
| 334 index1_(index1), \ |
| 335 index2_(index2), \ |
| 336 length_(length), \ |
| 337 rmode_length_(rmode_length), \ |
| 338 rmode_buffer_(rmode_buffer) {} \ |
| 339 \ |
| 340 void Generate() final { \ |
| 341 Label oob; \ |
| 342 __ push(index1_); \ |
| 343 __ lea(index1_, Operand(index1_, index2_)); \ |
| 344 __ cmp(index1_, Immediate(reinterpret_cast<Address>(length_), \ |
| 345 rmode_length_)); \ |
| 346 __ j(above_equal, &oob, Label::kNear); \ |
| 347 if (buffer_reg_.is_valid()) { \ |
| 348 __ asm_instr(result_, Operand(buffer_reg_, index1_, times_1, 0)); \ |
| 349 } else { \ |
| 350 __ asm_instr(result_, \ |
| 351 Operand(index1_, buffer_int_, rmode_buffer_)); \ |
| 352 } \ |
| 353 __ pop(index1_); \ |
| 354 __ jmp(exit()); \ |
| 355 __ bind(&oob); \ |
| 356 __ pop(index1_); \ |
| 357 __ xorp##SingleOrDouble(result_, result_); \ |
| 358 __ divs##SingleOrDouble(result_, result_); \ |
| 359 } \ |
| 360 \ |
| 361 private: \ |
| 362 XMMRegister const result_; \ |
| 363 Register const buffer_reg_; \ |
| 364 int32_t const buffer_int_; \ |
| 365 Register const index1_; \ |
| 366 int32_t const index2_; \ |
| 367 int32_t const length_; \ |
| 368 RelocInfo::Mode rmode_length_; \ |
| 369 RelocInfo::Mode rmode_buffer_; \ |
| 370 }; \ |
| 371 if (instr->InputAt(3)->IsRegister()) { \ |
| 372 auto buffer = i.InputRegister(3); \ |
| 373 OutOfLineCode* ool = new (zone()) \ |
| 374 OutOfLineLoadFloat(this, result, buffer, index1, index2, length, \ |
| 375 rmode_length, rmode_buffer); \ |
| 376 __ j(above_equal, ool->entry()); \ |
| 377 __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \ |
| 378 __ bind(ool->exit()); \ |
| 379 } else { \ |
| 380 auto buffer = i.InputInt32(3); \ |
| 381 OutOfLineCode* ool = new (zone()) \ |
| 382 OutOfLineLoadFloat(this, result, buffer, index1, index2, length, \ |
| 383 rmode_length, rmode_buffer); \ |
| 384 __ j(above_equal, ool->entry()); \ |
| 385 __ asm_instr(result, Operand(index1, buffer + index2, rmode_buffer)); \ |
| 386 __ bind(ool->exit()); \ |
| 387 } \ |
| 388 } \ |
299 } while (false) | 389 } while (false) |
300 | 390 |
301 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ | 391 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ |
302 do { \ | 392 do { \ |
303 auto result = i.OutputRegister(); \ | 393 auto result = i.OutputRegister(); \ |
304 auto offset = i.InputRegister(0); \ | 394 if (instr->InputAt(0)->IsRegister()) { \ |
305 if (instr->InputAt(1)->IsRegister()) { \ | 395 auto offset = i.InputRegister(0); \ |
306 __ cmp(offset, i.InputRegister(1)); \ | 396 if (instr->InputAt(1)->IsRegister()) { \ |
307 } else { \ | 397 __ cmp(offset, i.InputRegister(1)); \ |
308 __ cmp(offset, i.InputImmediate(1)); \ | 398 } else { \ |
309 } \ | 399 __ cmp(offset, i.InputImmediate(1)); \ |
310 OutOfLineCode* ool = new (zone()) OutOfLineLoadInteger(this, result); \ | 400 } \ |
311 __ j(above_equal, ool->entry()); \ | 401 OutOfLineCode* ool = new (zone()) OutOfLineLoadZero(this, result); \ |
312 __ asm_instr(result, i.MemoryOperand(2)); \ | 402 __ j(above_equal, ool->entry()); \ |
313 __ bind(ool->exit()); \ | 403 __ asm_instr(result, i.MemoryOperand(2)); \ |
| 404 __ bind(ool->exit()); \ |
| 405 } else { \ |
| 406 auto index2 = i.InputInt32(0); \ |
| 407 auto length = i.InputInt32(1); \ |
| 408 auto index1 = i.InputRegister(2); \ |
| 409 RelocInfo::Mode rmode_length = i.ToConstant(instr->InputAt(1)).rmode(); \ |
| 410 RelocInfo::Mode rmode_buffer = i.ToConstant(instr->InputAt(3)).rmode(); \ |
| 411 DCHECK_LE(index2, length); \ |
| 412 __ cmp(index1, Immediate(reinterpret_cast<Address>(length - index2), \ |
| 413 rmode_length)); \ |
| 414 class OutOfLineLoadInteger final : public OutOfLineCode { \ |
| 415 public: \ |
| 416 OutOfLineLoadInteger(CodeGenerator* gen, Register result, \ |
| 417 Register buffer, Register index1, int32_t index2, \ |
| 418 int32_t length, RelocInfo::Mode rmode_length, \ |
| 419 RelocInfo::Mode rmode_buffer) \ |
| 420 : OutOfLineCode(gen), \ |
| 421 result_(result), \ |
| 422 buffer_reg_(buffer), \ |
| 423 buffer_int_(0), \ |
| 424 index1_(index1), \ |
| 425 index2_(index2), \ |
| 426 length_(length), \ |
| 427 rmode_length_(rmode_length), \ |
| 428 rmode_buffer_(rmode_buffer) {} \ |
| 429 \ |
| 430 OutOfLineLoadInteger(CodeGenerator* gen, Register result, \ |
| 431 int32_t buffer, Register index1, int32_t index2, \ |
| 432 int32_t length, RelocInfo::Mode rmode_length, \ |
| 433 RelocInfo::Mode rmode_buffer) \ |
| 434 : OutOfLineCode(gen), \ |
| 435 result_(result), \ |
| 436 buffer_reg_({-1}), \ |
| 437 buffer_int_(buffer), \ |
| 438 index1_(index1), \ |
| 439 index2_(index2), \ |
| 440 length_(length), \ |
| 441 rmode_length_(rmode_length), \ |
| 442 rmode_buffer_(rmode_buffer) {} \ |
| 443 \ |
| 444 void Generate() final { \ |
| 445 Label oob; \ |
| 446 bool need_cache = !result_.is(index1_); \ |
| 447 if (need_cache) __ push(index1_); \ |
| 448 __ lea(index1_, Operand(index1_, index2_)); \ |
| 449 __ cmp(index1_, Immediate(reinterpret_cast<Address>(length_), \ |
| 450 rmode_length_)); \ |
| 451 __ j(above_equal, &oob, Label::kNear); \ |
| 452 if (buffer_reg_.is_valid()) { \ |
| 453 __ asm_instr(result_, Operand(buffer_reg_, index1_, times_1, 0)); \ |
| 454 } else { \ |
| 455 __ asm_instr(result_, \ |
| 456 Operand(index1_, buffer_int_, rmode_buffer_)); \ |
| 457 } \ |
| 458 if (need_cache) __ pop(index1_); \ |
| 459 __ jmp(exit()); \ |
| 460 __ bind(&oob); \ |
| 461 if (need_cache) __ pop(index1_); \ |
| 462 __ xor_(result_, result_); \ |
| 463 } \ |
| 464 \ |
| 465 private: \ |
| 466 Register const result_; \ |
| 467 Register const buffer_reg_; \ |
| 468 int32_t const buffer_int_; \ |
| 469 Register const index1_; \ |
| 470 int32_t const index2_; \ |
| 471 int32_t const length_; \ |
| 472 RelocInfo::Mode rmode_length_; \ |
| 473 RelocInfo::Mode rmode_buffer_; \ |
| 474 }; \ |
| 475 if (instr->InputAt(3)->IsRegister()) { \ |
| 476 auto buffer = i.InputRegister(3); \ |
| 477 OutOfLineCode* ool = new (zone()) \ |
| 478 OutOfLineLoadInteger(this, result, buffer, index1, index2, length, \ |
| 479 rmode_length, rmode_buffer); \ |
| 480 __ j(above_equal, ool->entry()); \ |
| 481 __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \ |
| 482 __ bind(ool->exit()); \ |
| 483 } else { \ |
| 484 auto buffer = i.InputInt32(3); \ |
| 485 OutOfLineCode* ool = new (zone()) \ |
| 486 OutOfLineLoadInteger(this, result, buffer, index1, index2, length, \ |
| 487 rmode_length, rmode_buffer); \ |
| 488 __ j(above_equal, ool->entry()); \ |
| 489 __ asm_instr(result, Operand(index1, buffer + index2, rmode_buffer)); \ |
| 490 __ bind(ool->exit()); \ |
| 491 } \ |
| 492 } \ |
314 } while (false) | 493 } while (false) |
315 | 494 |
316 #define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \ | 495 #define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \ |
317 do { \ | 496 do { \ |
318 auto offset = i.InputRegister(0); \ | 497 auto value = i.InputDoubleRegister(2); \ |
319 if (instr->InputAt(1)->IsRegister()) { \ | 498 if (instr->InputAt(0)->IsRegister()) { \ |
320 __ cmp(offset, i.InputRegister(1)); \ | 499 auto offset = i.InputRegister(0); \ |
321 } else { \ | 500 if (instr->InputAt(1)->IsRegister()) { \ |
322 __ cmp(offset, i.InputImmediate(1)); \ | 501 __ cmp(offset, i.InputRegister(1)); \ |
323 } \ | 502 } else { \ |
324 Label done; \ | 503 __ cmp(offset, i.InputImmediate(1)); \ |
325 __ j(above_equal, &done, Label::kNear); \ | 504 } \ |
326 __ asm_instr(i.MemoryOperand(3), i.InputDoubleRegister(2)); \ | 505 Label done; \ |
327 __ bind(&done); \ | 506 __ j(above_equal, &done, Label::kNear); \ |
| 507 __ asm_instr(i.MemoryOperand(3), value); \ |
| 508 __ bind(&done); \ |
| 509 } else { \ |
| 510 auto index2 = i.InputInt32(0); \ |
| 511 auto length = i.InputInt32(1); \ |
| 512 auto index1 = i.InputRegister(3); \ |
| 513 RelocInfo::Mode rmode_length = i.ToConstant(instr->InputAt(1)).rmode(); \ |
| 514 RelocInfo::Mode rmode_buffer = i.ToConstant(instr->InputAt(4)).rmode(); \ |
| 515 DCHECK_LE(index2, length); \ |
| 516 __ cmp(index1, Immediate(reinterpret_cast<Address>(length - index2), \ |
| 517 rmode_length)); \ |
| 518 class OutOfLineStoreFloat final : public OutOfLineCode { \ |
| 519 public: \ |
| 520 OutOfLineStoreFloat(CodeGenerator* gen, Register buffer, \ |
| 521 Register index1, int32_t index2, int32_t length, \ |
| 522 XMMRegister value, RelocInfo::Mode rmode_length, \ |
| 523 RelocInfo::Mode rmode_buffer) \ |
| 524 : OutOfLineCode(gen), \ |
| 525 buffer_reg_(buffer), \ |
| 526 buffer_int_(0), \ |
| 527 index1_(index1), \ |
| 528 index2_(index2), \ |
| 529 length_(length), \ |
| 530 value_(value), \ |
| 531 rmode_length_(rmode_length), \ |
| 532 rmode_buffer_(rmode_buffer) {} \ |
| 533 \ |
| 534 OutOfLineStoreFloat(CodeGenerator* gen, int32_t buffer, \ |
| 535 Register index1, int32_t index2, int32_t length, \ |
| 536 XMMRegister value, RelocInfo::Mode rmode_length, \ |
| 537 RelocInfo::Mode rmode_buffer) \ |
| 538 : OutOfLineCode(gen), \ |
| 539 buffer_reg_({-1}), \ |
| 540 buffer_int_(buffer), \ |
| 541 index1_(index1), \ |
| 542 index2_(index2), \ |
| 543 length_(length), \ |
| 544 value_(value), \ |
| 545 rmode_length_(rmode_length), \ |
| 546 rmode_buffer_(rmode_buffer) {} \ |
| 547 \ |
| 548 void Generate() final { \ |
| 549 Label oob; \ |
| 550 __ push(index1_); \ |
| 551 __ lea(index1_, Operand(index1_, index2_)); \ |
| 552 __ cmp(index1_, Immediate(reinterpret_cast<Address>(length_), \ |
| 553 rmode_length_)); \ |
| 554 __ j(above_equal, &oob, Label::kNear); \ |
| 555 if (buffer_reg_.is_valid()) { \ |
| 556 __ asm_instr(Operand(buffer_reg_, index1_, times_1, 0), value_); \ |
| 557 } else { \ |
| 558 __ asm_instr(Operand(index1_, buffer_int_, rmode_buffer_), \ |
| 559 value_); \ |
| 560 } \ |
| 561 __ bind(&oob); \ |
| 562 __ pop(index1_); \ |
| 563 } \ |
| 564 \ |
| 565 private: \ |
| 566 Register const buffer_reg_; \ |
| 567 int32_t const buffer_int_; \ |
| 568 Register const index1_; \ |
| 569 int32_t const index2_; \ |
| 570 int32_t const length_; \ |
| 571 XMMRegister const value_; \ |
| 572 RelocInfo::Mode rmode_length_; \ |
| 573 RelocInfo::Mode rmode_buffer_; \ |
| 574 }; \ |
| 575 if (instr->InputAt(4)->IsRegister()) { \ |
| 576 auto buffer = i.InputRegister(4); \ |
| 577 OutOfLineCode* ool = new (zone()) \ |
| 578 OutOfLineStoreFloat(this, buffer, index1, index2, length, value, \ |
| 579 rmode_length, rmode_buffer); \ |
| 580 __ j(above_equal, ool->entry()); \ |
| 581 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ |
| 582 __ bind(ool->exit()); \ |
| 583 } else { \ |
| 584 auto buffer = i.InputInt32(4); \ |
| 585 OutOfLineCode* ool = new (zone()) \ |
| 586 OutOfLineStoreFloat(this, buffer, index1, index2, length, value, \ |
| 587 rmode_length, rmode_buffer); \ |
| 588 __ j(above_equal, ool->entry()); \ |
| 589 __ asm_instr(Operand(index1, buffer + index2, rmode_buffer), value); \ |
| 590 __ bind(ool->exit()); \ |
| 591 } \ |
| 592 } \ |
328 } while (false) | 593 } while (false) |
329 | 594 |
330 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ | 595 #define ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Value) \ |
331 do { \ | 596 do { \ |
332 auto offset = i.InputRegister(0); \ | 597 if (instr->InputAt(0)->IsRegister()) { \ |
333 if (instr->InputAt(1)->IsRegister()) { \ | 598 auto offset = i.InputRegister(0); \ |
334 __ cmp(offset, i.InputRegister(1)); \ | 599 if (instr->InputAt(1)->IsRegister()) { \ |
335 } else { \ | 600 __ cmp(offset, i.InputRegister(1)); \ |
336 __ cmp(offset, i.InputImmediate(1)); \ | 601 } else { \ |
337 } \ | 602 __ cmp(offset, i.InputImmediate(1)); \ |
338 Label done; \ | 603 } \ |
339 __ j(above_equal, &done, Label::kNear); \ | 604 Label done; \ |
340 if (instr->InputAt(2)->IsRegister()) { \ | 605 __ j(above_equal, &done, Label::kNear); \ |
341 __ asm_instr(i.MemoryOperand(3), i.InputRegister(2)); \ | 606 __ asm_instr(i.MemoryOperand(3), value); \ |
342 } else { \ | 607 __ bind(&done); \ |
343 __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \ | 608 } else { \ |
344 } \ | 609 auto index2 = i.InputInt32(0); \ |
345 __ bind(&done); \ | 610 auto length = i.InputInt32(1); \ |
| 611 auto index1 = i.InputRegister(3); \ |
| 612 RelocInfo::Mode rmode_length = i.ToConstant(instr->InputAt(1)).rmode(); \ |
| 613 RelocInfo::Mode rmode_buffer = i.ToConstant(instr->InputAt(4)).rmode(); \ |
| 614 DCHECK_LE(index2, length); \ |
| 615 __ cmp(index1, Immediate(reinterpret_cast<Address>(length - index2), \ |
| 616 rmode_length)); \ |
| 617 class OutOfLineStoreInteger final : public OutOfLineCode { \ |
| 618 public: \ |
| 619 OutOfLineStoreInteger(CodeGenerator* gen, Register buffer, \ |
| 620 Register index1, int32_t index2, int32_t length, \ |
| 621 Value value, RelocInfo::Mode rmode_length, \ |
| 622 RelocInfo::Mode rmode_buffer) \ |
| 623 : OutOfLineCode(gen), \ |
| 624 buffer_reg_(buffer), \ |
| 625 buffer_int_(0), \ |
| 626 index1_(index1), \ |
| 627 index2_(index2), \ |
| 628 length_(length), \ |
| 629 value_(value), \ |
| 630 rmode_length_(rmode_length), \ |
| 631 rmode_buffer_(rmode_buffer) {} \ |
| 632 \ |
| 633 OutOfLineStoreInteger(CodeGenerator* gen, int32_t buffer, \ |
| 634 Register index1, int32_t index2, int32_t length, \ |
| 635 Value value, RelocInfo::Mode rmode_length, \ |
| 636 RelocInfo::Mode rmode_buffer) \ |
| 637 : OutOfLineCode(gen), \ |
| 638 buffer_reg_({-1}), \ |
| 639 buffer_int_(buffer), \ |
| 640 index1_(index1), \ |
| 641 index2_(index2), \ |
| 642 length_(length), \ |
| 643 value_(value), \ |
| 644 rmode_length_(rmode_length), \ |
| 645 rmode_buffer_(rmode_buffer) {} \ |
| 646 \ |
| 647 void Generate() final { \ |
| 648 Label oob; \ |
| 649 __ push(index1_); \ |
| 650 __ lea(index1_, Operand(index1_, index2_)); \ |
| 651 __ cmp(index1_, Immediate(reinterpret_cast<Address>(length_), \ |
| 652 rmode_length_)); \ |
| 653 __ j(above_equal, &oob, Label::kNear); \ |
| 654 if (buffer_reg_.is_valid()) { \ |
| 655 __ asm_instr(Operand(buffer_reg_, index1_, times_1, 0), value_); \ |
| 656 } else { \ |
| 657 __ asm_instr(Operand(index1_, buffer_int_, rmode_buffer_), \ |
| 658 value_); \ |
| 659 } \ |
| 660 __ bind(&oob); \ |
| 661 __ pop(index1_); \ |
| 662 } \ |
| 663 \ |
| 664 private: \ |
| 665 Register const buffer_reg_; \ |
| 666 int32_t const buffer_int_; \ |
| 667 Register const index1_; \ |
| 668 int32_t const index2_; \ |
| 669 int32_t const length_; \ |
| 670 Value const value_; \ |
| 671 RelocInfo::Mode rmode_length_; \ |
| 672 RelocInfo::Mode rmode_buffer_; \ |
| 673 }; \ |
| 674 if (instr->InputAt(4)->IsRegister()) { \ |
| 675 auto buffer = i.InputRegister(4); \ |
| 676 OutOfLineCode* ool = new (zone()) \ |
| 677 OutOfLineStoreInteger(this, buffer, index1, index2, length, value, \ |
| 678 rmode_length, rmode_buffer); \ |
| 679 __ j(above_equal, ool->entry()); \ |
| 680 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ |
| 681 __ bind(ool->exit()); \ |
| 682 } else { \ |
| 683 auto buffer = i.InputInt32(4); \ |
| 684 OutOfLineCode* ool = new (zone()) \ |
| 685 OutOfLineStoreInteger(this, buffer, index1, index2, length, value, \ |
| 686 rmode_length, rmode_buffer); \ |
| 687 __ j(above_equal, ool->entry()); \ |
| 688 __ asm_instr(Operand(index1, buffer + index2, rmode_buffer), value); \ |
| 689 __ bind(ool->exit()); \ |
| 690 } \ |
| 691 } \ |
346 } while (false) | 692 } while (false) |
347 | 693 |
| 694 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
| 695 do { \ |
| 696 if (instr->InputAt(2)->IsRegister()) { \ |
| 697 Register value = i.InputRegister(2); \ |
| 698 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register); \ |
| 699 } else { \ |
| 700 Immediate value = i.InputImmediate(2); \ |
| 701 ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \ |
| 702 } \ |
| 703 } while (false) |
| 704 |
348 #define ASSEMBLE_COMPARE(asm_instr) \ | 705 #define ASSEMBLE_COMPARE(asm_instr) \ |
349 do { \ | 706 do { \ |
350 if (AddressingModeField::decode(instr->opcode()) != kMode_None) { \ | 707 if (AddressingModeField::decode(instr->opcode()) != kMode_None) { \ |
351 size_t index = 0; \ | 708 size_t index = 0; \ |
352 Operand left = i.MemoryOperand(&index); \ | 709 Operand left = i.MemoryOperand(&index); \ |
353 if (HasImmediateInput(instr, index)) { \ | 710 if (HasImmediateInput(instr, index)) { \ |
354 __ asm_instr(left, i.InputImmediate(index)); \ | 711 __ asm_instr(left, i.InputImmediate(index)); \ |
355 } else { \ | 712 } else { \ |
356 __ asm_instr(left, i.InputRegister(index)); \ | 713 __ asm_instr(left, i.InputRegister(index)); \ |
357 } \ | 714 } \ |
(...skipping 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 case kCheckedLoadInt16: | 1912 case kCheckedLoadInt16: |
1556 ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_w); | 1913 ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_w); |
1557 break; | 1914 break; |
1558 case kCheckedLoadUint16: | 1915 case kCheckedLoadUint16: |
1559 ASSEMBLE_CHECKED_LOAD_INTEGER(movzx_w); | 1916 ASSEMBLE_CHECKED_LOAD_INTEGER(movzx_w); |
1560 break; | 1917 break; |
1561 case kCheckedLoadWord32: | 1918 case kCheckedLoadWord32: |
1562 ASSEMBLE_CHECKED_LOAD_INTEGER(mov); | 1919 ASSEMBLE_CHECKED_LOAD_INTEGER(mov); |
1563 break; | 1920 break; |
1564 case kCheckedLoadFloat32: | 1921 case kCheckedLoadFloat32: |
1565 ASSEMBLE_CHECKED_LOAD_FLOAT(movss, OutOfLineLoadFloat32NaN); | 1922 ASSEMBLE_CHECKED_LOAD_FLOAT(movss, OutOfLineLoadFloat32NaN, s); |
1566 break; | 1923 break; |
1567 case kCheckedLoadFloat64: | 1924 case kCheckedLoadFloat64: |
1568 ASSEMBLE_CHECKED_LOAD_FLOAT(movsd, OutOfLineLoadFloat64NaN); | 1925 ASSEMBLE_CHECKED_LOAD_FLOAT(movsd, OutOfLineLoadFloat64NaN, d); |
1569 break; | 1926 break; |
1570 case kCheckedStoreWord8: | 1927 case kCheckedStoreWord8: |
1571 ASSEMBLE_CHECKED_STORE_INTEGER(mov_b); | 1928 ASSEMBLE_CHECKED_STORE_INTEGER(mov_b); |
1572 break; | 1929 break; |
1573 case kCheckedStoreWord16: | 1930 case kCheckedStoreWord16: |
1574 ASSEMBLE_CHECKED_STORE_INTEGER(mov_w); | 1931 ASSEMBLE_CHECKED_STORE_INTEGER(mov_w); |
1575 break; | 1932 break; |
1576 case kCheckedStoreWord32: | 1933 case kCheckedStoreWord32: |
1577 ASSEMBLE_CHECKED_STORE_INTEGER(mov); | 1934 ASSEMBLE_CHECKED_STORE_INTEGER(mov); |
1578 break; | 1935 break; |
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2301 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2658 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
2302 __ Nop(padding_size); | 2659 __ Nop(padding_size); |
2303 } | 2660 } |
2304 } | 2661 } |
2305 | 2662 |
2306 #undef __ | 2663 #undef __ |
2307 | 2664 |
2308 } // namespace compiler | 2665 } // namespace compiler |
2309 } // namespace internal | 2666 } // namespace internal |
2310 } // namespace v8 | 2667 } // namespace v8 |
OLD | NEW |