OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
8 #include "src/arm64/macro-assembler-arm64.h" | 8 #include "src/arm64/macro-assembler-arm64.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/compiler/code-generator-impl.h" | 10 #include "src/compiler/code-generator-impl.h" |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 case kUnorderedEqual: | 393 case kUnorderedEqual: |
394 case kUnorderedNotEqual: | 394 case kUnorderedNotEqual: |
395 break; | 395 break; |
396 } | 396 } |
397 UNREACHABLE(); | 397 UNREACHABLE(); |
398 return nv; | 398 return nv; |
399 } | 399 } |
400 | 400 |
401 } // namespace | 401 } // namespace |
402 | 402 |
| 403 #define ASSEMBLE_BOUNDS_CHECK(offset, length, out_of_bounds) \ |
| 404 do { \ |
| 405 if (length.IsImmediate() && \ |
| 406 base::bits::IsPowerOfTwo64(length.ImmediateValue())) { \ |
| 407 __ Tst(offset, ~(length.ImmediateValue() - 1)); \ |
| 408 __ B(ne, out_of_bounds); \ |
| 409 } else { \ |
| 410 __ Cmp(offset, length); \ |
| 411 __ B(hs, out_of_bounds); \ |
| 412 } \ |
| 413 } while (0) |
403 | 414 |
404 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \ | 415 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \ |
405 do { \ | 416 do { \ |
406 auto result = i.OutputFloat##width##Register(); \ | 417 auto result = i.OutputFloat##width##Register(); \ |
407 auto buffer = i.InputRegister(0); \ | 418 auto buffer = i.InputRegister(0); \ |
408 auto offset = i.InputRegister32(1); \ | 419 auto offset = i.InputRegister32(1); \ |
409 auto length = i.InputOperand32(2); \ | 420 auto length = i.InputOperand32(2); \ |
410 __ Cmp(offset, length); \ | |
411 auto ool = new (zone()) OutOfLineLoadNaN##width(this, result); \ | 421 auto ool = new (zone()) OutOfLineLoadNaN##width(this, result); \ |
412 __ B(hs, ool->entry()); \ | 422 ASSEMBLE_BOUNDS_CHECK(offset, length, ool->entry()); \ |
413 __ Ldr(result, MemOperand(buffer, offset, UXTW)); \ | 423 __ Ldr(result, MemOperand(buffer, offset, UXTW)); \ |
414 __ Bind(ool->exit()); \ | 424 __ Bind(ool->exit()); \ |
415 } while (0) | 425 } while (0) |
416 | 426 |
417 | |
418 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ | 427 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ |
419 do { \ | 428 do { \ |
420 auto result = i.OutputRegister32(); \ | 429 auto result = i.OutputRegister32(); \ |
421 auto buffer = i.InputRegister(0); \ | 430 auto buffer = i.InputRegister(0); \ |
422 auto offset = i.InputRegister32(1); \ | 431 auto offset = i.InputRegister32(1); \ |
423 auto length = i.InputOperand32(2); \ | 432 auto length = i.InputOperand32(2); \ |
424 __ Cmp(offset, length); \ | |
425 auto ool = new (zone()) OutOfLineLoadZero(this, result); \ | 433 auto ool = new (zone()) OutOfLineLoadZero(this, result); \ |
426 __ B(hs, ool->entry()); \ | 434 ASSEMBLE_BOUNDS_CHECK(offset, length, ool->entry()); \ |
427 __ asm_instr(result, MemOperand(buffer, offset, UXTW)); \ | 435 __ asm_instr(result, MemOperand(buffer, offset, UXTW)); \ |
428 __ Bind(ool->exit()); \ | 436 __ Bind(ool->exit()); \ |
429 } while (0) | 437 } while (0) |
430 | 438 |
431 | |
432 #define ASSEMBLE_CHECKED_LOAD_INTEGER_64(asm_instr) \ | 439 #define ASSEMBLE_CHECKED_LOAD_INTEGER_64(asm_instr) \ |
433 do { \ | 440 do { \ |
434 auto result = i.OutputRegister(); \ | 441 auto result = i.OutputRegister(); \ |
435 auto buffer = i.InputRegister(0); \ | 442 auto buffer = i.InputRegister(0); \ |
436 auto offset = i.InputRegister32(1); \ | 443 auto offset = i.InputRegister32(1); \ |
437 auto length = i.InputOperand32(2); \ | 444 auto length = i.InputOperand32(2); \ |
438 __ Cmp(offset, length); \ | |
439 auto ool = new (zone()) OutOfLineLoadZero(this, result); \ | 445 auto ool = new (zone()) OutOfLineLoadZero(this, result); \ |
440 __ B(hs, ool->entry()); \ | 446 ASSEMBLE_BOUNDS_CHECK(offset, length, ool->entry()); \ |
441 __ asm_instr(result, MemOperand(buffer, offset, UXTW)); \ | 447 __ asm_instr(result, MemOperand(buffer, offset, UXTW)); \ |
442 __ Bind(ool->exit()); \ | 448 __ Bind(ool->exit()); \ |
443 } while (0) | 449 } while (0) |
444 | 450 |
445 #define ASSEMBLE_CHECKED_STORE_FLOAT(width) \ | 451 #define ASSEMBLE_CHECKED_STORE_FLOAT(width) \ |
446 do { \ | 452 do { \ |
447 auto buffer = i.InputRegister(0); \ | 453 auto buffer = i.InputRegister(0); \ |
448 auto offset = i.InputRegister32(1); \ | 454 auto offset = i.InputRegister32(1); \ |
449 auto length = i.InputOperand32(2); \ | 455 auto length = i.InputOperand32(2); \ |
450 auto value = i.InputFloat##width##OrZeroRegister(3); \ | 456 auto value = i.InputFloat##width##OrZeroRegister(3); \ |
451 __ Cmp(offset, length); \ | |
452 Label done; \ | 457 Label done; \ |
453 __ B(hs, &done); \ | 458 ASSEMBLE_BOUNDS_CHECK(offset, length, &done); \ |
454 __ Str(value, MemOperand(buffer, offset, UXTW)); \ | 459 __ Str(value, MemOperand(buffer, offset, UXTW)); \ |
455 __ Bind(&done); \ | 460 __ Bind(&done); \ |
456 } while (0) | 461 } while (0) |
457 | 462 |
458 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ | 463 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
459 do { \ | 464 do { \ |
460 auto buffer = i.InputRegister(0); \ | 465 auto buffer = i.InputRegister(0); \ |
461 auto offset = i.InputRegister32(1); \ | 466 auto offset = i.InputRegister32(1); \ |
462 auto length = i.InputOperand32(2); \ | 467 auto length = i.InputOperand32(2); \ |
463 auto value = i.InputOrZeroRegister32(3); \ | 468 auto value = i.InputOrZeroRegister32(3); \ |
464 __ Cmp(offset, length); \ | |
465 Label done; \ | 469 Label done; \ |
466 __ B(hs, &done); \ | 470 ASSEMBLE_BOUNDS_CHECK(offset, length, &done); \ |
467 __ asm_instr(value, MemOperand(buffer, offset, UXTW)); \ | 471 __ asm_instr(value, MemOperand(buffer, offset, UXTW)); \ |
468 __ Bind(&done); \ | 472 __ Bind(&done); \ |
469 } while (0) | 473 } while (0) |
470 | 474 |
471 #define ASSEMBLE_CHECKED_STORE_INTEGER_64(asm_instr) \ | 475 #define ASSEMBLE_CHECKED_STORE_INTEGER_64(asm_instr) \ |
472 do { \ | 476 do { \ |
473 auto buffer = i.InputRegister(0); \ | 477 auto buffer = i.InputRegister(0); \ |
474 auto offset = i.InputRegister32(1); \ | 478 auto offset = i.InputRegister32(1); \ |
475 auto length = i.InputOperand32(2); \ | 479 auto length = i.InputOperand32(2); \ |
476 auto value = i.InputOrZeroRegister64(3); \ | 480 auto value = i.InputOrZeroRegister64(3); \ |
477 __ Cmp(offset, length); \ | |
478 Label done; \ | 481 Label done; \ |
479 __ B(hs, &done); \ | 482 ASSEMBLE_BOUNDS_CHECK(offset, length, &done); \ |
480 __ asm_instr(value, MemOperand(buffer, offset, UXTW)); \ | 483 __ asm_instr(value, MemOperand(buffer, offset, UXTW)); \ |
481 __ Bind(&done); \ | 484 __ Bind(&done); \ |
482 } while (0) | 485 } while (0) |
483 | 486 |
484 #define ASSEMBLE_SHIFT(asm_instr, width) \ | 487 #define ASSEMBLE_SHIFT(asm_instr, width) \ |
485 do { \ | 488 do { \ |
486 if (instr->InputAt(1)->IsRegister()) { \ | 489 if (instr->InputAt(1)->IsRegister()) { \ |
487 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ | 490 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ |
488 i.InputRegister##width(1)); \ | 491 i.InputRegister##width(1)); \ |
489 } else { \ | 492 } else { \ |
(...skipping 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1927 padding_size -= kInstructionSize; | 1930 padding_size -= kInstructionSize; |
1928 } | 1931 } |
1929 } | 1932 } |
1930 } | 1933 } |
1931 | 1934 |
1932 #undef __ | 1935 #undef __ |
1933 | 1936 |
1934 } // namespace compiler | 1937 } // namespace compiler |
1935 } // namespace internal | 1938 } // namespace internal |
1936 } // namespace v8 | 1939 } // namespace v8 |
OLD | NEW |