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