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" |
| 13 // TODO(mrm) Remove this with debugging lines |
| 14 #include <stdio.h> |
| 15 #include <assert.h> |
13 | 16 |
14 /* | 17 /* |
15 * Models the "instruction classes" that the decoder produces. | 18 * Models the "instruction classes" that the decoder produces. |
16 */ | 19 */ |
17 namespace nacl_arm_dec { | 20 namespace nacl_arm_dec { |
18 | 21 |
19 /* | 22 /* |
| 23 * Describes whether an operation is safe to have during an IT. |
| 24 */ |
| 25 enum ITSafety { |
| 26 // Safe to use in an IT block |
| 27 ALWAYS, |
| 28 // Unsafe to use in an IT block |
| 29 NEVER, |
| 30 // Can only go at the end of an IT block |
| 31 END |
| 32 }; |
| 33 |
| 34 /* |
| 35 * Describes what mode an instruction governed under an IT is in. |
| 36 * THEN means condition must match, ELSE means condition must not match, |
| 37 * NONE means this is the end of IT control flow. |
| 38 */ |
| 39 enum ITMode { |
| 40 // No condition. There should be no Thens or Elses after this |
| 41 NONE = 0, |
| 42 // Matches condition |
| 43 THEN = 1, |
| 44 // Does not match condition |
| 45 ELSE = 2 |
| 46 }; |
| 47 |
| 48 /* |
| 49 * Used to store the full it conditional. This should fit in a byte, and so is |
| 50 * used instead of an array. It is a bitpacked size 4 array of 2 bit values. |
| 51 */ |
| 52 typedef uint32_t ITCond; |
| 53 inline ITMode it_select(uint32_t index, ITCond cond) { |
| 54 assert(index < 4); |
| 55 return (ITMode)((cond >> (2 * index)) & 0x3); |
| 56 } |
| 57 |
| 58 /* |
| 59 * In an if-then block, the instruction sequence can be predicated |
| 60 * COND or !COND (undef if COND==ALWAYS) |
| 61 * !COND is expressed same as COND but with the LSB inverted |
| 62 * See pages A8-8 and A8-104 for the exact encoding |
| 63 */ |
| 64 inline ITCond it_set(uint32_t index, ITMode mode, ITCond cond) { |
| 65 assert(index < 4); |
| 66 return (mode << (2 * index)) | (cond & (~(0x3 << (2 * index)))); |
| 67 } |
| 68 |
| 69 /* |
20 * Used to describe whether an instruction is safe, and if not, what the issue | 70 * Used to describe whether an instruction is safe, and if not, what the issue |
21 * is. Only instructions that MAY_BE_SAFE should be allowed in untrusted code, | 71 * is. Only instructions that MAY_BE_SAFE should be allowed in untrusted code, |
22 * and even those may be rejected by the validator. | 72 * and even those may be rejected by the validator. |
23 */ | 73 */ |
24 enum SafetyLevel { | 74 enum SafetyLevel { |
25 // The initial value of uninitialized SafetyLevels -- treat as unsafe. | 75 // The initial value of uninitialized SafetyLevels -- treat as unsafe. |
26 UNKNOWN = 0, | 76 UNKNOWN = 0, |
27 | 77 |
28 // This instruction is left undefined by the ARMv7 ISA spec. | 78 // This instruction is left undefined by the ARMv7 ISA spec. |
29 UNDEFINED, | 79 UNDEFINED, |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 /* | 219 /* |
170 * Checks whether this instruction is the special bit sequence that marks | 220 * Checks whether this instruction is the special bit sequence that marks |
171 * the start of a literal pool. | 221 * the start of a literal pool. |
172 */ | 222 */ |
173 virtual bool is_literal_pool_head(Instruction i) const { | 223 virtual bool is_literal_pool_head(Instruction i) const { |
174 UNREFERENCED_PARAMETER(i); | 224 UNREFERENCED_PARAMETER(i); |
175 return false; | 225 return false; |
176 } | 226 } |
177 | 227 |
178 /* | 228 /* |
| 229 * Checks that an instruction sets a certain pattern of bits in all its |
| 230 * (non-flag) result registers. The mask should include 1s in the positions |
| 231 * that should be set. Unlike clears_bits, which may clear a superset of these |
| 232 * bits, sets_bits must set PRECISELY the bits in mask. |
| 233 */ |
| 234 virtual bool sets_bits(Instruction i, uint32_t mask) const { |
| 235 UNREFERENCED_PARAMETER(i); |
| 236 UNREFERENCED_PARAMETER(mask); |
| 237 return false; |
| 238 } |
| 239 |
| 240 /* |
179 * Checks that an instruction clears a certain pattern of bits in all its | 241 * Checks that an instruction clears a certain pattern of bits in all its |
180 * (non-flag) result registers. The mask should include 1s in the positions | 242 * (non-flag) result registers. The mask should include 1s in the positions |
181 * that should be cleared. | 243 * that should be cleared. |
182 */ | 244 */ |
183 virtual bool clears_bits(Instruction i, uint32_t mask) const { | 245 virtual bool clears_bits(Instruction i, uint32_t mask) const { |
184 UNREFERENCED_PARAMETER(i); | 246 UNREFERENCED_PARAMETER(i); |
185 UNREFERENCED_PARAMETER(mask); | 247 UNREFERENCED_PARAMETER(mask); |
186 return false; | 248 return false; |
187 } | 249 } |
188 | 250 |
189 /* | 251 /* |
190 * Checks that an instruction will set Z if certain bits in r (chosen by 1s in | 252 * Checks that an instruction will set Z if certain bits in r (chosen by 1s in |
191 * the mask) are clear. | 253 * the mask) are clear. |
192 * | 254 * |
193 * Note that the inverse does not hold: the actual instruction i may require | 255 * Note that the inverse does not hold: the actual instruction i may require |
194 * *more* bits to be clear to set Z. This is fine. | 256 * *more* bits to be clear to set Z. This is fine. |
195 */ | 257 */ |
196 virtual bool sets_Z_if_bits_clear(Instruction i, | 258 virtual bool sets_Z_if_bits_clear(Instruction i, |
197 Register r, | 259 Register r, |
198 uint32_t mask) const { | 260 uint32_t mask) const { |
199 UNREFERENCED_PARAMETER(i); | 261 UNREFERENCED_PARAMETER(i); |
200 UNREFERENCED_PARAMETER(r); | 262 UNREFERENCED_PARAMETER(r); |
201 UNREFERENCED_PARAMETER(mask); | 263 UNREFERENCED_PARAMETER(mask); |
202 return false; | 264 return false; |
203 } | 265 } |
204 | 266 |
| 267 /* |
| 268 * Generates the appropriate it condition set for this instruction. |
| 269 * All entries after a NONE is hit should be zero. |
| 270 * Default return is that no IT is in effect. |
| 271 * There are exactly 4 entries, encoded as a bitpacked 2-bit element array. |
| 272 */ |
| 273 virtual ITCond it_sequence(Instruction i) const { |
| 274 UNREFERENCED_PARAMETER(i); |
| 275 return 0; |
| 276 } |
| 277 |
| 278 /* |
| 279 * Determines under what conditions an instruction is safe to have in an IT |
| 280 * block for CPU sanity. Usually, most instructions are. |
| 281 */ |
| 282 virtual ITSafety it_safe(Instruction i) const { |
| 283 UNREFERENCED_PARAMETER(i); |
| 284 return ALWAYS; |
| 285 } |
| 286 |
| 287 /* |
| 288 * Calculate the condition code. This used to be done by Instruction, |
| 289 * but Thumb has some special cases, so we hook here for potential override. |
| 290 */ |
| 291 virtual Instruction::Condition condition(Instruction i) const { |
| 292 return i.condition(); |
| 293 } |
| 294 |
205 protected: | 295 protected: |
206 ClassDecoder() {} | 296 ClassDecoder() {} |
207 virtual ~ClassDecoder() {} | 297 virtual ~ClassDecoder() {} |
208 }; | 298 }; |
209 | 299 |
210 /* | 300 /* |
| 301 * Base class for thumb decoders, has different default behavior for conditions |
| 302 */ |
| 303 class ClassDecoderT : public ClassDecoder { |
| 304 public: |
| 305 virtual ~ClassDecoderT() {} |
| 306 virtual Instruction::Condition condition(Instruction i) const { |
| 307 UNREFERENCED_PARAMETER(i); |
| 308 return Instruction::UNCONDITIONAL; |
| 309 } |
| 310 }; |
| 311 |
| 312 /* |
211 * Represents an instruction that is forbidden under all circumstances, so we | 313 * Represents an instruction that is forbidden under all circumstances, so we |
212 * didn't bother decoding it further. | 314 * didn't bother decoding it further. |
213 */ | 315 */ |
214 class Forbidden : public ClassDecoder { | 316 class Forbidden : public ClassDecoder { |
215 public: | 317 public: |
216 virtual ~Forbidden() {} | 318 virtual ~Forbidden() {} |
217 | 319 |
218 virtual SafetyLevel safety(Instruction i) const { | 320 virtual SafetyLevel safety(Instruction i) const { |
219 UNREFERENCED_PARAMETER(i); | 321 UNREFERENCED_PARAMETER(i); |
220 return FORBIDDEN; | 322 return FORBIDDEN; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 * code isn't expected to use it, but it's not unsafe, and there are cases where | 431 * code isn't expected to use it, but it's not unsafe, and there are cases where |
330 * we may generate it. | 432 * we may generate it. |
331 */ | 433 */ |
332 class Breakpoint : public Roadblock { | 434 class Breakpoint : public Roadblock { |
333 public: | 435 public: |
334 virtual ~Breakpoint() {} | 436 virtual ~Breakpoint() {} |
335 | 437 |
336 virtual bool is_literal_pool_head(Instruction i) const; | 438 virtual bool is_literal_pool_head(Instruction i) const; |
337 }; | 439 }; |
338 | 440 |
| 441 class ThumbBreakpoint : public Breakpoint { |
| 442 public: |
| 443 virtual ~ThumbBreakpoint() {} |
| 444 |
| 445 virtual bool is_literal_pool_head(Instruction i) const; |
| 446 }; |
| 447 |
| 448 |
339 /* | 449 /* |
340 * Models the most common class of data processing instructions. We use this | 450 * Models the most common class of data processing instructions. We use this |
341 * for any operation that | 451 * for any operation that |
342 * - writes a single register, specified in 15:12; | 452 * - writes a single register, specified in 15:12; |
343 * - does not write memory, | 453 * - does not write memory, |
344 * - should not be permitted to cause a jump by writing r15, | 454 * - should not be permitted to cause a jump by writing r15, |
345 * - writes flags when bit 20 is set. | 455 * - writes flags when bit 20 is set. |
346 */ | 456 */ |
347 class DataProc : public ClassDecoder { | 457 class DataProc : public ClassDecoder { |
348 public: | 458 public: |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 return MAY_BE_SAFE; | 871 return MAY_BE_SAFE; |
762 } | 872 } |
763 virtual RegisterList defs(Instruction i) const; | 873 virtual RegisterList defs(Instruction i) const; |
764 virtual bool is_relative_branch(Instruction i) const { | 874 virtual bool is_relative_branch(Instruction i) const { |
765 UNREFERENCED_PARAMETER(i); | 875 UNREFERENCED_PARAMETER(i); |
766 return true; | 876 return true; |
767 } | 877 } |
768 virtual int32_t branch_target_offset(Instruction i) const; | 878 virtual int32_t branch_target_offset(Instruction i) const; |
769 }; | 879 }; |
770 | 880 |
| 881 /* Thumb Classes */ |
| 882 |
| 883 class Def3 : public ClassDecoderT { |
| 884 public: |
| 885 virtual ~Def3() {} |
| 886 |
| 887 virtual SafetyLevel safety(Instruction i) const; |
| 888 virtual RegisterList defs(Instruction i) const; |
| 889 }; |
| 890 |
| 891 class Def8_10 : public ClassDecoderT { |
| 892 public: |
| 893 virtual ~Def8_10() {} |
| 894 |
| 895 virtual SafetyLevel safety(Instruction i) const; |
| 896 virtual RegisterList defs(Instruction i) const; |
| 897 }; |
| 898 |
| 899 class MemOpThumb : public ClassDecoderT { |
| 900 public: |
| 901 virtual ~MemOpThumb() {} |
| 902 |
| 903 virtual SafetyLevel safety(Instruction i) const; |
| 904 virtual RegisterList defs(Instruction i) const { |
| 905 UNREFERENCED_PARAMETER(i); |
| 906 return kRegisterNone; |
| 907 } |
| 908 |
| 909 virtual Register base_address_register(Instruction i) const; |
| 910 }; |
| 911 |
| 912 class MemOpThumbLoad : public MemOpThumb { |
| 913 public: |
| 914 virtual ~MemOpThumbLoad() {} |
| 915 |
| 916 virtual RegisterList defs(Instruction i) const; |
| 917 }; |
| 918 |
| 919 class MemOpThumbStore : public MemOpThumb { |
| 920 public: |
| 921 virtual ~MemOpThumbStore() {} |
| 922 |
| 923 virtual bool writes_memory(Instruction i) const { |
| 924 UNREFERENCED_PARAMETER(i); |
| 925 return true; |
| 926 } |
| 927 }; |
| 928 |
| 929 class SPMod : public ClassDecoderT { |
| 930 public: |
| 931 virtual ~SPMod() {} |
| 932 virtual SafetyLevel safety(Instruction i) const { |
| 933 UNREFERENCED_PARAMETER(i); |
| 934 return MAY_BE_SAFE; |
| 935 } |
| 936 virtual RegisterList defs(Instruction i) const { |
| 937 UNREFERENCED_PARAMETER(i); |
| 938 return kRegisterStack; |
| 939 } |
| 940 }; |
| 941 |
| 942 // mrm BiC3, OrMask3, Mask3 are dummies atm, and could be replaced by |
| 943 // Def3, its only potential purpose is to allow registerwise |
| 944 // bitmasking, which is not a current feature. |
| 945 class BiC3 : public Def3 { |
| 946 public: |
| 947 virtual ~BiC3() {} |
| 948 }; |
| 949 |
| 950 class Mask3 : public Def3 { |
| 951 public: |
| 952 virtual ~Mask3() {} |
| 953 }; |
| 954 |
| 955 class OrMask3 : public Def3 { |
| 956 public: |
| 957 virtual ~OrMask3() {} |
| 958 }; |
| 959 |
| 960 class Cmp : public ClassDecoderT { |
| 961 public : |
| 962 virtual ~Cmp() {} |
| 963 virtual SafetyLevel safety(Instruction i) const { |
| 964 UNREFERENCED_PARAMETER(i); |
| 965 return MAY_BE_SAFE; |
| 966 } |
| 967 virtual RegisterList defs(Instruction i) const { |
| 968 UNREFERENCED_PARAMETER(i); |
| 969 return kRegisterNone; |
| 970 } |
| 971 // mrm may want logic for cmp sandboxing, but not atm |
| 972 // This would be a superclass for that, not the target class |
| 973 }; |
| 974 |
| 975 class CmpBrZ : public ClassDecoderT { |
| 976 public: |
| 977 virtual ~CmpBrZ() {} |
| 978 virtual SafetyLevel safety(Instruction i) const { |
| 979 UNREFERENCED_PARAMETER(i); |
| 980 return MAY_BE_SAFE; |
| 981 } |
| 982 virtual RegisterList defs(Instruction i) const { |
| 983 UNREFERENCED_PARAMETER(i); |
| 984 return kRegisterPc; |
| 985 } |
| 986 virtual bool is_relative_branch(Instruction i) const { |
| 987 UNREFERENCED_PARAMETER(i); |
| 988 return true; |
| 989 } |
| 990 virtual ITSafety it_safe(Instruction i) const { |
| 991 UNREFERENCED_PARAMETER(i); |
| 992 return NEVER; |
| 993 } |
| 994 virtual int32_t branch_target_offset(Instruction i) const; |
| 995 }; |
| 996 |
| 997 class PushMult : public ClassDecoderT { |
| 998 public: |
| 999 virtual ~PushMult() {} |
| 1000 virtual SafetyLevel safety(Instruction i) const { |
| 1001 UNREFERENCED_PARAMETER(i); |
| 1002 return MAY_BE_SAFE; |
| 1003 } |
| 1004 virtual RegisterList defs(Instruction i) const { |
| 1005 UNREFERENCED_PARAMETER(i); |
| 1006 return kRegisterStack; |
| 1007 } |
| 1008 virtual Register base_address_register(Instruction i) const { |
| 1009 UNREFERENCED_PARAMETER(i); |
| 1010 return kRegisterStack; |
| 1011 } |
| 1012 virtual RegisterList immediate_addressing_defs(Instruction i) const { |
| 1013 return base_address_register(i); |
| 1014 } |
| 1015 virtual bool writes_memory(Instruction i) const { |
| 1016 UNREFERENCED_PARAMETER(i); |
| 1017 return true; |
| 1018 } |
| 1019 }; |
| 1020 |
| 1021 class PopMult : public PushMult { |
| 1022 public: |
| 1023 virtual ~PopMult() {} |
| 1024 virtual RegisterList defs(Instruction i) const; |
| 1025 }; |
| 1026 |
| 1027 class BranchT : public ClassDecoder { |
| 1028 public: |
| 1029 virtual ~BranchT() {} |
| 1030 virtual SafetyLevel safety(Instruction i) const { |
| 1031 UNREFERENCED_PARAMETER(i); |
| 1032 return MAY_BE_SAFE; |
| 1033 } |
| 1034 virtual RegisterList defs(Instruction i) const { |
| 1035 UNREFERENCED_PARAMETER(i); |
| 1036 return kRegisterPc; |
| 1037 } |
| 1038 virtual bool is_relative_branch(Instruction i) const { |
| 1039 UNREFERENCED_PARAMETER(i); |
| 1040 return true; |
| 1041 } |
| 1042 virtual ITSafety it_safe(Instruction i) const { |
| 1043 UNREFERENCED_PARAMETER(i); |
| 1044 return END; |
| 1045 } |
| 1046 }; |
| 1047 |
| 1048 class BranchTCond : public BranchT { |
| 1049 public: |
| 1050 virtual ~BranchTCond() {} |
| 1051 virtual SafetyLevel safety(Instruction i) const; |
| 1052 virtual ITSafety it_safe(Instruction i) const { |
| 1053 UNREFERENCED_PARAMETER(i); |
| 1054 return NEVER; |
| 1055 } |
| 1056 }; |
| 1057 |
| 1058 class BranchT1 : public BranchTCond { |
| 1059 virtual int32_t branch_target_offset(Instruction i) const; |
| 1060 virtual Instruction::Condition condition(Instruction i) const; |
| 1061 }; |
| 1062 |
| 1063 class BranchT2 : public BranchT { |
| 1064 public: |
| 1065 virtual ~BranchT2() {} |
| 1066 virtual int32_t branch_target_offset(Instruction i) const; |
| 1067 }; |
| 1068 |
| 1069 class BranchT3 : public BranchTCond { |
| 1070 public: |
| 1071 virtual ~BranchT3() {} |
| 1072 virtual int32_t branch_target_offset(Instruction i) const; |
| 1073 virtual Instruction::Condition condition(Instruction i) const; |
| 1074 }; |
| 1075 |
| 1076 class BranchT4 : public BranchT { |
| 1077 public: |
| 1078 virtual ~BranchT4() {} |
| 1079 virtual int32_t branch_target_offset(Instruction i) const; |
| 1080 }; |
| 1081 |
| 1082 class STMT1 : public ClassDecoderT { |
| 1083 public: |
| 1084 virtual ~STMT1() {} |
| 1085 virtual SafetyLevel safety(Instruction i) const { |
| 1086 UNREFERENCED_PARAMETER(i); |
| 1087 return MAY_BE_SAFE; |
| 1088 } |
| 1089 virtual RegisterList immediate_addressing_defs(Instruction i) const; |
| 1090 virtual RegisterList defs(Instruction i) const; |
| 1091 virtual Register base_address_register(Instruction i) const; |
| 1092 virtual bool writes_memory(Instruction i) const { |
| 1093 UNREFERENCED_PARAMETER(i); |
| 1094 return true; |
| 1095 } |
| 1096 }; |
| 1097 |
| 1098 class LDMT1 : public STMT1 { |
| 1099 public: |
| 1100 virtual ~LDMT1() {} |
| 1101 virtual RegisterList defs(Instruction i) const; |
| 1102 virtual bool writes_memory(Instruction i) const { |
| 1103 UNREFERENCED_PARAMETER(i); |
| 1104 return false; |
| 1105 } |
| 1106 }; |
| 1107 |
| 1108 class LDRLitT1 : public ClassDecoderT { |
| 1109 public: |
| 1110 virtual ~LDRLitT1() {} |
| 1111 virtual SafetyLevel safety(Instruction i) const { |
| 1112 UNREFERENCED_PARAMETER(i); |
| 1113 return MAY_BE_SAFE; |
| 1114 } |
| 1115 virtual RegisterList defs(Instruction i) const; |
| 1116 }; |
| 1117 |
| 1118 class ADRT1 : public ClassDecoderT { |
| 1119 public: |
| 1120 virtual ~ADRT1() {} |
| 1121 virtual SafetyLevel safety(Instruction i) const { |
| 1122 UNREFERENCED_PARAMETER(i); |
| 1123 return MAY_BE_SAFE; |
| 1124 } |
| 1125 virtual RegisterList defs(Instruction i) const; |
| 1126 }; |
| 1127 |
| 1128 class MemOpSPThumbStore : public ClassDecoderT { |
| 1129 public: |
| 1130 virtual ~MemOpSPThumbStore() {} |
| 1131 virtual SafetyLevel safety(Instruction i) const { |
| 1132 UNREFERENCED_PARAMETER(i); |
| 1133 return MAY_BE_SAFE; |
| 1134 } |
| 1135 virtual bool writes_memory(Instruction i) const { |
| 1136 UNREFERENCED_PARAMETER(i); |
| 1137 return true; |
| 1138 } |
| 1139 virtual RegisterList defs(Instruction i) const { |
| 1140 UNREFERENCED_PARAMETER(i); |
| 1141 return kRegisterNone; |
| 1142 } |
| 1143 virtual Register base_address_register(Instruction i) const { |
| 1144 UNREFERENCED_PARAMETER(i); |
| 1145 return kRegisterStack; |
| 1146 } |
| 1147 }; |
| 1148 |
| 1149 class MemOpSPThumbLoad : public ClassDecoderT { |
| 1150 public: |
| 1151 virtual ~MemOpSPThumbLoad() {} |
| 1152 virtual SafetyLevel safety(Instruction i) const { |
| 1153 UNREFERENCED_PARAMETER(i); |
| 1154 return MAY_BE_SAFE; |
| 1155 } |
| 1156 virtual RegisterList defs(Instruction i) const; |
| 1157 virtual Register base_address_register(Instruction i) const { |
| 1158 UNREFERENCED_PARAMETER(i); |
| 1159 return kRegisterStack; |
| 1160 } |
| 1161 }; |
| 1162 |
| 1163 class DPMImm : public ClassDecoderT { |
| 1164 public: |
| 1165 virtual ~DPMImm() {} |
| 1166 virtual SafetyLevel safety(Instruction i) const { |
| 1167 UNREFERENCED_PARAMETER(i); |
| 1168 return MAY_BE_SAFE; |
| 1169 } |
| 1170 virtual RegisterList defs(Instruction i) const; |
| 1171 }; |
| 1172 |
| 1173 class BicModImmT : public DPMImm { |
| 1174 public: |
| 1175 virtual ~BicModImmT() {} |
| 1176 virtual bool clears_bits(Instruction i, uint32_t mask) const; |
| 1177 }; |
| 1178 |
| 1179 class OrrModImmT : public DPMImm { |
| 1180 public: |
| 1181 virtual ~OrrModImmT() {} |
| 1182 virtual bool sets_bits(Instruction i, uint32_t mask) const; |
| 1183 }; |
| 1184 |
| 1185 class MovT : public Def3 { |
| 1186 public: |
| 1187 virtual ~MovT() {} |
| 1188 virtual RegisterList defs(Instruction i) const; |
| 1189 }; |
| 1190 |
| 1191 class BXT : public ClassDecoderT { |
| 1192 public: |
| 1193 virtual ~BXT() {} |
| 1194 virtual SafetyLevel safety(Instruction i) const { |
| 1195 UNREFERENCED_PARAMETER(i); |
| 1196 return MAY_BE_SAFE; |
| 1197 } |
| 1198 virtual RegisterList defs(Instruction i) const { |
| 1199 UNREFERENCED_PARAMETER(i); |
| 1200 return kRegisterPc; |
| 1201 } |
| 1202 Register branch_target_register(Instruction i) const; |
| 1203 virtual ITSafety it_safe(Instruction i) const { |
| 1204 UNREFERENCED_PARAMETER(i); |
| 1205 return END; |
| 1206 } |
| 1207 }; |
| 1208 |
| 1209 class BLXT : public BXT { |
| 1210 public: |
| 1211 virtual ~BLXT() {} |
| 1212 virtual RegisterList defs(Instruction i) const { |
| 1213 UNREFERENCED_PARAMETER(i); |
| 1214 return kRegisterPc + kRegisterLink; |
| 1215 } |
| 1216 }; |
| 1217 |
| 1218 class BLT : public ClassDecoderT { |
| 1219 public: |
| 1220 virtual ~BLT() {} |
| 1221 virtual SafetyLevel safety(Instruction i) const { |
| 1222 UNREFERENCED_PARAMETER(i); |
| 1223 return MAY_BE_SAFE; |
| 1224 } |
| 1225 virtual RegisterList defs(Instruction i) const { |
| 1226 UNREFERENCED_PARAMETER(i); |
| 1227 return kRegisterPc + kRegisterLink; |
| 1228 } |
| 1229 virtual bool is_relative_branch(Instruction i) const { |
| 1230 UNREFERENCED_PARAMETER(i); |
| 1231 return true; |
| 1232 } |
| 1233 virtual int32_t branch_target_offset(Instruction i) const; |
| 1234 virtual ITSafety it_safe(Instruction i) const { |
| 1235 UNREFERENCED_PARAMETER(i); |
| 1236 return END; |
| 1237 } |
| 1238 }; |
| 1239 |
| 1240 class IT : public ClassDecoderT { |
| 1241 public: |
| 1242 virtual ~IT() {} |
| 1243 virtual SafetyLevel safety(Instruction i) const { |
| 1244 UNREFERENCED_PARAMETER(i); |
| 1245 return MAY_BE_SAFE; |
| 1246 } |
| 1247 virtual ITSafety it_safe(Instruction i) const { |
| 1248 UNREFERENCED_PARAMETER(i); |
| 1249 return NEVER; |
| 1250 } |
| 1251 virtual RegisterList defs(Instruction i) const { |
| 1252 UNREFERENCED_PARAMETER(i); |
| 1253 return kRegisterNone; |
| 1254 } |
| 1255 virtual Instruction::Condition condition(Instruction i) const; |
| 1256 virtual ITCond it_sequence(Instruction i) const; |
| 1257 }; |
| 1258 |
| 1259 class STMTD : public ClassDecoderT { |
| 1260 public: |
| 1261 virtual ~STMTD() {} |
| 1262 virtual SafetyLevel safety(Instruction i) const { |
| 1263 UNREFERENCED_PARAMETER(i); |
| 1264 return MAY_BE_SAFE; |
| 1265 } |
| 1266 virtual RegisterList defs(Instruction i) const; |
| 1267 virtual bool writes_memory(Instruction i) const { |
| 1268 UNREFERENCED_PARAMETER(i); |
| 1269 return true; |
| 1270 } |
| 1271 virtual Register base_address_register(Instruction i) const; |
| 1272 virtual RegisterList immediate_addressing_defs(Instruction i) const; |
| 1273 }; |
| 1274 |
| 1275 class LDMTD : public STMTD { |
| 1276 public: |
| 1277 virtual ~LDMTD() {} |
| 1278 virtual RegisterList defs(Instruction i) const; |
| 1279 virtual bool writes_memory(Instruction i) const { |
| 1280 UNREFERENCED_PARAMETER(i); |
| 1281 return false; |
| 1282 } |
| 1283 }; |
| 1284 |
| 1285 class StrS : public STMTD { |
| 1286 public: |
| 1287 virtual ~StrS() {} |
| 1288 virtual Register base_address_register(Instruction i) const; |
| 1289 virtual RegisterList defs(Instruction i) const; |
| 1290 }; |
| 1291 |
| 1292 class LDRImmT3 : public ClassDecoderT { |
| 1293 public: |
| 1294 virtual ~LDRImmT3() {} |
| 1295 virtual SafetyLevel safety(Instruction i) const { |
| 1296 UNREFERENCED_PARAMETER(i); |
| 1297 return MAY_BE_SAFE; |
| 1298 } |
| 1299 virtual RegisterList defs(Instruction i) const { |
| 1300 UNREFERENCED_PARAMETER(i); |
| 1301 return kRegisterNone; |
| 1302 } |
| 1303 virtual Register base_address_register(Instruction i) const; |
| 1304 }; |
| 1305 |
| 1306 class LDRImmT4 : public LDRImmT3 { |
| 1307 public: |
| 1308 virtual ~LDRImmT4() {} |
| 1309 virtual RegisterList immediate_addressing_defs(Instruction i) const; |
| 1310 virtual RegisterList defs(Instruction i) const; |
| 1311 }; |
| 1312 |
| 1313 class Def31_18 : public Def3 { |
| 1314 public: |
| 1315 virtual ~Def31_18() {} |
| 1316 virtual RegisterList defs(Instruction i) const; |
| 1317 }; |
| 1318 |
| 1319 class StrEx : public Def3 { |
| 1320 public: |
| 1321 virtual ~StrEx() {} |
| 1322 virtual RegisterList defs(Instruction i) const; |
| 1323 virtual RegisterList immediate_addressing_defs(Instruction i) const; |
| 1324 virtual bool writes_memory(Instruction i) const { |
| 1325 UNREFERENCED_PARAMETER(i); |
| 1326 return true; |
| 1327 } |
| 1328 virtual Register base_address_register(Instruction i) const; |
| 1329 }; |
| 1330 |
| 1331 class LdrEx : public StrEx { |
| 1332 public: |
| 1333 virtual ~LdrEx() {} |
| 1334 virtual RegisterList defs(Instruction i) const; |
| 1335 virtual bool writes_memory(Instruction i) const { |
| 1336 UNREFERENCED_PARAMETER(i); |
| 1337 return false; |
| 1338 } |
| 1339 }; |
| 1340 |
| 1341 class StrD : public StrEx { |
| 1342 public: |
| 1343 virtual ~StrD() {} |
| 1344 virtual RegisterList defs(Instruction i) const; |
| 1345 }; |
| 1346 |
| 1347 class LdrD : public LdrEx { |
| 1348 public: |
| 1349 virtual ~LdrD() {} |
| 1350 virtual RegisterList defs(Instruction i) const; |
| 1351 }; |
| 1352 |
| 1353 class StrExD : public StrEx { |
| 1354 public: |
| 1355 virtual ~StrExD() {} |
| 1356 virtual RegisterList immediate_addressing_defs(Instruction i) const { |
| 1357 UNREFERENCED_PARAMETER(i); |
| 1358 return kRegisterNone; // Writeback not available |
| 1359 } |
| 1360 }; |
| 1361 |
| 1362 class LdrExD : public LdrD { |
| 1363 public: |
| 1364 virtual ~LdrExD() {} |
| 1365 virtual RegisterList immediate_addressing_defs(Instruction i) const { |
| 1366 UNREFERENCED_PARAMETER(i); |
| 1367 return kRegisterNone; // Writeback not available |
| 1368 } |
| 1369 }; |
| 1370 |
| 1371 class Def27_24 : public Def3 { |
| 1372 public: |
| 1373 virtual ~Def27_24() {} |
| 1374 virtual RegisterList defs(Instruction i) const; |
| 1375 }; |
| 1376 |
| 1377 /* Unimplemented Thumb instructions go here */ |
| 1378 #define THUMB_TODO(x) class x : public Forbidden {}; |
| 1379 THUMB_TODO(Unimplemented) |
771 } // namespace | 1380 } // namespace |
772 | 1381 |
773 #endif // NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_INST_CLASSES_H | 1382 #endif // NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_INST_CLASSES_H |
OLD | NEW |