OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2012 The Native Client Authors. All rights reserved. | |
3 * Use of this source code is governed by a BSD-style license that can | |
4 * be found in the LICENSE file. | |
5 * Copyright 2012, Google Inc. | |
6 */ | |
7 | |
8 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_MODEL_H | |
9 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_MODEL_H | |
10 | |
11 /* | |
12 * Models instructions and decode results. | |
13 * | |
14 * Implementation Note: | |
15 * All the classes in this file are designed to be fully inlined as 32-bit | |
16 * integers. The goal: to provide a nice, fluent interface for describing | |
17 * instruction bit operations, with zero runtime cost. Compare: | |
18 * | |
19 * return (1 << ((insn >> 12) & 0xF)) | (1 << ((insn >> 19) & 0xF)); | |
20 * | |
21 * return insn.reg(15,12) + insn.reg(19,16); | |
22 * | |
23 * Both lines compile to the same machine code, but the second one is easier | |
24 * to read, and eliminates a common error (using X in place of 1 << X). | |
25 * | |
26 * To this end, keep the following in mind: | |
27 * - Avoid virtual methods. | |
28 * - Mark all methods as inline. Small method bodies may be included here, | |
29 * but anything nontrivial should go in model-inl.h. | |
30 * - Do not declare destructors. A destructor causes an object to be passed | |
31 * on the stack, even when passed by value. (This may be a GCC bug.) | |
32 * Adding a destructor to Instruction slowed the decoder down by 10% on | |
33 * gcc 4.3.3. | |
34 */ | |
35 | |
36 #include <stdint.h> | |
37 | |
38 namespace nacl_mips_dec { | |
39 | |
40 /* | |
41 * A value class that names a single register. We could use a typedef for this, | |
42 * but it introduces some ambiguity problems because of the implicit conversion | |
43 * to/from int. | |
44 * | |
45 * May be implicitly converted to a single-entry RegisterList (see below). | |
46 */ | |
47 class Register { | |
48 public: | |
49 explicit inline Register(uint32_t); | |
50 | |
51 /* | |
52 * Produces the bitmask used to represent this register. | |
53 */ | |
54 inline uint32_t bitmask() const; | |
55 | |
56 inline bool operator==(const Register &) const; | |
Brad Chen
2012/05/04 22:49:50
avoid operator overloading
petarj
2012/05/08 14:54:19
Seen in validator_arm/model.h
| |
57 inline bool operator!=(const Register &) const; | |
58 | |
59 private: | |
60 uint32_t _number; | |
61 }; | |
62 | |
63 const Register kRegisterNone(0); | |
64 | |
65 // Registers with special meaning in our model: | |
66 const Register kRegisterStack(29); | |
67 const Register kRegisterJumpMask(14); // $t6 = holds mask for jr. | |
68 const Register kRegisterLoadStoreMask(15); // $t7 = holds mask for load/store. | |
69 const Register kRegisterTls(24); // $t8 = holds tls index. | |
70 | |
71 const Register kRegisterZero(0); | |
72 | |
73 | |
74 /* | |
75 * A collection of Registers. Used to describe the side effects of operations. | |
76 * | |
77 * Note that this is technically a set, not a list -- but RegisterSet is a | |
78 * well-known term that means something else. | |
79 */ | |
80 class RegisterList { | |
81 public: | |
82 /* | |
83 * Produces a RegisterList that contains the registers specified in the | |
84 * given bitmask. To indicate rN, the bitmask must include (1 << N). | |
85 */ | |
86 explicit inline RegisterList(uint32_t bitmask); | |
87 | |
88 /* | |
89 * Produces a RegisterList containing a single register. | |
90 * | |
91 * Note that this is an implicit constructor. This is okay in this case | |
92 * because | |
93 * - It converts between two types that we control, | |
94 * - It converts at most one step (no implicit conversions to Register), | |
95 * - It inlines to a single machine instruction, | |
96 * - The readability gain in inst_classes.cc is large. | |
97 */ | |
98 inline RegisterList(const Register r); | |
99 | |
100 /* | |
101 * Checks whether this list contains the given register. | |
102 */ | |
103 inline bool operator[](const Register) const; | |
104 | |
105 // Checks whether this list contains all the registers in the operand. | |
106 inline bool contains_all(RegisterList) const; | |
107 | |
108 // Checks whether this list contains any of the registers in the operand. | |
109 inline bool contains_any(RegisterList) const; | |
110 | |
111 inline bool operator==(RegisterList) const; | |
112 | |
113 inline const RegisterList operator&(const RegisterList) const; | |
114 | |
115 // Allow the addition operator access to our bitwise representation. | |
116 friend const RegisterList operator+(const RegisterList, const RegisterList); | |
117 | |
118 private: | |
119 uint32_t _bits; | |
120 }; | |
121 | |
122 /* | |
123 * Returns a new RegisterList that contains the union of two lists. | |
124 * | |
125 * This is not a member function to allow implicit conversion of Register. | |
126 */ | |
127 inline const RegisterList operator+(const RegisterList, const RegisterList); | |
128 | |
129 /* | |
130 * A list containing every possible register, even some we don't define. | |
131 * Used exclusively as a bogus scary return value for forbidden instructions. | |
132 */ | |
133 static const RegisterList kRegisterListEverything = RegisterList(-1); | |
134 | |
135 static uint32_t const kReservedRegsBitmask = kRegisterTls.bitmask() | |
136 + kRegisterJumpMask.bitmask() | |
137 + kRegisterLoadStoreMask.bitmask(); | |
138 static RegisterList const kRegListReserved = RegisterList(kReservedRegsBitmask); | |
139 | |
140 /* | |
141 * A 32-bit Mips instruction of unspecified type. | |
142 * | |
143 * This class is designed for efficiency: | |
144 * - Its public methods for bitfield extraction are short and inline. | |
145 * - It has no vtable, so on 32-bit platforms it's exactly the size of the | |
146 * instruction it models. | |
147 */ | |
148 class Instruction { | |
149 public: | |
150 explicit inline Instruction(uint32_t bits); | |
151 | |
152 /* | |
153 * Extracts a range of contiguous bits, right-justifies it, and returns it. | |
154 * Note that the range follows hardware convention, with the high bit first. | |
155 */ | |
156 inline uint32_t bits(int hi, int lo) const; | |
157 | |
158 /* | |
159 * A convenience method that's exactly equivalent to | |
160 * Register(instruction.bits(hi, lo)) | |
161 * | |
162 * This sequence is quite common in inst_classes.cc. | |
163 */ | |
164 inline const Register reg(int hi, int lo) const; | |
165 | |
166 /* | |
167 * Extracts a single bit (0 - 31). | |
168 */ | |
169 inline bool bit(int index) const; | |
170 | |
171 | |
172 /* | |
173 * Returns an integer equivalent of this instruction, masked by the given | |
174 * mask. Used during decoding to test bitfields. | |
175 */ | |
176 inline uint32_t operator&(uint32_t) const; | |
177 | |
178 | |
179 | |
180 private: | |
181 uint32_t _bits; | |
182 }; | |
183 | |
184 uint32_t const kInstrSize = 4; | |
185 uint32_t const kInstrAlign = 0xFFFFFFFC; | |
186 uint32_t const kBundleAlign = 0xFFFFFFF0; | |
187 | |
188 } // namespace | |
189 | |
190 // Definitions for our inlined functions. | |
191 #include "native_client/src/trusted/validator_mips/model-inl.h" | |
192 | |
193 #endif // NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_MODEL_H | |
OLD | NEW |