| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_INST_CLASSES_H | 7 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_INST_CLASSES_H |
| 8 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_INST_CLASSES_H | 8 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_INST_CLASSES_H |
| 9 | 9 |
| 10 #include <stdint.h> | 10 #include <stdint.h> |
| 11 #include "native_client/src/trusted/validator_arm/model.h" | 11 #include "native_client/src/trusted/validator_arm/model.h" |
| 12 #include "native_client/src/include/portability.h" | 12 #include "native_client/src/include/portability.h" |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 * being used. | 112 * being used. |
| 113 * | 113 * |
| 114 * Stubbed to return 'false', which is the common case. | 114 * Stubbed to return 'false', which is the common case. |
| 115 */ | 115 */ |
| 116 virtual bool writes_memory(Instruction i) const { | 116 virtual bool writes_memory(Instruction i) const { |
| 117 UNREFERENCED_PARAMETER(i); | 117 UNREFERENCED_PARAMETER(i); |
| 118 return false; | 118 return false; |
| 119 } | 119 } |
| 120 | 120 |
| 121 /* | 121 /* |
| 122 * For instructions that can write memory, gets the register used as the base | 122 * For instructions that can read or write memory, gets the register used as |
| 123 * for generating the effective address. | 123 * the base for generating the effective address. |
| 124 * | 124 * |
| 125 * The result is useful only for safe instructions where writes_memory() is | 125 * It is stubbed to return nonsense. |
| 126 * true. It is stubbed to return nonsense. | |
| 127 */ | 126 */ |
| 128 virtual Register base_address_register(Instruction i) const { | 127 virtual Register base_address_register(Instruction i) const { |
| 129 UNREFERENCED_PARAMETER(i); | 128 UNREFERENCED_PARAMETER(i); |
| 130 return kRegisterNone; | 129 return kRegisterNone; |
| 131 } | 130 } |
| 132 | 131 |
| 133 /* | 132 /* |
| 133 * Checks whether the instruction computes its read or write address as |
| 134 * base address + immediate. |
| 135 * |
| 136 * It is stubbed to return false. |
| 137 */ |
| 138 virtual bool offset_is_immediate(Instruction i) const { |
| 139 UNREFERENCED_PARAMETER(i); |
| 140 return false; |
| 141 } |
| 142 |
| 143 /* |
| 134 * For indirect branch instructions, returns the register being moved into | 144 * For indirect branch instructions, returns the register being moved into |
| 135 * r15. Otherwise, reports kRegisterNone. | 145 * r15. Otherwise, reports kRegisterNone. |
| 136 * | 146 * |
| 137 * Note that this exclusively describes instructions that write r15 from a | 147 * Note that this exclusively describes instructions that write r15 from a |
| 138 * register, unmodified. This means BX, BLX, and MOV without shift. Not | 148 * register, unmodified. This means BX, BLX, and MOV without shift. Not |
| 139 * even BIC, which we allow to write to r15, is modeled this way. | 149 * even BIC, which we allow to write to r15, is modeled this way. |
| 140 */ | 150 */ |
| 141 virtual Register branch_target_register(Instruction i) const { | 151 virtual Register branch_target_register(Instruction i) const { |
| 142 UNREFERENCED_PARAMETER(i); | 152 UNREFERENCED_PARAMETER(i); |
| 143 return kRegisterNone; | 153 return kRegisterNone; |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 * Loads using a register displacement, which may affect Rt (the destination) | 562 * Loads using a register displacement, which may affect Rt (the destination) |
| 553 * and Rn (the base address, if writeback is used). | 563 * and Rn (the base address, if writeback is used). |
| 554 * | 564 * |
| 555 * Notice we do not care about the width of the loaded value, because it doesn't | 565 * Notice we do not care about the width of the loaded value, because it doesn't |
| 556 * affect addressing. | 566 * affect addressing. |
| 557 */ | 567 */ |
| 558 class LoadRegister : public AbstractLoad { | 568 class LoadRegister : public AbstractLoad { |
| 559 public: | 569 public: |
| 560 virtual ~LoadRegister() {} | 570 virtual ~LoadRegister() {} |
| 561 | 571 |
| 572 virtual SafetyLevel safety(Instruction i) const; |
| 562 virtual RegisterList defs(Instruction i) const; | 573 virtual RegisterList defs(Instruction i) const; |
| 574 virtual Register base_address_register(Instruction i) const; |
| 563 }; | 575 }; |
| 564 | 576 |
| 565 /* | 577 /* |
| 566 * Loads using an immediate displacement, which may affect Rt (the destination) | 578 * Loads using an immediate displacement, which may affect Rt (the destination) |
| 567 * and Rn (the base address, if writeback is used). | 579 * and Rn (the base address, if writeback is used). |
| 568 * | 580 * |
| 569 * Notice we do not care about the width of the loaded value, because it doesn't | 581 * Notice we do not care about the width of the loaded value, because it doesn't |
| 570 * affect addressing. | 582 * affect addressing. |
| 571 */ | 583 */ |
| 572 class LoadImmediate : public AbstractLoad { | 584 class LoadImmediate : public AbstractLoad { |
| 573 public: | 585 public: |
| 574 virtual ~LoadImmediate() {} | 586 virtual ~LoadImmediate() {} |
| 575 | 587 |
| 576 virtual RegisterList immediate_addressing_defs(Instruction i) const; | 588 virtual RegisterList immediate_addressing_defs(Instruction i) const; |
| 589 virtual Register base_address_register(Instruction i) const; |
| 590 virtual bool offset_is_immediate(Instruction i) const; |
| 577 }; | 591 }; |
| 578 | 592 |
| 579 /* | 593 /* |
| 580 * Two-register immediate-offset load, which also writes Rt+1. | 594 * Two-register immediate-offset load, which also writes Rt+1. |
| 581 */ | 595 */ |
| 582 class LoadDoubleI : public LoadImmediate { | 596 class LoadDoubleI : public LoadImmediate { |
| 583 public: | 597 public: |
| 584 virtual ~LoadDoubleI() {} | 598 virtual ~LoadDoubleI() {} |
| 585 | 599 |
| 586 virtual RegisterList defs(Instruction i) const; | 600 virtual RegisterList defs(Instruction i) const; |
| 601 virtual Register base_address_register(Instruction i) const; |
| 602 virtual bool offset_is_immediate(Instruction i) const; |
| 587 }; | 603 }; |
| 588 | 604 |
| 589 /* | 605 /* |
| 590 * Two-register register-offset load, which also writes Rt+1. | 606 * Two-register register-offset load, which also writes Rt+1. |
| 591 */ | 607 */ |
| 592 class LoadDoubleR : public LoadRegister { | 608 class LoadDoubleR : public LoadRegister { |
| 593 public: | 609 public: |
| 594 virtual ~LoadDoubleR() {} | 610 virtual ~LoadDoubleR() {} |
| 595 | 611 |
| 612 virtual SafetyLevel safety(Instruction i) const; |
| 596 virtual RegisterList defs(Instruction i) const; | 613 virtual RegisterList defs(Instruction i) const; |
| 614 virtual Register base_address_register(Instruction i) const; |
| 597 }; | 615 }; |
| 598 | 616 |
| 599 /* | 617 /* |
| 600 * LDREX and friends, where writeback is unavailable. | 618 * LDREX and friends, where writeback is unavailable. |
| 601 */ | 619 */ |
| 602 class LoadExclusive : public AbstractLoad { | 620 class LoadExclusive : public AbstractLoad { |
| 603 public: | 621 public: |
| 604 virtual ~LoadExclusive() {} | 622 virtual ~LoadExclusive() {} |
| 623 virtual Register base_address_register(Instruction i) const; |
| 605 }; | 624 }; |
| 606 | 625 |
| 607 /* | 626 /* |
| 608 * LDREXD, which also writes Rt+1. | 627 * LDREXD, which also writes Rt+1. |
| 609 */ | 628 */ |
| 610 class LoadDoubleExclusive : public LoadExclusive { | 629 class LoadDoubleExclusive : public LoadExclusive { |
| 611 public: | 630 public: |
| 612 virtual ~LoadDoubleExclusive() {} | 631 virtual ~LoadDoubleExclusive() {} |
| 613 | 632 |
| 614 virtual RegisterList defs(Instruction i) const; | 633 virtual RegisterList defs(Instruction i) const; |
| 634 virtual Register base_address_register(Instruction i) const; |
| 615 }; | 635 }; |
| 616 | 636 |
| 617 /* | 637 /* |
| 618 * And, finally, the oddest class of loads: LDM. In addition to the base | 638 * And, finally, the oddest class of loads: LDM. In addition to the base |
| 619 * register, this may write every other register, subject to a bitmask. | 639 * register, this may write every other register, subject to a bitmask. |
| 620 */ | 640 */ |
| 621 class LoadMultiple : public ClassDecoder { | 641 class LoadMultiple : public ClassDecoder { |
| 622 public: | 642 public: |
| 623 virtual ~LoadMultiple() {} | 643 virtual ~LoadMultiple() {} |
| 624 | 644 |
| 625 virtual SafetyLevel safety(Instruction i) const; | 645 virtual SafetyLevel safety(Instruction i) const; |
| 626 virtual RegisterList defs(Instruction i) const; | 646 virtual RegisterList defs(Instruction i) const; |
| 627 virtual RegisterList immediate_addressing_defs(Instruction i) const; | 647 virtual RegisterList immediate_addressing_defs(Instruction i) const; |
| 648 virtual Register base_address_register(Instruction i) const; |
| 628 }; | 649 }; |
| 629 | 650 |
| 630 /* | 651 /* |
| 631 * A load to a vector register. Like LoadCoprocessor below, the only visible | 652 * A load to a vector register. Like LoadCoprocessor below, the only visible |
| 632 * side effect is from writeback. | 653 * side effect is from writeback. |
| 633 */ | 654 */ |
| 634 class VectorLoad : public ClassDecoder { | 655 class VectorLoad : public ClassDecoder { |
| 635 public: | 656 public: |
| 636 virtual ~VectorLoad() {} | 657 virtual ~VectorLoad() {} |
| 637 | 658 |
| 638 virtual SafetyLevel safety(Instruction i) const; | 659 virtual SafetyLevel safety(Instruction i) const; |
| 639 virtual RegisterList defs(Instruction i) const; | 660 virtual RegisterList defs(Instruction i) const; |
| 640 virtual RegisterList immediate_addressing_defs(Instruction i) const; | 661 virtual RegisterList immediate_addressing_defs(Instruction i) const; |
| 662 virtual Register base_address_register(Instruction i) const; |
| 641 }; | 663 }; |
| 642 | 664 |
| 643 /* | 665 /* |
| 644 * A store from a vector register. | 666 * A store from a vector register. |
| 645 */ | 667 */ |
| 646 class VectorStore : public ClassDecoder { | 668 class VectorStore : public ClassDecoder { |
| 647 public: | 669 public: |
| 648 virtual ~VectorStore() {} | 670 virtual ~VectorStore() {} |
| 649 | 671 |
| 650 virtual SafetyLevel safety(Instruction i) const; | 672 virtual SafetyLevel safety(Instruction i) const; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 virtual bool is_relative_branch(Instruction i) const { | 786 virtual bool is_relative_branch(Instruction i) const { |
| 765 UNREFERENCED_PARAMETER(i); | 787 UNREFERENCED_PARAMETER(i); |
| 766 return true; | 788 return true; |
| 767 } | 789 } |
| 768 virtual int32_t branch_target_offset(Instruction i) const; | 790 virtual int32_t branch_target_offset(Instruction i) const; |
| 769 }; | 791 }; |
| 770 | 792 |
| 771 } // namespace | 793 } // namespace |
| 772 | 794 |
| 773 #endif // NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_INST_CLASSES_H | 795 #endif // NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_INST_CLASSES_H |
| OLD | NEW |