Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: src/trusted/validator_arm/baseline_classes.cc

Issue 10879090: ARM validator: continue with extra_load_store_instructions. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: "Update test_sp_updates.S and related .nexe and .err files: they were relying on UNDEFINED behavior… Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2012 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 #include "native_client/src/trusted/validator_arm/baseline_classes.h" 7 #include "native_client/src/trusted/validator_arm/baseline_classes.h"
8 8
9 #include <assert.h> 9 #include <assert.h>
10 #include <string.h> 10 #include <string.h>
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 bool BranchImmediate24::is_relative_branch(Instruction i) const { 75 bool BranchImmediate24::is_relative_branch(Instruction i) const {
76 UNREFERENCED_PARAMETER(i); 76 UNREFERENCED_PARAMETER(i);
77 return true; 77 return true;
78 } 78 }
79 79
80 int32_t BranchImmediate24::branch_target_offset(Instruction i) const { 80 int32_t BranchImmediate24::branch_target_offset(Instruction i) const {
81 return imm24.relative_address(i); 81 return imm24.relative_address(i);
82 } 82 }
83 83
84 // BreakPointAndConstantPoolHead 84 // BreakPointAndConstantPoolHead
85 SafetyLevel BreakPointAndConstantPoolHead::safety(const Instruction i) const {
86 return i.GetCondition() == Instruction::AL
87 ? MAY_BE_SAFE
88 : UNPREDICTABLE;
89 }
90
85 bool BreakPointAndConstantPoolHead:: 91 bool BreakPointAndConstantPoolHead::
86 is_literal_pool_head(const Instruction i) const { 92 is_literal_pool_head(const Instruction i) const {
87 return i.GetCondition() == Instruction::AL && 93 return i.GetCondition() == Instruction::AL &&
88 value(i) == 0x7777; 94 value(i) == 0x7777;
89 } 95 }
90 96
91 // BranchToRegister 97 // BranchToRegister
92 SafetyLevel BranchToRegister::safety(const Instruction i) const { 98 SafetyLevel BranchToRegister::safety(const Instruction i) const {
99 // Extra NaCl constraint: can't branch to PC. This would branch to 8 bytes
100 // after the current instruction. This instruction should be in an instruction
101 // pair, the mask should therefore be to PC and fail checking, but there's
102 // little harm in checking.
103 if (m.reg(i).Equals(kRegisterPc)) return FORBIDDEN_OPERANDS;
104
105 // Redundant with the above, but this is actually UNPREDICTABLE. Expect DCE.
93 if (link_register.IsUpdated(i) && m.reg(i).Equals(kRegisterPc)) { 106 if (link_register.IsUpdated(i) && m.reg(i).Equals(kRegisterPc)) {
94 return UNPREDICTABLE; 107 return UNPREDICTABLE;
95 } 108 }
96 109
97 return MAY_BE_SAFE; 110 return MAY_BE_SAFE;
98 } 111 }
99 112
100 RegisterList BranchToRegister::defs(const Instruction i) const { 113 RegisterList BranchToRegister::defs(const Instruction i) const {
101 return RegisterList(kRegisterPc). 114 return RegisterList(kRegisterPc).
102 Add(link_register.IsUpdated(i) ? kRegisterLink : kRegisterNone); 115 Add(link_register.IsUpdated(i) ? kRegisterLink : kRegisterNone);
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 return UNPREDICTABLE; 363 return UNPREDICTABLE;
351 } 364 }
352 365
353 if (HasWriteBack(i) && 366 if (HasWriteBack(i) &&
354 (n.reg(i).Equals(kRegisterPc) || 367 (n.reg(i).Equals(kRegisterPc) ||
355 // NOTE: The manual states that that it is also unpredictable 368 // NOTE: The manual states that that it is also unpredictable
356 // when HasWriteBack(i) and Rn=Rt. However, the compilers 369 // when HasWriteBack(i) and Rn=Rt. However, the compilers
357 // may not check for this. For the moment, we are changing 370 // may not check for this. For the moment, we are changing
358 // the code to ignore this case for stores. 371 // the code to ignore this case for stores.
359 // TODO(karl): Should we not allow this? 372 // TODO(karl): Should we not allow this?
373 // TODO(jfb) Fix this.
360 (is_load_ && n.reg(i).Equals(t.reg(i))))) { 374 (is_load_ && n.reg(i).Equals(t.reg(i))))) {
361 return UNPREDICTABLE; 375 return UNPREDICTABLE;
362 } 376 }
363 377
364 // Above implies literal loads can't writeback, the following checks the 378 // Above implies literal loads can't writeback, the following checks the
365 // ARM restriction that literal loads can't have P == W. 379 // ARM restriction that literal loads can't have P == W.
366 // This should always decode to another instruction, but checking it is good. 380 // This should always decode to another instruction, but checking it is good.
367 if (n.reg(i).Equals(kRegisterPc) && 381 if (n.reg(i).Equals(kRegisterPc) &&
368 (indexing.IsDefined(i) == writes.IsDefined(i))) { 382 (indexing.IsDefined(i) == writes.IsDefined(i))) {
369 return UNPREDICTABLE; 383 return UNPREDICTABLE;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 // LoadStore2RegisterImm12Op 457 // LoadStore2RegisterImm12Op
444 SafetyLevel LoadStore2RegisterImm12Op::safety(const Instruction i) const { 458 SafetyLevel LoadStore2RegisterImm12Op::safety(const Instruction i) const {
445 // Arm restrictions for this instruction. 459 // Arm restrictions for this instruction.
446 if (HasWriteBack(i) && 460 if (HasWriteBack(i) &&
447 (n.reg(i).Equals(kRegisterPc) || 461 (n.reg(i).Equals(kRegisterPc) ||
448 // NOTE: The manual states that that it is also unpredictable 462 // NOTE: The manual states that that it is also unpredictable
449 // when HasWriteBack(i) and Rn=Rt. However, the compilers 463 // when HasWriteBack(i) and Rn=Rt. However, the compilers
450 // may not check for this. For the moment, we are changing 464 // may not check for this. For the moment, we are changing
451 // the code to ignore this case for stores. 465 // the code to ignore this case for stores.
452 // TODO(karl): Should we not allow this? 466 // TODO(karl): Should we not allow this?
467 // TODO(jfb) Fix this. Once this is fixed,
468 // Store2RegisterImm12OpRnNotRtOnWriteback becomes redundant
469 // with this class and can be removed.
453 (is_load_ && n.reg(i).Equals(t.reg(i))))) { 470 (is_load_ && n.reg(i).Equals(t.reg(i))))) {
454 return UNPREDICTABLE; 471 return UNPREDICTABLE;
455 } 472 }
456 473
457 // Don't allow modification of PC (NaCl constraint). 474 // Don't allow modification of PC (NaCl constraint).
458 if (defs(i).Contains(kRegisterPc)) return FORBIDDEN_OPERANDS; 475 if (defs(i).Contains(kRegisterPc)) return FORBIDDEN_OPERANDS;
459 476
460 // NaCl special restriction to make all load/store immediates behave 477 // NaCl special restriction to make all load/store immediates behave
461 // the same. 478 // the same.
462 if (t.reg(i).Equals(kRegisterPc)) { 479 if (t.reg(i).Equals(kRegisterPc)) {
(...skipping 24 matching lines...) Expand all
487 } 504 }
488 505
489 // Store2RegisterImm12Op 506 // Store2RegisterImm12Op
490 RegisterList Store2RegisterImm12Op::defs(Instruction i) const { 507 RegisterList Store2RegisterImm12Op::defs(Instruction i) const {
491 return immediate_addressing_defs(i); 508 return immediate_addressing_defs(i);
492 } 509 }
493 510
494 // Store2RegisterImm12OpRnNotRtOnWriteback 511 // Store2RegisterImm12OpRnNotRtOnWriteback
495 SafetyLevel Store2RegisterImm12OpRnNotRtOnWriteback:: 512 SafetyLevel Store2RegisterImm12OpRnNotRtOnWriteback::
496 safety(Instruction i) const { 513 safety(Instruction i) const {
514 // TODO(jfb) Redundant with LoadStore2RegisterImm12Op, once it is fixed.
497 if (HasWriteBack(i) && (n.reg(i).Equals(t.reg(i)))) 515 if (HasWriteBack(i) && (n.reg(i).Equals(t.reg(i))))
498 return UNPREDICTABLE; 516 return UNPREDICTABLE;
499 return Store2RegisterImm12Op::safety(i); 517 return Store2RegisterImm12Op::safety(i);
500 } 518 }
501 519
502 // LoadStoreRegisterList 520 // LoadStoreRegisterList
503 SafetyLevel LoadStoreRegisterList::safety(const Instruction i) const { 521 SafetyLevel LoadStoreRegisterList::safety(const Instruction i) const {
504 if (n.reg(i).Equals(kRegisterPc) || (register_list.value(i) == 0)) { 522 if (n.reg(i).Equals(kRegisterPc) || (register_list.value(i) == 0)) {
505 return UNPREDICTABLE; 523 return UNPREDICTABLE;
506 } 524 }
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 return UNPREDICTABLE; 676 return UNPREDICTABLE;
659 } 677 }
660 678
661 if (HasWriteBack(i) && 679 if (HasWriteBack(i) &&
662 (n.reg(i).Equals(kRegisterPc) || 680 (n.reg(i).Equals(kRegisterPc) ||
663 // NOTE: The manual states that that it is also unpredictable 681 // NOTE: The manual states that that it is also unpredictable
664 // when HasWriteBack(i) and Rn=Rt. However, the compilers 682 // when HasWriteBack(i) and Rn=Rt. However, the compilers
665 // may not check for this. For the moment, we are changing 683 // may not check for this. For the moment, we are changing
666 // the code to ignore this case for stores. 684 // the code to ignore this case for stores.
667 // TODO(karl): Should we not allow this? 685 // TODO(karl): Should we not allow this?
686 // TODO(jfb) Fix this.
668 (is_load_ && n.reg(i).Equals(t.reg(i))))) { 687 (is_load_ && n.reg(i).Equals(t.reg(i))))) {
669 return UNPREDICTABLE; 688 return UNPREDICTABLE;
670 } 689 }
671 690
691 // TODO(jfb) if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
692
672 // Don't let addressing writeback alter PC (NaCl constraint). 693 // Don't let addressing writeback alter PC (NaCl constraint).
673 if (defs(i).Contains(kRegisterPc)) return FORBIDDEN_OPERANDS; 694 if (defs(i).Contains(kRegisterPc)) return FORBIDDEN_OPERANDS;
674 695
675 return MAY_BE_SAFE; 696 return MAY_BE_SAFE;
676 } 697 }
677 698
678 Register LoadStore3RegisterOp::base_address_register( 699 Register LoadStore3RegisterOp::base_address_register(
679 const Instruction i) const { 700 const Instruction i) const {
680 return n.reg(i); 701 return n.reg(i);
681 } 702 }
(...skipping 25 matching lines...) Expand all
707 728
708 if (RegisterList(t2.reg(i)).Add(m.reg(i)).Contains(kRegisterPc)) { 729 if (RegisterList(t2.reg(i)).Add(m.reg(i)).Contains(kRegisterPc)) {
709 return UNPREDICTABLE; 730 return UNPREDICTABLE;
710 } 731 }
711 732
712 // NOTE: The manual states that that it is also unpredictable 733 // NOTE: The manual states that that it is also unpredictable
713 // when HasWriteBack(i) and Rn=Rt2. However, the compilers 734 // when HasWriteBack(i) and Rn=Rt2. However, the compilers
714 // may not check for this. For the moment, we are changing 735 // may not check for this. For the moment, we are changing
715 // the code to ignore this case for stores. 736 // the code to ignore this case for stores.
716 // TODO(karl): Should we not allow this? 737 // TODO(karl): Should we not allow this?
738 // TODO(jfb) Fix this.
717 if (is_load_ && HasWriteBack(i) && n.reg(i).Equals(t2.reg(i))) { 739 if (is_load_ && HasWriteBack(i) && n.reg(i).Equals(t2.reg(i))) {
718 return UNPREDICTABLE; 740 return UNPREDICTABLE;
719 } 741 }
720 742
743 if (is_load_ && (m.reg(i).Equals(t.reg(i)) || m.reg(i).Equals(t2.reg(i)))) {
744 return UNPREDICTABLE;
745 }
746
721 // Now apply non-double width restrictions for this instruction. 747 // Now apply non-double width restrictions for this instruction.
722 return LoadStore3RegisterOp::safety(i); 748 return LoadStore3RegisterOp::safety(i);
723 } 749 }
724 750
725 // StoreExclusive3RegisterOp 751 // StoreExclusive3RegisterOp
726 SafetyLevel StoreExclusive3RegisterOp::safety(const Instruction i) const { 752 SafetyLevel StoreExclusive3RegisterOp::safety(const Instruction i) const {
727 // Arm restrictions for this instruction. 753 // Arm restrictions for this instruction.
728 if (RegisterList(d.reg(i)).Add(t.reg(i)).Add(n.reg(i)). 754 if (RegisterList(d.reg(i)).Add(t.reg(i)).Add(n.reg(i)).
729 Contains(kRegisterPc)) { 755 Contains(kRegisterPc)) {
730 return UNPREDICTABLE; 756 return UNPREDICTABLE;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 return UNPREDICTABLE; 827 return UNPREDICTABLE;
802 } 828 }
803 829
804 if (HasWriteBack(i) && 830 if (HasWriteBack(i) &&
805 (n.reg(i).Equals(kRegisterPc) || 831 (n.reg(i).Equals(kRegisterPc) ||
806 // NOTE: The manual states that that it is also unpredictable 832 // NOTE: The manual states that that it is also unpredictable
807 // when HasWriteBack(i) and Rn=Rt2. However, the compilers 833 // when HasWriteBack(i) and Rn=Rt2. However, the compilers
808 // may not check for this. For the moment, we are changing 834 // may not check for this. For the moment, we are changing
809 // the code to ignore this case for stores. 835 // the code to ignore this case for stores.
810 // TODO(karl): Should we not allow this? 836 // TODO(karl): Should we not allow this?
837 // TODO(jfb) Fix this.
811 (is_load_ && n.reg(i).Equals(t.reg(i))))) { 838 (is_load_ && n.reg(i).Equals(t.reg(i))))) {
812 return UNPREDICTABLE; 839 return UNPREDICTABLE;
813 } 840 }
814 841
815 // Don't let Rt be Pc (NaCl constraint -- See header file for special 842 // Don't let Rt be Pc (NaCl constraint -- See header file for special
816 // note). 843 // note).
817 if (t.reg(i).Equals(kRegisterPc)) { 844 if (t.reg(i).Equals(kRegisterPc)) {
818 return FORBIDDEN_OPERANDS; 845 return FORBIDDEN_OPERANDS;
819 } 846 }
820 847
821 // Don't let addressing writeback alter PC (NaCl constraint). 848 // Don't let addressing writeback alter PC (NaCl constraint).
822 if (defs(i).Contains(kRegisterPc)) return FORBIDDEN_OPERANDS; 849 if (defs(i).Contains(kRegisterPc)) return FORBIDDEN_OPERANDS;
823 850
851 // TODO(jfb) if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
852
824 return MAY_BE_SAFE; 853 return MAY_BE_SAFE;
825 } 854 }
826 855
827 Register LoadStore3RegisterImm5Op::base_address_register( 856 Register LoadStore3RegisterImm5Op::base_address_register(
828 const Instruction i) const { 857 const Instruction i) const {
829 return n.reg(i); 858 return n.reg(i);
830 } 859 }
831 860
832 // Load3RegisterImm5Op 861 // Load3RegisterImm5Op
833 RegisterList Load3RegisterImm5Op::defs(const Instruction i) const { 862 RegisterList Load3RegisterImm5Op::defs(const Instruction i) const {
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 if (be_value(i) == 0x3) 1078 if (be_value(i) == 0x3)
1050 return UNDEFINED; 1079 return UNDEFINED;
1051 1080
1052 if (t.reg(i).Equals(kRegisterPc)) 1081 if (t.reg(i).Equals(kRegisterPc))
1053 return UNPREDICTABLE; 1082 return UNPREDICTABLE;
1054 1083
1055 return CondVfpOp::safety(i); 1084 return CondVfpOp::safety(i);
1056 } 1085 }
1057 1086
1058 } // namespace nacl_arm_dec 1087 } // namespace nacl_arm_dec
OLDNEW
« no previous file with comments | « src/trusted/validator_arm/baseline_classes.h ('k') | src/trusted/validator_arm/gen/arm32_decode.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698